]> git.hungrycats.org Git - linux/commitdiff
v2.4.9.4 -> v2.4.9.5
authorLinus Torvalds <torvalds@athlon.transmeta.com>
Tue, 5 Feb 2002 04:13:37 +0000 (20:13 -0800)
committerLinus Torvalds <torvalds@athlon.transmeta.com>
Tue, 5 Feb 2002 04:13:37 +0000 (20:13 -0800)
  - Merge with Alan
  - Trond Myklebust: NFS fixes - kmap and root inode special case
  - Al Viro: more superblock cleanups, inode leak in rd.c, minix
  directories in page cache
  - Paul Mackerras: clean up rubbish from sl82c105.c
  - Neil Brown: md/raid cleanups, NFS filehandles
  - Johannes Erdfelt: USB update (usb-2.0 support, visor fix, Clie fix,
  pl2303 driver update)
  - David Miller: sparc and net update
  - Eric Biederman: simplify and correct bootdata allocation - don't
  overwrite ramdisks
  - Tim Waugh: support multiple SuperIO devices, parport doc updates

291 files changed:
Documentation/DocBook/Makefile
Documentation/DocBook/parportbook.tmpl
Documentation/arm/SA1100/Assabet
Documentation/arm/SA1100/DMA [new file with mode: 0644]
Documentation/arm/SA1100/FreeBird [new file with mode: 0644]
Documentation/arm/SA1100/GraphicsClient
Documentation/arm/SA1100/HUW_WEBPANEL [new file with mode: 0644]
Documentation/arm/SA1100/Itsy
Documentation/arm/SA1100/PCMCIA [new file with mode: 0644]
Documentation/arm/SA1100/Pangolin
Documentation/arm/SA1100/Yopy [new file with mode: 0644]
Documentation/arm/SA1100/nanoEngine
Documentation/arm/SA1100/serial_UART
Documentation/fb/README-sstfb.txt [new file with mode: 0644]
Documentation/ide.txt
Documentation/kernel-doc-nano-HOWTO.txt
Documentation/s390/3270.txt
Documentation/s390/config3270.sh
Documentation/sound/CMI8338
Documentation/sound/WaveArtist [new file with mode: 0644]
Documentation/watchdog.txt
MAINTAINERS
Makefile
arch/arm/kernel/arthur.c
arch/arm/kernel/process.c
arch/arm/lib/io-readsl-armv4.S
arch/arm/lib/io-writesl.S
arch/arm/mm/fault-armv.c
arch/arm/tools/Makefile
arch/arm/tools/mach-types
arch/i386/defconfig
arch/i386/kernel/setup.c
arch/i386/mm/fault.c
arch/ppc/amiga/config.c
arch/sparc64/defconfig
arch/sparc64/kernel/head.S
arch/sparc64/kernel/ioctl32.c
arch/sparc64/kernel/sparc64_ksyms.c
arch/sparc64/lib/blockops.S
arch/sparc64/mm/fault.c
arch/sparc64/mm/init.c
arch/sparc64/mm/ultra.S
arch/sparc64/vmlinux.lds
drivers/block/floppy.c
drivers/block/paride/ppc6lnx.c
drivers/block/rd.c
drivers/bluetooth/Config.in
drivers/bluetooth/Makefile
drivers/bluetooth/hci_emu.c [deleted file]
drivers/bluetooth/hci_uart.c
drivers/bluetooth/hci_usb.c
drivers/bluetooth/hci_vhci.c [new file with mode: 0644]
drivers/cdrom/aztcd.c
drivers/cdrom/cdu31a.c
drivers/cdrom/cm206.c
drivers/cdrom/gscd.c
drivers/cdrom/isp16.c
drivers/cdrom/mcd.c
drivers/cdrom/mcdx.c
drivers/cdrom/sjcd.c
drivers/char/busmouse.c
drivers/char/dsp56k.c
drivers/char/misc.c
drivers/char/pc110pad.c
drivers/char/qpmouse.c
drivers/char/rio/rio_linux.c
drivers/char/rio/riocmd.c
drivers/char/selection.c
drivers/char/serial_tx3912.c [new file with mode: 0644]
drivers/char/serial_tx3912.h [new file with mode: 0644]
drivers/char/softdog.c
drivers/char/sx.c
drivers/char/tpqic02.c
drivers/char/tty_io.c
drivers/char/vino.h [deleted file]
drivers/char/wdt.c
drivers/char/wdt285.c
drivers/char/wdt977.c
drivers/char/wdt_pci.c
drivers/ide/Config.in
drivers/ide/Makefile
drivers/ide/ide-floppy.c
drivers/ide/ide-proc.c
drivers/ide/ide.c
drivers/ide/it8172.c
drivers/ide/pdc202xx.c
drivers/ide/qd6580.c [deleted file]
drivers/ide/qd65xx.c [new file with mode: 0644]
drivers/ide/qd65xx.h [new file with mode: 0644]
drivers/ide/sis5513.c
drivers/ide/sl82c105.c
drivers/ide/via82cxxx.c
drivers/ieee1394/highlevel.c
drivers/ieee1394/ieee1394_core.c
drivers/ieee1394/ieee1394_core.h
drivers/isdn/hisax/isar.c
drivers/isdn/icn/icn.c
drivers/isdn/icn/icn.h
drivers/isdn/isdn_audio.c
drivers/isdn/pcbit/layer2.c
drivers/isdn/pcbit/layer2.h
drivers/macintosh/nvram.c
drivers/md/md.c
drivers/md/raid5.c
drivers/media/video/vino.h [new file with mode: 0644]
drivers/message/fusion/Makefile
drivers/message/fusion/isense.c
drivers/message/fusion/lsi/fc_log.h
drivers/message/fusion/lsi/mpi.h
drivers/message/fusion/lsi/mpi_cnfg.h
drivers/message/fusion/lsi/mpi_fc.h
drivers/message/fusion/lsi/mpi_history.txt
drivers/message/fusion/lsi/mpi_init.h
drivers/message/fusion/lsi/mpi_ioc.h
drivers/message/fusion/lsi/mpi_lan.h
drivers/message/fusion/lsi/mpi_targ.h
drivers/message/fusion/mptbase.c
drivers/message/fusion/mptbase.h
drivers/message/fusion/mptctl.c
drivers/message/fusion/mptlan.c
drivers/message/fusion/mptlan.h
drivers/message/fusion/mptscsih.c
drivers/message/fusion/scsi3.h
drivers/net/net_init.c
drivers/net/ni5010.c
drivers/net/starfire.c
drivers/net/starfire_firmware.pl [new file with mode: 0644]
drivers/net/via-rhine.c
drivers/parport/ChangeLog
drivers/parport/parport_pc.c
drivers/parport/parport_serial.c
drivers/pci/pci.ids
drivers/s390/char/tuball.c
drivers/s390/char/tubfs.c
drivers/s390/char/tubio.h
drivers/s390/char/tubtty.c
drivers/s390/char/tubttybld.c
drivers/scsi/3w-xxxx.c
drivers/scsi/3w-xxxx.h
drivers/scsi/aha1542.c
drivers/scsi/dpt/dpt_osdutil.h [new file with mode: 0644]
drivers/scsi/dpt/dpti_i2o.h [new file with mode: 0644]
drivers/scsi/dpt/dpti_ioctl.h [new file with mode: 0644]
drivers/scsi/dpt/dptsig.h [new file with mode: 0644]
drivers/scsi/dpt/osd_defs.h [new file with mode: 0644]
drivers/scsi/dpt/osd_util.h [new file with mode: 0644]
drivers/scsi/dpt/sys_info.h [new file with mode: 0644]
drivers/scsi/dpt_i2o.c [new file with mode: 0644]
drivers/scsi/dpti.h [new file with mode: 0644]
drivers/scsi/gdth.c
drivers/scsi/gdth.h
drivers/scsi/gdth_ioctl.h
drivers/scsi/gdth_proc.c
drivers/scsi/gdth_proc.h
drivers/scsi/pcmcia/nsp_cs.c
drivers/scsi/pcmcia/nsp_debug.c
drivers/scsi/pcmcia/nsp_message.c
drivers/scsi/qlogicfc.c
drivers/scsi/qlogicfc_asm.c [new file with mode: 0644]
drivers/scsi/sd.c
drivers/scsi/seagate.c
drivers/scsi/seagate.h
drivers/scsi/sg.c
drivers/sound/Config.in
drivers/sound/ac97.h
drivers/sound/ac97_codec.c
drivers/sound/ad1848.c
drivers/sound/cmpci.c
drivers/sound/cs46xx.c
drivers/sound/esssolo1.c
drivers/sound/i810_audio.c
drivers/sound/ite8172.c [new file with mode: 0644]
drivers/sound/msnd_pinnacle.c
drivers/sound/nec_vrc5477.c [new file with mode: 0644]
drivers/sound/sonicvibes.c
drivers/sound/trident.c
drivers/sound/trident.h
drivers/sound/via82cxxx_audio.c
drivers/telephony/Config.in
drivers/telephony/Makefile
drivers/telephony/ixj-ver.h [new file with mode: 0644]
drivers/telephony/ixj.c
drivers/telephony/ixj.h
drivers/telephony/ixj_pcmcia.c [new file with mode: 0644]
drivers/telephony/phonedev.c
drivers/usb/devices.c
drivers/usb/devio.c
drivers/usb/hub.c
drivers/usb/hub.h
drivers/usb/pwc-if.c
drivers/usb/pwc.h
drivers/usb/se401.c
drivers/usb/se401.h
drivers/usb/serial/pl2303.c
drivers/usb/serial/visor.c
drivers/usb/serial/visor.h
drivers/usb/usb-uhci.c
drivers/usb/usbvideo.c [new file with mode: 0644]
drivers/usb/usbvideo.h [new file with mode: 0644]
drivers/video/fbcon.c
drivers/video/radeon.h [new file with mode: 0644]
drivers/video/radeonfb.c [new file with mode: 0644]
drivers/video/riva/fbdev.c
drivers/video/sstfb.c [new file with mode: 0644]
drivers/video/sstfb.h [new file with mode: 0644]
drivers/video/tx3912fb.c [new file with mode: 0644]
drivers/video/tx3912fb.h [new file with mode: 0644]
drivers/zorro/names.c
drivers/zorro/zorro.c
fs/adfs/inode.c
fs/dquot.c
fs/exec.c
fs/file_table.c
fs/lockd/clntlock.c
fs/minix/bitmap.c
fs/minix/dir.c
fs/minix/file.c
fs/minix/inode.c
fs/minix/itree_common.c
fs/minix/itree_v1.c
fs/minix/itree_v2.c
fs/minix/namei.c
fs/nfs/file.c
fs/nfs/inode.c
fs/nfsd/export.c
fs/nfsd/nfsfh.c
fs/open.c
fs/partitions/check.c
fs/partitions/ldm.c
fs/proc/generic.c
fs/qnx4/inode.c
fs/reiserfs/inode.c
fs/super.c
include/asm-sparc64/elf.h
include/asm-sparc64/pgtable.h
include/asm-sparc64/system.h
include/linux/ac97_codec.h
include/linux/fs.h
include/linux/generic_serial.h
include/linux/i2c-id.h
include/linux/ide.h
include/linux/lockd/xdr.h
include/linux/minix_fs.h
include/linux/mmzone.h
include/linux/module.h
include/linux/prefetch.h [new file with mode: 0644]
include/linux/sunrpc/xdr.h
include/linux/telephony.h
include/linux/usb.h
include/net/bluetooth/bluetooth.h
include/net/bluetooth/bluez.h
include/net/bluetooth/hci.h
include/net/bluetooth/hci_core.h
include/net/bluetooth/hci_emu.h [deleted file]
include/net/bluetooth/hci_uart.h
include/net/bluetooth/hci_usb.h
include/net/bluetooth/hci_vhci.h [new file with mode: 0644]
include/net/bluetooth/l2cap.h
include/net/bluetooth/l2cap_core.h
include/scsi/sg.h
kernel/ksyms.c
net/bluetooth/af_bluetooth.c
net/bluetooth/hci_core.c
net/bluetooth/hci_sock.c
net/bluetooth/l2cap_core.c
net/bluetooth/l2cap_proc.c
net/bluetooth/lib.c
net/bluetooth/syms.c
net/core/dev.c
net/ipv4/arp.c
net/ipv4/icmp.c
net/ipv4/ip_fragment.c
net/ipv4/ip_options.c
net/ipv4/ip_output.c
net/ipv4/ipip.c
net/ipv4/tcp_ipv4.c
net/ipv4/udp.c
net/ipv6/addrconf.c
net/ipv6/datagram.c
net/ipv6/icmp.c
net/ipv6/ip6_output.c
net/ipv6/sit.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/irda/irda_device.c
net/lapb/lapb_iface.c
net/netrom/af_netrom.c
net/sunrpc/clnt.c
net/sunrpc/sunrpc_syms.c
net/sunrpc/svc.c
net/sunrpc/xdr.c

index 9729d2b08552c77134eb4cc68e96bc0898499750..5e1d047b109727d24a97c0ddcb9b64e31a18a8f7 100644 (file)
@@ -24,10 +24,10 @@ pdf:        $(PDF)
 html:  $(HTML)
 
 %.eps: %.fig
-       -fig2dev -Leps $< $@
+       fig2dev -Leps $< $@
 
 %.jpeg: %.fig
-       -fig2dev -Ljpeg $< $@
+       fig2dev -Ljpeg $< $@
 
 %.sgml: %.c
        echo "<programlisting>" > $@
@@ -129,7 +129,7 @@ kernel-api-man: $(APISOURCES)
                $(PERL) $(TOPDIR)/scripts/split-man $(TOPDIR)/Documentation/man
 
 parportbook: $(JPG-parportbook)
-parportbook.ps: $(EPS-parportbook)
+parportbook.ps parportbook.pdf: $(EPS-parportbook)
 parportbook.sgml: parportbook.tmpl $(TOPDIR)/drivers/parport/init.c
        $(TOPDIR)/scripts/docgen $(TOPDIR)/drivers/parport/init.c <$< >$@
 
index ada2ebd525ed9b3eeb630b81e29457a7d0ef60bc..8a5425407985bd59e755aaa5035f0a14b8939bbb 100644 (file)
@@ -1654,6 +1654,16 @@ struct parport_operations {
 
       </listitem></varlistentry>
 
+     <varlistentry><term><constant>PPGETMODE</constant></term>
+      <listitem>
+
+       <para>
+       Retrieves the current IEEE 1284 mode to use for
+       <function>read</function> and <function>write</function>.
+       </para>
+
+      </listitem></varlistentry>
+
      <varlistentry><term><constant>PPGETTIME</constant></term>
       <listitem>
 
@@ -1684,6 +1694,36 @@ struct parport_operations {
 
       </listitem></varlistentry>
 
+     <varlistentry><term><constant>PPGETMODES</constant></term>
+      <listitem>
+
+       <para>
+       Retrieves the capabilities of the hardware (i.e. the
+       <structfield>modes</structfield> field of the
+       <structname>parport</structname> structure).
+       </para>
+
+      </listitem></varlistentry>
+
+     <varlistentry><term><constant>PPSETFLAGS</constant></term>
+      <listitem>
+
+       <para>
+       Sets flags on the <literal>ppdev</literal> device which can
+       affect future I/O operations.  Available flags are:
+       </para>
+
+       <itemizedlist spacing=compact>
+       <listitem><para>
+         <constant>PP_FASTWRITE</constant></para></listitem>
+       <listitem><para>
+         <constant>PP_FASTREAD</constant></para></listitem>
+       <listitem><para>
+         <constant>PP_W91284PIC</constant></para></listitem>
+       </itemizedlist>
+
+      </listitem></varlistentry>
+
      <varlistentry><term><constant>PPWCONTROL</constant></term>
       <listitem>
 
index ad5dedbf250e5e7b7ac7906b6fa88c3182f42e3f..b3136f78ffd5947c5fe8251034138abccf3e3b1a 100644 (file)
@@ -9,38 +9,268 @@ Also some notes from John G Dorsey <jd5q@andrew.cmu.edu>:
 http://www.cs.cmu.edu/~wearable/software/assabet.html
 
 
-To build the kernel:
+Building the kernel
+-------------------
+
+To build the kernel with current defaults:
 
        make assabet_config
-       make config
-       [accept all defaults]
+       make oldconfig
        make dep
        make zImage
 
-Typically, you'll need angelboot to load the kernel.
-The following angelboot.opt file should be used:
+The resulting kernel image should be available in linux/arch/arm/boot/zImage.
+
+
+Installing a bootloader
+-----------------------
+
+A couple of bootloaders able to boot Linux on Assabet are available:
+
+BLOB (http://www.lart.tudelft.nl/lartware/blob/)
+
+   BLOB is a bootloader used within the LART project.  Some contributed
+   patches were merged into BLOB to add support for Assabet.
+
+Compaq's Bootldr + John Dorsey's patch for Assabet support
+(http://www.handhelds.org/Compaq/bootldr.html)
+(http://www.wearablegroup.org/software/bootldr/)
+
+   Bootldr is the bootloader developed by Compaq for the iPAQ Pocket PC.
+   John Dorsey has produced add-on patches to add support for Assabet and
+   the JFFS filesystem.
+
+RedBoot (http://sources.redhat.com/redboot/)
+
+   RedBoot is a bootloader developed by Red Hat based on the eCos RTOS
+   hardware abstraction layer.  It supports Assabet amongst many other
+   hardware platforms.
+
+RedBoot is currently the recommended choice since it's the only one to have
+networking support, and is the most actively maintained.
+
+Brief examples on how to boot Linux with RedBoot are shown below.  But first
+you need to have RedBoot installed in your flash memory.  A known to work
+precompiled RedBoot binary is available from the following location:
+
+ftp://ftp.netwinder.org/users/n/nico/
+ftp://ftp.arm.linux.org.uk/pub/linux/arm/people/nico/
+ftp://ftp.handhelds.org/pub/linux/arm/sa-1100-patches/
+
+Look for redboot-assabet*.tgz.  Some installation infos are provided in
+redboot-assabet*.txt.
+
+
+Initial RedBoot configuration
+-----------------------------
+
+The commands used here are explained in The RedBoot User's Guide available
+on-line at http://sources.redhat.com/ecos/docs-latest/redboot/redboot.html.
+Please refer to it for explanations.
+
+If you have a CF network card (my Assabet kit contained a CF+ LP-E from
+Socket Communications Inc.), you should strongly consider using it for TFTP
+file transfers.  You must insert it before RedBoot runs since it can't detect
+it dynamically.
+
+To initialize the flash directory:
+
+       fis init -f
+
+To initialize the non-volatile settings, like whether you want to use BOOTP or
+a static IP address, etc, use this command:
+
+       fconfig -i
+
+
+Writing a kernel image into flash
+---------------------------------
+
+First, the kernel image must be loaded into RAM.  If you have the zImage file
+available on a TFTP server:
+
+       load zImage -r -b 0x100000
+
+If you rather want to use Y-Modem upload over the serial port:
+
+       load -m ymodem -r -b 0x100000
+
+To write it to flash:
+
+       fis create "Linux kernel" -b 0x100000 -l 0xc0000
+
+
+Booting the kernel
+------------------
+
+The kernel still requires a filesystem to boot.  A ramdisk image can be loaded
+as follows:
+
+       load ramdisk_image.gz -r -b 0x800000
+
+Again, Y-Modem upload can be used instead of TFTP by replacing the file name
+by '-y ymodem'.
+
+Now the kernel can be retrieved from flash like this:
+
+       fis load "Linux kernel"
+
+or loaded as described previously.  To boot the kernel:
+
+       exec -b 0x100000 -l 0xc0000
+
+The ramdisk image could be stored into flash as well, but there are better
+solutions for on-flash filesystems as mentioned below.
+
+
+Using JFFS2
+-----------
+
+Using JFFS2 (the Second Journaling Flash File System) is probably the most
+convenient way to store a writable filesystem into flash.  JFFS2 is used in
+conjunction with the MTD layer which is responsible for low-level flash
+management.  More information on the Linux MTD can be found on-line at:
+http://www.linux-mtd.infradead.org/.  A JFFS howto with some infos about
+creating JFFS/JFFS2 images is available from the same site.
+
+For instance, a sample JFFS2 image can be retrieved from the same FTP sites
+mentioned below for the precompiled RedBoot image.
+
+To load this file:
+
+       load sample_img.jffs2 -r -b 0x100000
+
+The result should look like:
+
+RedBoot> load sample_img.jffs2 -r -b 0x100000
+Raw file loaded 0x00100000-0x00377424
+
+Now we must know the size of the unallocated flash:
+
+       fis free
+
+Result:
+
+RedBoot> fis free
+  0x500E0000 .. 0x503C0000
+
+The values above may be different depending on the size of the filesystem and
+the type of flash.  See their usage below as an example and take care of
+substituting yours appropriately.
+
+We must determine some values:
+
+size of unallocated flash:     0x503c0000 - 0x500e0000 = 0x2e0000
+size of the filesystem image:  0x00377424 - 0x00100000 = 0x277424
+
+We want to fit the filesystem image of course, but we also want to give it all
+the remaining flash space as well.  To write it:
+
+       fis unlock -f 0x500E0000 -l 0x2e0000
+       fis erase -f 0x500E0000 -l 0x2e0000
+       fis write -b 0x100000 -l 0x277424 -f 0x500E0000
+       fis create "JFFS2" -n -f 0x500E0000 -l 0x2e0000
+
+Now the filesystem is associated to a MTD "partition" once Linux has discovered
+what they are in the boot process.  From Redboot, the 'fis list' command
+displays them:
+
+RedBoot> fis list
+Name              FLASH addr  Mem addr    Length      Entry point
+RedBoot           0x50000000  0x50000000  0x00020000  0x00000000
+RedBoot config    0x503C0000  0x503C0000  0x00020000  0x00000000
+FIS directory     0x503E0000  0x503E0000  0x00020000  0x00000000
+Linux kernel      0x50020000  0x00100000  0x000C0000  0x00000000
+JFFS2             0x500E0000  0x500E0000  0x002E0000  0x00000000
+
+However Linux should display something like:
+
+SA1100 flash: probing 32-bit flash bus
+SA1100 flash: Found 2 x16 devices at 0x0 in 32-bit mode
+Using RedBoot partition definition
+Creating 5 MTD partitions on "SA1100 flash":
+0x00000000-0x00020000 : "RedBoot"
+0x00020000-0x000e0000 : "Linux kernel"
+0x000e0000-0x003c0000 : "JFFS2"
+0x003c0000-0x003e0000 : "RedBoot config"
+0x003e0000-0x00400000 : "FIS directory"
+
+What's important here is the position of the partition we are interested in,
+which is the third one.  Within Linux, this correspond to /dev/mtdblock2.
+Therefore to boot Linux with the kernel and its root filesystem in flash, we
+need this RedBoot command:
+
+       fis load "Linux kernel"
+       exec -b 0x100000 -l 0xc0000 -c "root=/dev/mtdblock2"
+
+Of course other filesystems than JFFS might be used, like cramfs for example.
+You might want to boot with a root filesystem over NFS, etc.  It is also
+possible, and sometimes more convenient, to flash a filesystem directly from
+within Linux while booted from a ramdisk or NFS.  The Linux MTD repository has
+many tools to deal with flash memory as well, to erase it for example.  JFFS2
+can then be mounted directly on a freshly erased partition and files can be
+copied over directly.  Etc...
+
+
+RedBoot scripting
+-----------------
+
+All the commands above aren't so useful if they have to be typed in every
+time the Assabet is rebooted.  Therefore it's possible to automatize the boot
+process using RedBoot's scripting capability.
+
+For example, I use this to boot Linux with both the kernel and the ramdisk
+images retrieved from a TFTP server on the network:
+
+RedBoot> fconfig
+Run script at boot: false true
+Boot script:
+Enter script, terminate with empty line
+>> load zImage -r -b 0x100000
+>> load ramdisk_ks.gz -r -b 0x800000
+>> exec -b 0x100000 -l 0xc0000
+>>
+Boot script timeout (1000ms resolution): 3
+Use BOOTP for network configuration: true
+GDB connection port: 9000
+Network debug at boot time: false
+Update RedBoot non-volatile configuration - are you sure (y/n)? y
+
+Then, rebooting the Assabet is just a matter of waiting for the login prompt.
+
+
+
+Nicolas Pitre
+nico@cam.org
+June 12, 2001
+
+
+Status of peripherals in -rmk tree
+----------------------------------
+
+Assabet:
+ Serial ports:
+  Radio:       TX, RX, CTS, DSR, DCD, RI
+  COM:         TX, RX, CTS, DSR, DCD, RTS, DTR, PM
+  I2C:         TX, RX
+  L3:          No
 
------ begin angelboot.opt -----
-base 0xc0008000
-entry 0xc0008000
-r0 0x00000000
-r1 0x00000019
-device /dev/ttyS1
-options "9600 8N1"
-baud 115200
-otherfile ramdisk_img.gz
-otherbase 0xc0800000
-exec minicom
------ end angelboot.opt -----
+ Video:
+  LCD:         PM
+  Video out:   Not fully
+  Touchscreen: No
 
-Then load the kernel and ramdisk with:
+ Audio:
+  Codec:       No
+  POTS:                No
 
-       angelboot -f angelboot.opt zImage
+ Other:
+  PCMCIA:      Yes
+  USB:         No
 
-Here it is assumed that your Assabet is connected to ttyS1 and that
-minicom is preconfigured with /dev/ttyS1, 9600 baud, 8N1, no flow control
-by default.
+Neponset:
+ Serial ports:
+  COM1,2:      TX, RX, CTS, DSR, DCD, RTS, DTR
 
-This is work in progress...
+More stuff can be found in the -np (Nicolas Pitre's) tree.
 
-Please send any patches to nico@cam.org.
diff --git a/Documentation/arm/SA1100/DMA b/Documentation/arm/SA1100/DMA
new file mode 100644 (file)
index 0000000..0b35186
--- /dev/null
@@ -0,0 +1,248 @@
+Support functions for the SA11x0 internal DMA channels
+======================================================
+
+Nicolas Pitre <nico@cam.org>
+Last updated: 2001/07/15
+
+
+The DMA controller consists of six independent DMA channels. Each channel
+can be configured to service any of the serial controllers. Two channels
+are required to service a full-duplex serial controller. The DMA
+controller is intended to relieve the processor of the interrupt overhead
+in servicing these ports with programmed I/ O.
+
+If desired, any or all peripherals (except the UDC) may be serviced with
+programmed I/ O instead of DMA. Each peripheral is capable of requesting
+processor service through its own interrupt lines or through a DMA
+request.
+
+A set of functions is provided to support drivers working with DMA buffers
+through a generic interface for (wishfully) all DMA usages.  Those
+functions will take care of buffer queueing and splitting, DMA register
+management, interrupt handling, etc.
+
+
+SA11x0 DMA API
+--------------
+
+Here is the description for the DMA API.
+
+
+int sa1100_request_dma( dmach_t *channel, const char *device_id,
+                       dma_device_t device );
+
+This function will search for a free DMA channel and returns the channel
+number in '*channel'.  'device_id' should point to a string identifying
+the DMA usage or device (mainly for /proc).  'device' is the SA11x0
+peripheral's ports.  Note that reading from a port and writing to the
+same port are actually considered as two different streams requiring
+two DMA channels with their own device type.  All possible dma_device_t
+are defined in include/asm-arm/arch-sa1100/dma.h.  If no channel is
+available, or if the desired device is already in use by another DMA
+channel, then an error code is returned.  This function must be called
+before any other DMA calls.
+
+
+int sa1100_dma_queue_buffer( dmach_t channel, void *buf_id,
+                             dma_addr_t data, int size );
+
+This function enqueue the specified buffer for DMA processing.  The buffer
+will be transmitted or filled with incoming data depending on the channel
+configuration made through sa1100_dma_set_device().  If the queue is
+empty, DMA starts immediately on the given buffer.
+
+Arguments are:
+
+dmach_t channel:       the channel number.
+void *buf_id:          a buffer identification known by the caller.
+dma_addr_t data:       the buffer's physical address.
+int size:              the buffer size in bytes.
+
+Note here the dma_addr_t which is not the same as the virtual address as
+returned by kmalloc() and friends.  The DMA controller must be given a
+physical address to a buffer which is not cached bye the CPU data cache.
+To get such address, the DMA mapping functions (see
+Documentation/DMA-mapping.txt) are recommended.  The only relevant
+functions are pci_alloc_consistent(), pci_map_single() and their unmap
+counterparts.  The PCI dev argument is NULL of course.
+
+There is no restriction on the buffer size.  The DMA code will split it up
+internally to acommodate the DMA controller as needed.  If the buffer
+can't be enqueued the appropriate error code is returned.
+
+
+int sa1100_dma_set_callback( dmach_t channel, dma_callback_t cb );
+
+As soon as the DMa completes with a buffer, a callback function is used to
+notify the driver which would have registered one.  The callback function
+is prototyped as:
+
+void dma_callback( void *buf_id, int size );
+
+The 'buf_id' argument is the buffer identifier as passed to
+sa1100_dma_queue_buffer().  The 'size' argument is the number of bytes the
+DMA processed (should be the same as the buffer size).
+
+Note that this callback function is called while in interrupt context.
+So it has to be small and efficient while posponing more complex
+processing to a bottom-half function or similar.  All
+restrictions for interrupt handlers still apply.
+
+
+int sa1100_dma_get_current( dmach_t channel, void **buf_id,
+                            dma_addr_t *addr );
+
+This returns the buffer ID and the DMA address pointer within the buffer
+currently being processed.  If no such buffer is currently processed, an
+error code is returned.  This is useful for mmap()'ed buffers like in
+audio drivers.
+
+
+int sa1100_dma_stop( dmach_t channel );
+
+This call stops any DMA transfer on the given channel.
+
+
+int sa1100_dma_resume( dmach_t channel );
+
+This call resumes a DMA transfer which would have been stopped through
+sa1100_dma_stop().
+
+
+int sa1100_dma_flush_all( dmach_t channel );
+
+This completely flushes all queued buffers and on-going DMA transfers on a
+given channel.  The next enqueued buffer following this call will be
+processed right away.
+
+
+int sa1100_dma_set_spin( dmach_t channel, dma_addr_t addr, int size );
+
+Because there is at least one device out there that uses its receive
+signal for its transmit clock reference, we need a mecanism to make the
+DMA "spin" on a certain buffer for when there is no more actual buffer to
+process.  The 'addr' argument is the physical memory address to use, and
+the 'size' argument determines the spin DMA chunk.  This size can't be
+larger than 8191 (if so, it is clamped to 4096).  When the size is 0,
+the spin function is turned off.
+
+When activated, DMA will "spin" until there is any buffer in the queue.
+The current DMA chunk will terminate before a newly queued buffer is
+processed.  The spin buffer will only be reused when there is no more
+acctual buffer to process.
+
+It is important not to choose a too small 'size' value since it will
+greatly increase the interrupt load required to restart the spin.  Since
+this feature will typically be used on transmit DMAs, and because a buffer
+full of zeros is probably the best thing to spin out, the 'addr' argument
+may well be used with FLUSH_BASE_PHYS for which no allocation nor memory
+bus request are needed.
+
+The spinning DMA is affected by sa1100_dma_stop() and sa1100_dma_resume()
+but not bu sa1100_dma_flush_all().
+
+
+void sa1100_free_dma( dmach_t channel );
+
+This clears all activities on a given DMA channel and releases it for
+future requests.
+
+
+Buffer allocation
+-----------------
+
+Like mentionned above, it is the driver's responsibility to allocate, free
+and keep track of buffer space with dma_addr_t type addresses. However the
+driver must not change the state of any buffer after it has been sent to
+sa1100-dma_queue_buffer().  When that function has been called, the buffer
+becomes the DMA's ownership until one of these events occur:
+
+- The callback function is called by the DMA code with a buffer ID to
+  indicate that DMA processing terminated on that buffer.  Then the
+  driver owns the buffer again.
+- The sa1100-dma_flush_all() function is called by the driver at which
+  point *all* queued buffers are owned by the driver again.
+- The sa1100-free_dma() does the same as sa1100-dma_flush_all().
+
+This doesn't mean that you can't change the content of a queued buffer in
+conjonction with the usage of pci_map_consistent() and
+sa1100_dma_get_current()... but then you must be sure you know what you're
+doing (this doesn't work with pci_map_single()).
+
+
+Examples
+--------
+
+A real example of audio ring buffers is implemented in the
+drivers/sound/sa1100-audio.c driver.  The SA1110 USB client and the
+SA11x0 FIR drivers are also using this interface to implement packetized
+DMA.
+
+A transmit DMA for network packets could look like this (largely simplified):
+
+struct sk_buff *tx_ring_skb[RING_SIZE];
+dma_addr_t      tx_ring_dma[RING_SIZE];
+int cur_tx;
+...
+
+transmit function:
+
+       tx_ring_skb[cur_tx] = skb;
+       tx_ring_dma[cur_tx] = pci_map_single(NULL, skb->data, skb->len,
+                                            PCI_DMA_TODEVICE);
+       sa1100_dma_queue_buffer(channel, (void*)cur_tx,
+                               tx_ring_dma[cur_tx], skb->len);
+       cur_tx++; cur_tx %= RING_SIZE;
+       ...
+
+and the callback function:
+
+void tx_done_callback( void *buf_id, int size ) {
+       int done_tx = (int) buf_id;
+       struct sk_buff *skb = tx_ring_skb[done_tx];
+       pci_unmap_single(NULL, tx_ring_dma[done_tx], skb->len,
+                        PCI_DMA_TODEVICE);
+       stats.tx_packets++;
+       stats.tx_bytes += size;
+       dev_kfree_skb_irq(skb);
+       tx_ring_skb[done_tx] = NULL;
+}
+
+
+For drivers expecting variable length packets i.e. USB client, it is
+necessary to register the appropriate IRQ to be notified when the receiver
+is idle, the packet is complete, etc.  We could use one buffer at a time
+with its ID being the virtual address of the buffer.
+
+Then the sequence:
+
+       /* be sure DMA won't continue under our feet */
+       sa1100_dma_stop(channel);
+       /* get the actual DMA length */
+       sa1100_get_current(channel, &data, &dma_ptr);
+       /* acquire ownership for the buffer */
+       sa1100_dma_flush_all(channel);
+       /* unmap the DMA buffer (actually doing cache coherency on ARM) */
+       pci_unmap_single (NULL, dma_addr, MAX_PKT_SIZE, PCI_DMA_FROMDEVICE);
+       /* get remaining bytes from the fifo */
+       ptr = data + dma_ptr - dma_addr;
+       while (fifo_not_empty)
+               *ptr++ = get_byte_from_fifo;
+       /* feed another free buffer for the next packet */
+       dma_addr2 = pci_map_single(NULL, data2, MAX_PKT_SIZE,
+                                       PCI_DMA_FROMDEVICE);
+       sa1100_dma_queue_buffer(channel, data2, dma_addr2, MAX_PKT_SIZE);
+       /* process the current packet */
+       ...
+
+might do the trick.  This looks a bit ugly but that's a starting point for
+improvements.
+
+
+TODO
+----
+
+- Create kernel-doc comments in the source to document the API and
+  let the documentation be generated automatically.
+
+
diff --git a/Documentation/arm/SA1100/FreeBird b/Documentation/arm/SA1100/FreeBird
new file mode 100644 (file)
index 0000000..eda28b3
--- /dev/null
@@ -0,0 +1,21 @@
+Freebird-1.1 is produced by Legned(C) ,Inc.
+(http://www.legend.com.cn)
+and software/linux mainatined by Coventive(C),Inc.
+(http://www.coventive.com)
+
+Based on the Nicolas's strongarm kernel tree.
+
+===============================================================
+Maintainer:
+
+Chester Kuo <chester@coventive.com>
+           <chester@linux.org.tw>
+
+Author :
+Tim wu <timwu@coventive.com>
+CIH <cih@coventive.com>
+Eric Peng <ericpeng@coventive.com>
+Jeff Lee <jeff_lee@coventive.com>
+Allen Cheng
+Tony Liu <tonyliu@coventive.com>
+
index 01f3f050ab0ae9f30d1828312206f00012572fe1..8fa7e8027ff13ec2230ab6117ea8821b1a08f4ab 100644 (file)
@@ -1,15 +1,18 @@
-ADS GraphicsClient/ThinClient Single Board Computer
+ADS GraphicsClient Plus Single Board Computer
 
 For more details, contact Applied Data Systems or see
-http://www.flatpanels.com/products.html
+http://www.applieddata.net/products.html
 
 The original Linux support for this product has been provided by 
-Nicolas Pitre <nico@cam.org>.
+Nicolas Pitre <nico@cam.org>. Continued development work by
+Woojung Huh <whuh@applieddata.net>
 
 It's currently possible to mount a root filesystem via NFS providing a
-complete Linux environment.  Otherwise a ramdisk image may be used.  Use
-'make graphicsclient_config' before any 'make config'.  This will set up
-defaults for GraphicsClient/ThinClient support.
+complete Linux environment.  Otherwise a ramdisk image may be used.  The
+board supports MTD/JFFS, so you could also mount something on there.
+
+Use 'make graphicsclient_config' before any 'make config'.  This will set up
+defaults for GraphicsClient Plus support.
 
 The kernel zImage is linked to be loaded and executed at 0xc0200000.  
 Also the following registers should have the specified values upon entry:
@@ -17,8 +20,18 @@ Also the following registers should have the specified values upon entry:
        r0 = 0
        r1 = 29 (this is the GraphicsClient architecture number)
 
-Here is a tipical angel.opt option file if the kernel is loaded through
-the Angel Debug Monitor:
+Linux can  be used with the ADS BootLoader that ships with the
+newer rev boards. See their documentation on how to load Linux.
+Angel is not available for the GraphicsClient Plus AFAIK.
+
+There is a  board known as just the GraphicsClient that ADS used to
+produce but has end of lifed. This code will not work on the older
+board with the ADS bootloader, but should still work with Angel,
+as outlined below.  In any case, if you're planning on deploying
+something en masse, you should probably get the newer board.
+
+If using Angel on the older boards, here is a typical angel.opt option file
+if the kernel is loaded through the Angel Debug Monitor:
 
 ----- begin angelboot.opt -----
 base 0xc0200000
@@ -26,7 +39,7 @@ entry 0xc0200000
 r0 0x00000000
 r1 0x0000001d
 device /dev/ttyS1
-options "9600 8N1"
+options "38400 8N1"
 baud 115200
 #otherfile ramdisk.gz
 #otherbase 0xc0800000
@@ -39,7 +52,7 @@ uncommented) would be loaded with:
        angelboot -f angelboot.opt zImage
 
 Here it is assumed that the board is connected to ttyS1 on your PC
-and that minicom is preconfigured with /dev/ttyS1, 9600 baud, 8N1, no flow
+and that minicom is preconfigured with /dev/ttyS1, 38400 baud, 8N1, no flow
 control by default.
 
 If any other bootloader is used, ensure it accomplish the same, especially
@@ -47,19 +60,39 @@ for r0/r1 register values before jumping into the kernel.
 
 
 Supported peripherals:
-- SA1100 LCD frame buffer (only 8bpp yet)
-- on-board SMC 92C94 ethernet NIC
+- SA1100 LCD frame buffer (8/16bpp...sort of)
+- on-board SMC 92C96 ethernet NIC
 - SA1100 serial port
-- flash memory access
+- flash memory access (MTD/JFFS)
 - pcmcia
-- possibly UCB1200 audio (not tested yet)
+- touchscreen(ucb1200)
+- ps/2 keyboard
+- console on LCD screen
+- serial ports (ttyS[0-2])
+  - ttyS0 is default for serial console
+- Smart I/O (ADC, keypad, digital inputs, etc)
+  See http://www.applieddata.com/developers/linux for IOCTL documentation
+  and example user space code. ps/2 keybd is multiplexed through this driver
 
 To do:
-- touchscreen driver
-- 16bpp frame buffer support
-- extra (external) serial port driver
-- some console keyboard support (maybe IR?)
+- UCB1200 audio with new ucb_generic layer
 - everything else!  :-)
 
+Notes:
+
+- The flash on board is divided into 3 partitions.  mtd0 is where
+  the ADS boot ROM and zImage is stored.  It's been marked as
+  read-only to keep you from blasting over the bootloader. :)  mtd1 is
+  for the ramdisk.gz image.  mtd2 is user flash space and can be
+  utilized for either JFFS or if you're feeling crazy, running ext2
+  on top of it. If you're not using the ADS bootloader, you're
+  welcome to blast over the mtd1 partition also.
+
+- 16bpp mode requires a different cable than what ships with the board.
+  Contact ADS or look through the manual to wire your own. Currently,
+  if you compile with 16bit mode support and switch into a lower bpp
+  mode, the timing is off so the image is corrupted.  This will be
+  fixed soon.
+
 Any contribution can be sent to nico@cam.org and will be greatly welcome!
 
diff --git a/Documentation/arm/SA1100/HUW_WEBPANEL b/Documentation/arm/SA1100/HUW_WEBPANEL
new file mode 100644 (file)
index 0000000..ffc8181
--- /dev/null
@@ -0,0 +1,18 @@
+The HUW_WEBPANEL is a product of the german company Hoeft & Wessel AG
+
+If you want more information, please visit
+http://www.hoeft-wessel.de
+
+To build the kernel:
+       make huw_webpanel_config
+       make oldconfig
+       [accept all defaults]
+       make dep
+       make zImage
+
+Mostly of the work is done by:
+Roman Jordan         jor@hoeft-wessel.de
+Christoph Schulz    schu@hoeft-wessel.de
+
+2000/12/18/
+
index a2b3ecda3be4d30eb7d34bbb5badac05d4c67ea0..ed62bdf84c31635317b721d6cea94c70978faade 100644 (file)
@@ -2,11 +2,38 @@ Itsy is a research project done by the Western Research Lab, and Systems
 Research Center in Palo Alto, CA. The Itsy project is one of several
 research projects at Compaq that are related to pocket computing.
 
-Itsy support has yet to be fully integrated in this kernel.  Linux 2.0.x
-support is available though.
-
 For more information, see:
 
        http://www.research.digital.com/wrl/itsy/index.html
 
+Notes on initial 2.4 Itsy support (8/27/2000) :
+The port was done on an Itsy version 1.5 machine with a daughtercard with
+64 Meg of DRAM and 32 Meg of Flash. The initial work includes support for
+serial console (to see what you're doing).  No other devices have been
+enabled.
+
+To build, do a "make menuconfig" (or xmenuconfig) and select Itsy support.
+Disable Flash and LCD support. and then do a make dep and a make zImage.
+Finally, you will need to cd to arch/arm/boot/tools and execute a make there
+to build the params-itsy program used to boot the kernel.
+
+In order to install the port of 2.4 to the itsy, You will need to set the
+configuration parameters in the monitor as follows:
+Arg 1:0x08340000, Arg2: 0xC0000000, Arg3:18 (0x12), Arg4:0
+Make sure the start-routine address is set to 0x00060000.
+
+Next, flash the params-itsy program to 0x00060000 ("p 1 0x00060000" in the
+flash menu)  Flash the kernel in arch/arm/boot/zImage into 0x08340000
+("p 1 0x00340000").  Finally flash an initial ramdisk into 0xC8000000
+("p 2 0x0")  We used ramdisk-2-30.gz from the 0.11 version directory on
+handhelds.org.
+
+The serial connection we established was at:
+ 8-bit data, no parity, 1 stop bit(s), 115200.00 b/s. in the monitor, in the
+params-itsy program, and in the kernel itself.  This can be changed, but
+not easily. The monitor parameters are easily changed, the params program
+setup is assembly outl's, and the kernel is a configuration item specific to
+the itsy. (i.e. grep for CONFIG_SA1100_ITSY and you'll find where it is.)
+
 
+This should get you a properly booting 2.4 kernel on the itsy.
diff --git a/Documentation/arm/SA1100/PCMCIA b/Documentation/arm/SA1100/PCMCIA
new file mode 100644 (file)
index 0000000..5eb5d3a
--- /dev/null
@@ -0,0 +1,374 @@
+Kernel Low-Level PCMCIA Interface Documentation
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+John G Dorsey <john+@cs.cmu.edu>
+Updated: 30 June, 2000
+
+
+Note: this interface has not been finalized!
+See also: http://www.cs.cmu.edu/~wearable/software/pcmcia-arm.html
+
+
+Introduction
+
+Early versions of PCMCIA Card Services for StrongARM were designed to
+permit a single socket driver to run on a variety of SA-1100 boards by
+using a userland configuration process. During the conversion to the 2.3
+kernel series, all of the configuration has moved into sub-drivers in the
+kernel proper (see linux/drivers/pcmcia/sa1100*). This document describes
+the low-level interface between those sub-drivers and the sa1100 socket
+driver module.
+
+Presently, there are six operations which must be provided by the
+board-specific code. Only functions whose implementation is likely to
+differ across board designs are required at this level. Some examples
+include:
+
+  - configuring card detect lines to generate interrupts
+  - sensing the legal voltage levels for inserted cards
+  - asserting the reset signal for a card
+
+Functions which are assumed to be the same across all designs are
+performed within the generic socket driver itself. Some examples of these
+kinds of operations include:
+
+  - configuring memory access times based on the core clock frequency
+  - reads/writes on memory, byte swizzling, ...
+
+The current implementation allows the specific per-board set of low-level
+operations to be determined at run time. For each specific board, the
+following structure should be filled in:
+
+  struct pcmcia_low_level {
+    int (*init)(struct pcmcia_init *);
+    int (*shutdown)(void);
+    int (*socket_state)(struct pcmcia_state_array *);
+    int (*get_irq_info)(struct pcmcia_irq_info *);
+    int (*configure_socket)(const struct pcmcia_configure *);
+  };
+
+The component functions are described in detail below. Using the
+machine_is_*() tests, the pointer `pcmcia_low_level' should be assigned to
+the location of the table for your board.
+
+
+0. init(struct pcmcia_init *init)
+
+This operation has three responsibilities:
+
+  - perform any board-specific initialization tasks
+  - associate the given handler with any interrupt-generating signals
+    such as card detection, or battery voltage detection
+  - set up any necessary edge detection for card ready signals
+
+Argument passing for this operation is implemented by the following
+structure:
+
+  struct pcmcia_init {
+    void (*handler)(int irq, void *dev, struct pt_regs *regs);
+    struct pcmcia_maps *maps;
+  };
+
+Here, `handler' is provided by the socket driver, and `maps' must be
+modified if the default mapping isn't appropriate. This operation should
+return one of two values:
+
+  - the highest-numbered socket available, plus one
+  - a negative number, indicating an error in configuration
+
+Note that the former case is _not_ the same as "the number of sockets
+available." In particular, if your design uses SA-1100 slot "one" but
+not slot "zero," you MUST report "2" to the socket driver.
+
+
+1. shutdown(void)
+
+This operation takes no arguments, and will be called during cleanup for
+the socket driver module. Any state associated with the socket controller,
+including allocated data structures, reserved IRQs, etc. should be
+released in this routine.
+
+The return value for this operation is not examined.
+
+
+2. socket_state(struct pcmcia_state_array *state_array)
+
+This operation will be invoked from the interrupt handler which was set up
+in the earlier call to init(). Note, however, that it should not include
+any side effects which would be inappropriate if the operation were to
+occur when no interrupt is pending. (An extra invocation of this operation
+currently takes place to initialize state in the socket driver.)
+
+Argument passing for this operation is handled by a structure which
+contains an array of the following type:
+
+  struct pcmcia_state {
+    unsigned detect: 1,
+              ready: 1,
+               bvd1: 1,
+               bvd2: 1,
+             wrprot: 1,
+              vs_3v: 1,
+              vs_Xv: 1;
+  };
+
+Upon return from the operation, a struct pcmcia_state should be filled in
+for each socket available in the hardware. For every array element (up to
+`size' in the struct pcmcia_state_saarray) which does not correspond to an
+available socket, zero the element bits. (This includes element [0] if
+socket zero is not used.)
+
+Regardless of how the various signals are routed to the SA-1100, the bits
+in struct pcmcia_state always have the following semantics:
+
+  detect - 1 if a card is fully inserted, 0 otherwise
+  ready  - 1 if the card ready signal is asserted, 0 otherwise
+  bvd1   - the value of the Battery Voltage Detect 1 signal
+  bvd2   - the value of the Battery Voltage Detect 2 signal
+  wrprot - 1 if the card is write-protected, 0 otherwise
+  vs_3v  - 1 if the card must be operated at 3.3V, 0 otherwise
+  vs_Xv  - 1 if the card must be operated at X.XV, 0 otherwise
+
+A note about the BVD signals: if your board does not make both lines
+directly observable to the processor, just return reasonable values. The
+standard interpretation of the BVD signals is:
+
+  BVD1  BVD2
+
+   0     x    battery is dead
+   1     0    battery warning
+   1     1    battery ok
+
+Regarding the voltage sense flags (vs_3v, vs_Xv), these bits should be set
+based on a sampling of the Voltage Sense pins, if available. The standard
+interpretation of the VS signals (for a "low-voltage" socket) is:
+
+  VS1   VS2
+
+   0     0    X.XV, else 3.3V, else none
+   0     1    3.3V, else none
+   1     0    X.XV, else none
+   1     1    5V, else none
+
+More information about the BVD and VS conventions is available in chapter
+5 of "PCMCIA System Architecture," 2nd ed., by Don Anderson.
+
+This operation should return 1 if an IRQ is actually pending for the
+socket controller, 0 if no IRQ is pending (but no error condition exists,
+such as an undersized state array), or -1 on any error.
+
+
+3. get_irq_info(struct pcmcia_irq_info *info)
+
+This operation obtains the IRQ assignment which is legal for the given
+socket. An argument of the following type is passed:
+
+  struct pcmcia_irq_info {
+    unsigned int sock;
+    unsigned int irq ;
+  };
+
+The `sock' field contains the socket index being queried. The `irq' field
+should contain the IRQ number corresponding to the card ready signal from
+the device.
+
+This operation should return 0 on success, or -1 on any error.
+
+
+4. configure_socket(const struct pcmcia_configure *configure)
+
+This operation allows the caller to apply power to the socket, issue a
+reset, or enable various outputs. The argument is of the following type:
+
+  struct pcmcia_configure {
+    unsigned sock: 8,
+              vcc: 8,
+              vpp: 8,
+           output: 1,
+          speaker: 1,
+            reset: 1;
+  };
+
+The `sock' field contains the index of the socket to be configured. The
+`vcc' and `vpp' fields contain the voltages to be applied for Vcc and Vpp,
+respectively, in units of 0.1V. (Note that vpp==120 indicates that
+programming voltage should be applied.)
+
+The two output enables, `output' and `speaker', refer to the card data
+signal enable and the card speaker enable, respectively. The `reset' bit,
+when set, indicates that the card reset should be asserted.
+
+This operation should return 0 on success, or -1 on any error.
+
+
+Board-Specific Notes
+
+The following information is known about various SA-11x0 board designs
+which may be used as reference while adding support to the kernel.
+
+
+Carnegie Mellon Itsy/Cue (http://www.cs.cmu.edu/~wearable/itsy/)
+
+  Itsy Chip Select 3 (CS3) Interface
+  ("ITSY MEMORY/PCMCIA ADD-ON BOARD with BATTERY and CHARGER CIRCUITRY,"
+   memo dated 5-20-99, from Tim Manns to Richard Martin, et. al)
+
+  Read:
+    ABVD2    (SS)D0          A slot, Battery Voltage Detect
+    ABVD1    (SS)D1
+    AVSS2    (SS)D2          A slot, Voltage Sense
+    AVSS1    (SS)D3
+    GND      (SS)D4
+    GND      (SS)D5
+    GND      (SS)D6
+    GND      (SS)D7
+  
+    BBVD2    (SS)D8          B slot, Battery Voltage Detect
+    BBVD1    (SS)D9
+    BVSS2    (SS)D10         B slot, Voltage Sense
+    BVSS1    (SS)D11
+    GND      (SS)D12
+    GND      (SS)D13
+    GND      (SS)D14
+    GND      (SS)D15
+  
+  Write:
+    (SS)D0   A_VPP_VCC       LTC1472 VPPEN1
+    (SS)D1   A_VPP_PGM       LTC1472 VPPEN0
+    (SS)D2   A_VCC_3         LTC1472 VCCEN0
+    (SS)D3   A_VCC_5         LTC1472 VCCEN1
+    (SS)D4   RESET (A SLOT)
+    (SS)D5   GND
+    (SS)D6   GND
+    (SS)D7   GND
+    (SS)D8   B_VPP_VCC       LTC1472 VPPEN1
+    (SS)D9   B_VPP_PGM       LTC1472 VPPEN0
+    (SS)D10  B_VCC_3         LTC1472 VCCEN0
+    (SS)D11  B_VCC_5         LTC1472 VCCEN1
+    (SS)D12  RESET (B SLOT)
+    (SS)D13  GND
+    (SS)D14  GND
+    (SS)D15  GND
+  GPIO pin assignments are as follows: (from schematics)
+    GPIO 10                  Slot 0 Card Detect
+    GPIO 11                  Slot 1 Card Detect
+    GPIO 12                  Slot 0 Ready/Interrupt
+    GPIO 13                  Slot 1 Ready/Interrupt
+
+
+
+Intel SA-1100 Multimedia Board (http://developer.intel.com/design/strong/)
+
+  CPLD Registers
+  SA-1100 Multimedia Development Board with Companion SA-1101 Development
+    Board User's Guide, p.4-42
+
+  This SA-1100/1101 development package uses only one GPIO pin (24) to
+  signal changes in card status, and requires software to inspect a
+  PCMCIA status register to determine the source.
+
+  Read: (PCMCIA Power Sense Register - 0x19400000)
+    S0VS1           0        Slot 0 voltage sense
+    S0VS2           1
+    S0BVD1          2        Slot 0 battery voltage sense
+    S0BVD2          3
+    S1VS1           4        Slot 1 voltage sense
+    S1VS2           5
+    S1BVD1          6        Slot 1 battery voltage sense
+    S1BVD2          7
+
+  Read/Write: (PCMCIA Power Control Register - 0x19400002)
+    S0VPP0          0        Slot 0 Vpp
+    S0VPP1          1
+    S0VCC0          2        Slot 0 Vcc
+    S0VCC1          3
+    S1VPP0          4        Slot 1 Vpp
+    S1VPP1          5
+    S1VCC0          6        Slot 1 Vcc
+    S1VCC1          7
+
+  Read: (PCMCIA Status Register - 0x19400004)
+    S0CD1           0        Slot 0 Card Detect 1
+    S0RDY           1        Slot 0 Ready/Interrupt
+    S0STSCHG        2        Slot 0 Status Change
+    S0Reset         3        Slot 0 Reset (RW)
+    S1CD1           4        Slot 1 Card Detect 1
+    S1RDY           5        Slot 1 Ready/Interrupt
+    S1STSCHG        6        Slot 1 Status Change
+    S1Reset         7        Slot 1 Reset (RW)
+
+
+
+Intel SA-1100 Evaluation Platform (http://developer.intel.com/design/strong/)
+
+  Brutus I/O Pins and Chipselect Register
+  pcmcia-brutus.c, by Ivo Clarysse
+  (What's the official reference for this info?)
+
+  This SA-1100 development board uses more GPIO pins than say, the Itsy
+  or the SA-1100/1101 multimedia package. The pin assignments are as
+  follows:
+
+    GPIO 2                   Slot 0 Battery Voltage Detect 1
+    GPIO 3                   Slot 0 Ready/Interrupt
+    GPIO 4                   Slot 0 Card Detect
+    GPIO 5                   Slot 1 Battery Voltage Detect 1
+    GPIO 6                   Slot 1 Ready/Interrupt
+    GPIO 7                   Slot 1 Card Detect
+
+  Like the Itsy, Brutus uses a chipselect register in static memory
+  bank 3 for the other signals, such as voltage sense or reset:
+
+  Read:
+    P0_VS1          8        Slot 0 Voltage Sense
+    P0_VS2          9
+    P0_STSCHG      10        Slot 0 Status Change
+    P1_VS1         12        Slot 1 Voltage Sense
+    P1_VS2         13
+    P1_STSCHG      14        Slot 1 Status Change
+
+  Read/Write:
+    P0_            16        Slot 0 MAX1600EAI control line
+    P0_            17        Slot 0 MAX1600EAI control line
+    P0_            18        Slot 0 MAX1600EAI control line
+    P0_            19        Slot 0 MAX1600EAI control line
+    P0_            20        Slot 0 12V
+    P0_            21        Slot 0 Vpp to Vcc (CONFIRM?)
+    P0_            22        Slot 0 enable fan-out drivers & xcvrs
+    P0_SW_RST      23        Slot 0 Reset
+    P1_            24        Slot 1 MAX1600EAI control line
+    P1_            25        Slot 1 MAX1600EAI control line
+    P1_            26        Slot 1 MAX1600EAI control line
+    P1_            27        Slot 1 MAX1600EAI control line
+    P1_            28        Slot 1 12V
+    P1_            29        Slot 1 Vpp to Vcc (CONFIRM?)
+    P1_            30        Slot 1 enable fan-out drivers & xcvrs
+    P1_SW_RST      31        Slot 1 Reset
+
+  For each slot, the bits labelled "MAX1600EAI" should (apparently)
+  be written with the value 0101 for Vcc 3.3V, and 1001 for Vcc 5V.
+
+
+
+Intel SA-1110 Development Platform (http://developer.intel.com/design/strong/)
+
+  GPIO Pin Descriptions and Board Control Register
+  SA-1110 Microprocessor Development Board User's Guide, p.4-7, 4-10
+
+  The Assabet board contains only a single Compact Flash slot,
+  attached to slot 1 on the SA-1110. Card detect, ready, and BVD
+  signals are routed through GPIO, with power and reset placed in a
+  control register. Note that the CF bus must be enabled before use.
+
+    GPIO 21                  Slot 1 Compact Flash interrupt
+    GPIO 22                  Slot 1 card detect (CD1 NOR CD2)
+    GPIO 24                  Slot 1 Battery Voltage Detect 2
+    GPIO 25                  Slot 1 Battery Voltage Detect 1
+
+  Write-only: (Board Control Register - 0x12000000)
+    CF_PWR          0        CF bus power (3.3V)
+    CF_RST          1        CF reset
+    CF_Bus_On       7        CF bus enable
+
index 88cff5bf14a37083bc61770d88be32b26233d205..6fa266765c74a577b4ad2b45fb17d9c33d11ade1 100644 (file)
@@ -1,25 +1,20 @@
-Pangolin is a StrongARM 1110-based evaluation  platform produced
-by Dialogue Technoloy (http://www.dialogue.com.tw/).
+Pangolin is a StrongARM 1110-based evaluation platform produced
+by Dialogue Technology (http://www.dialogue.com.tw/).
 It has EISA slots for ease of configuration with SDRAM/Flash
 memory card, USB/Serial/Audio card, Compact Flash card,
 and TFT-LCD card.
-This platform is currently under development.
 
 To compile for Pangolin, you must issue the following commands:
 
        make pangolin_config
-       make config
-       [accept all defaults]
+       make oldconfig
        make dep
        make zImage
 
 Supported peripherals:
-- SA1110 serial port
+- SA1110 serial port (UART1/UART2/UART3)
 - flash memory access
-
-Testing:
-- pcmcia driver
-- sound driver
-
-To do:
-- MQ-200 driver
+- compact flash driver
+- UDA1341 sound driver
+- SA1100 LCD controller for 800x600 16bpp TFT-LCD
+- MQ-200 driver for 800x600 16bpp TFT-LCD
diff --git a/Documentation/arm/SA1100/Yopy b/Documentation/arm/SA1100/Yopy
new file mode 100644 (file)
index 0000000..e14f16d
--- /dev/null
@@ -0,0 +1,2 @@
+See http://www.yopydeveloper.org for more.
+
index ff34c4fb6d46ae5cb28c0a17b7b35e46e04a036c..fc431cbfefc2d7f346952abfda6b3a6d30ceb0cd 100644 (file)
@@ -4,6 +4,8 @@ nanoEngine
 "nanoEngine" is a SA1110 based single board computer from 
 Bright Star Engineering Inc.  See www.brightstareng.com/arm
 for more info.
+(Ref: Stuart Adams <sja@brightstareng.com>)
 
-Ref: Stuart Adams <sja@brightstareng.com>
+Also visit Larry Doolittle's "Linux for the nanoEngine" site:
+http://recycle.lbl.gov/~ldoolitt/bse/
 
index 3807dea193eaa3797de8648e6cb49880c5ff2c45..161ec115c6f0a5bca7bb56fa6df28c0c3699ea0a 100644 (file)
@@ -1,5 +1,4 @@
-The SA1100 serial port finally had its major/minor numbers officially 
-assigned:
+The SA1100 serial port had its major/minor numbers officially assigned:
 
 > Date: Sun, 24 Sep 2000 21:40:27 -0700
 > From: H. Peter Anvin <hpa@transmeta.com>
@@ -25,7 +24,7 @@ assigned:
 >                   7 = /dev/cusa2                Callout device for ttySA2
 >
 
-So, if you're not using devfs, you must create those inodes in /dev
+If you're not using devfs, you must create those inodes in /dev
 on the root filesystem used by your SA1100-based device:
 
        mknod ttySA0 c 204 5
@@ -35,31 +34,14 @@ on the root filesystem used by your SA1100-based device:
        mknod cusa1 c 205 6
        mknod cusa2 c 205 7
 
-Note that the old incorrect use of /dev/ttyS0 in order to use the serial port 
-won't work anymore.  This device node is reserved to the conventionnal 16x50
-UART which may appear on devices like PCMCIA modem, etc.
+In addition to the creation of the appropriate device nodes above, you
+must ensure your user space applications make use of the correct device
+name. The classic example is the content of the /etc/inittab file where
+you might have a getty process started on ttyS0.  In this case:
 
-In addition to the creation of the appropriate device nodes above, you must
-ensure your user space applications make use of the correct device name.
-The classic example is the content of the /etc/inittab where you might have 
-a getty process started on ttyS0.  In this case you have two choices:
+- replace occurences of ttyS0 with ttySA0, ttyS1 with ttySA1, etc.
 
-1- replace occurences of ttyS0 with ttySA0, ttyS1 with ttySA1, etc.
+- don't forget to add 'ttySA0', 'console', or the appropriate tty name
+  in /etc/securetty for root to be allowed to login as well.
 
-2- in the occurence of 'ttyS0', you may consider replacing it with 'console'.
-   as in "T0:12345:respawn:/sbin/getty -L console 9600 vt100"
-
-(don't forget to add 'ttySA0', 'console', or the appropriate tty name 
- in /etc/securetty for root to be allowed to login as well.)
-
-The use of /dev/console has the advantage of being independent of the real
-serial device used.  The kernel automatically forward all operations on
-/dev/console to the apropriate serial device.  The nature of the console may
-also be modified with a kernel command line parameter (see
-Documentation/serial-console.txt for the details).  Of course, 
-/dev/console must have been created as a char device with major 5 minor 1.
-
-Using /dev/console is also compatible with older kernels that used /dev/ttyS0.
-Therefore it is handy for ramdisk images which are targetted for different
-StrongARM platforms and older kernels.
 
diff --git a/Documentation/fb/README-sstfb.txt b/Documentation/fb/README-sstfb.txt
new file mode 100644 (file)
index 0000000..81b93c0
--- /dev/null
@@ -0,0 +1,167 @@
+
+Introduction
+
+         This is a frame buffer device driver for 3dfx' Voodoo Graphics 
+       (aka voodoo 1, aka sst1) and Voodoo² (aka Voodoo 2, aka CVG) based 
+       video boards. It's highly experimental code, but is guaranteed to work
+       on my computer, with my "Maxi Gamer 3D" and "Maxi Gamer 3d²" boards,
+       and with me "between chair and keyboard". Some people tested other
+       combinations and it seems that it works.
+         The main page is located at <http://sstfb.sourceforge.net>, and if
+       you want the latest version, check out the CVS, as the driver is a work
+       in progress, i feel incomfortable with releasing tarballs of something
+       not completely working...Don't worry, it's still more than useable
+       (I eat my own dog food)
+
+         Please read the Bug section, and report any success or failure to me
+       (Ghozlane Toumi <gtoumi@messel.emse.fr>).
+         BTW, If you have only one monitor , and you don't feel like playing
+       with the vga passthrou cable, I can only suggest borrowing a screen
+       somewhere... 
+
+
+Installation 
+
+         This driver (should) work on ix86, with any 2.2.x kernel (tested
+       with x = 19) and "recent" 2.4.x kernel, as a module or compiled in.
+         You can apply the patches found in sstfb/kernel/*-2.{2|4}.x.patch,
+       and copy sstfb.c to linux/drivers/video/, or apply a single patch, 
+       sstfb/patch-2.{2|4}.x-sstfb-yymmdd to your linux source tree.
+
+         Then configure your kernel as usual: choose "m" or "y" to 3Dfx Voodoo
+       Graphics in section "console". Compile, install, have fun... and please
+       drop me a report :)
+
+
+Module Usage
+       
+       Warnings.
+       # You should read completely this section before issuing any command.
+       # If you have only one monitor to play with, once you insmod the
+         module, the 3dfx takes control of the output, so you'll have to
+         plug the monitor to the "normal" video board in order to issue
+         the commands, or you can blindly use sst_dbg_vgapass
+          in the tools directory (See Tools). The latest option is pass the
+         parameter vgapass=1 when insmodding the driver. (See Kernel/Modules
+         Options)
+
+       Module insertion:
+       # insmod sstfb.o
+         you should see some strange output frome the board: 
+         a big blue square, a green and a red small squares and a vertical
+         white rectangle. why ? the function's name is self explanatory :
+         "sstfb_test()"...
+         (if you don't have a second monitor, you'll have to plug your monitor
+         directely to the 2D videocard to see what you're typing)
+       # con2fb /dev/fbx /dev/ttyx
+         bind a tty to the new frame buffer. if you already have a frame
+         buffer driver, the voodoo fb will likely be /dev/fb1. if not, 
+         the device will be /dev/fb0. You can check this by doing a 
+         cat /proc/fb. You can find a copy of con2fb in tools/ directory.
+         if you don't have another fb device, this step is superfluous,
+         as the console subsystem automagicaly binds ttys to the fb.
+       # switch to the virtual console you just mapped. "tadaaa" ...
+
+       Module removal:
+       # con2fb /dev/fbx /dev/ttyx
+         bind the tty to the old frame buffer so the module can be removed.
+         (how does it work with vgacon ? short answer : it doesn't work)
+       # rmmod sstfb
+
+
+Kernel/Modules Options
+
+       You can pass some otions to sstfb module, and via the kernel command
+       line when the driver is compiled in :
+       for module : insmod sstfb.o option1=value1 option2=value2 ...
+       in kernel :  video=sstfb:option1,option2:value2,option3 ...
+       
+       sstfb supports the folowing options :
+       module          kernel          description
+
+       vgapass=1       vgapass         enable or disable VGA passthrou cable
+       vgapass=0       vganopass       when enabled, the monitor will
+                                       get the signal from the VGA board
+                                       and not from the voodoo. default nopass
+
+       mem=x           mem:x           force frame buffer memory in MiB
+                                       allowed values: 1, 2, 4. default detect
+
+       inverse=1       inverse         suposed to enable inverse console.
+                                       doesn't work ...
+
+       clipping=1      clipping        enable or disable clipping . with
+       clipping=0      noclipping      clipping enabled, all offscreen reads
+                                       and writes are disgarded. default:
+                                       enable clipping.
+
+       gfxclk=x        gfxclk:x        force graphic clock frequency (in MHz)
+                                       becarefull with this option .
+                                       default is 50Mhz for voodoo1, 75MHz
+                                       for voodoo2. Be carefull, this one is
+                                       dangerous. default=auto
+
+       slowpci=0       slowpci         enable or disable fast PCI read/writes
+       slowpci=1       fastpci         default : fastpci
+
+       dev=x           dev:x           attach the driver to device number x
+                                       0 is the first compatible board (in 
+                                       lspci order)
+
+Tools
+
+       These tools are mostly for debugging purposes, but you can 
+       find some of these interesting :
+        - con2fb , maps a tty to a fbramebuffer .
+               con2fb /dev/fb1 /dev/tty5
+        - sst_dbg_vgapass , changes vga passthrou. You have to recompile the
+       driver with SST_DEBUG and SST_DEBUG_IOCTL set to 1
+               sst_dbg_vgapass /dev/fb1 1 (enables vga cable)
+               sst_dbg_vgapass /dev/fb1 0 (disables vga cable)
+        - glide_reset , resets the voodoo using glide
+               use this after rmmoding sstfb, if the module refuses to
+               reinsert .
+
+Bugs
+
+       - DO NOT use glide while the sstfb module is in, you'll most likely
+       hang your computer.
+       - if you see some artefacts (pixels not cleaning and stuff like that), 
+       try turning off clipping (clipping=0)
+       - the driver don't detect the 4Mb frame buffer voodoos, it seems that
+       the 2 last Mbs wrap around. looking into that .
+       - The driver is 16 bpp only, 24/32 won't work.
+       - The driver is not your_favorite_toy-safe. this includes SMP...
+          [Actually from inspection it seems to be safe - Alan]
+       - when using XFree86 FBdev (X over fbdev) you may see strange color
+       patterns at the border of your windows (the pixels loose the lowest
+       byte -> basicaly the blue component nd some of the green) . I'm unable
+       to reproduce this with XFree86-3.3, but one of the testers has this
+       problem with XFree86-4. I don't know yet if this is the drivers fault
+       or X's (most likely the driver, of course).
+       - I didn't really test changing the palette, so you may find some weird
+       things when playing with that.
+       - Sometimes the driver will not recognise the DAC , and the
+        initialisation will fail. this is specificaly true for
+       voodoo 2 boards , but it should be solved in recent versions. please
+       contact me .
+       - the 24/32 is not likely to work anytime soon , knowing that the
+       hardware does ... unusual thigs in 24/32 bpp
+
+Todo
+
+       - Get rid of the previous paragraph.
+       - Buy more coffee.
+       - test/port to other arch.
+       - try to add panning using tweeks with front and back buffer .
+       - try to implement accel en voodoo2 , this board can actualy do a 
+         lot in 2D even if it was sold as a 3D only board ...
+
+ghoz.
+
+-- 
+Ghozlane Toumi <gtoumi@messel.emse.fr>
+
+
+$Date: 2001/08/29 00:21:11 $
+http://sstfb.sourceforge.net/README
index 7352528bdbe2b5636cd5fc0f6f7745edd2ae0b30..f3013824d2fa6a2c09ce5083904c39a3b70eebc5 100644 (file)
@@ -314,7 +314,7 @@ Summary of ide driver parameters for kernel "command line":
  "ide0=ht6560b"                : probe/support HT6560B interface
  "ide0=cmd640_vlb"     : *REQUIRED* for VLB cards with the CMD640 chip
                          (not for PCI -- automatically detected)
- "ide0=qd6580"         : probe/support qd6580 interface
+ "ide0=qd65xx"         : probe/support qd65xx interface
  "ide0=ali14xx"                : probe/support ali14xx chipsets (ALI M1439/M1445)
  "ide0=umc8672"                : probe/support umc8672 chipsets
 
index eb96562e4e63ed7ffaa4d28ecdd2031c2fb20589..03ee7b1270f41e67ea59a852e8b00b98e6cb9f10 100644 (file)
@@ -35,9 +35,9 @@ are:
 
 - Makefile
 
-  The targets 'sgmldocs', 'psdocs', and 'pdfdocs' are used to build
-  DocBook files, PostScript files, and PDF files in
-  Documentation/DocBook.
+  The targets 'sgmldocs', 'psdocs', 'pdfdocs', and 'htmldocs' are used
+  to build DocBook files, PostScript files, PDF files, and html files
+  in Documentation/DocBook.
 
 - Documentation/DocBook/Makefile
 
@@ -49,10 +49,11 @@ How to extract the documentation
 
 If you just want to read the ready-made books on the various
 subsystems (see Documentation/DocBook/*.tmpl), just type 'make
-psdocs', or 'make pdfdocs', depending on your preference.  If you
-would rather read a different format, you can type 'make sgmldocs' and
-then use DocBook tools to convert Documentation/DocBook/*.sgml to a
-format of your choice (for example, 'db2html ...').
+psdocs', or 'make pdfdocs', or 'make htmldocs', depending on your 
+preference.  If you would rather read a different format, you can type 
+'make sgmldocs' and then use DocBook tools to convert 
+Documentation/DocBook/*.sgml to a format of your choice (for example, 
+'db2html ...' if 'make htmldocs' was not defined).
 
 If you want to see man pages instead, you can do this:
 
@@ -111,7 +112,9 @@ The format of the block comment is like this:
 (*)?*/
 
 The short function description cannot be multiline, but the other
-descriptions can be.
+descriptions can be (and they can contain blank lines). Avoid putting a
+spurious blank line after the function name, or else the description will
+be repeated!
 
 All descriptive text is further processed, scanning for the following special
 patterns, which are highlighted appropriately.
index 2261e3f23501aad25ada7aea9e62129d9e9291ff..33b4ff6a6be3703736eb62f733b815dbda552b84 100644 (file)
@@ -34,17 +34,6 @@ This paper covers installation of the driver and operation of a
 dialed-in x3270.
 
 
-HELP !!!
-
-The device name of e.g. /dev/3270/tty620 noted below is at variance
-with "standard" Linux device names.  What should it be?  The portion
-"/dev/3270" was recommended by H. Peter Anvin, maintainer of the
-official Linux major-numbers list; the portion "tty620" was recommended
-by me.  Please send your thoughts on this issue at least to me at
-rbh00@utsglobal.com.  Even if you think it's okay as is, please let me
-know.  Thanks.
-
-
 INSTALLATION.
 
 You install the driver by installing a patch, doing a kernel build, and
@@ -60,9 +49,14 @@ script and the resulting /tmp/mkdev3270.
 
 If you have chosen to make tub3270 a module, you add a line to
 /etc/modules.conf.  If you are working on a VM virtual machine, you
-can use DEF GRAF to define virtual 3270 devices.  If you generate 3270
-console support, the driver automatically converts your console at boot
-time to a 3270 if it is a 3215.
+can use DEF GRAF to define virtual 3270 devices.
+
+You may generate both 3270 and 3215 console support, or one or the
+other, or neither.  If you generate both, the console type under VM is
+not changed.  Use #CP Q TERM to see what the current console type is.
+Use #CP TERM CONMODE 3270 to change it to 3270.  If you generate only
+3270 console support, then the driver automatically converts your console
+at boot time to a 3270 if it is a 3215.
 
 In brief, these are the steps:
        1. Install the tub3270 patch
@@ -78,21 +72,17 @@ To test that everything works, assuming VM and x3270,
 
 Here are the installation steps in detail:
 
-       0.  Retrieve the patch file via anonymous ftp from
-       ftp://ftp.utsglobal.com/pub/tub3270.  The patch is designed
-       to apply smoothly to an IBM 2.4.0 system with no other
-       UTS-Global patches applied.  We know of some easily resolvable
-       conflicts between this and other of our patches.
-
-       1. Apply the patch.  Then do
+       1.  The 3270 driver is a part of the official Linux kernel
+       source.  Build a tree with the kernel source and any necessary
+       patches.  Then do
                make oldconfig
-                       (Reply "y" or "m" for CONFIG_3270; if "y",
-                       reply "y" or "n" for CONFIG_3270_CONSOLE)
+               (If you wish to disable 3215 console support, edit
+               .config; change CONFIG_TN3215's value to "n";
+               and rerun "make oldconfig".)
                make dep
                make image
                make modules
                make modules_install
-               <run silo in the usual way>
 
        2. (Perform this step only if you have configured tub3270 as a
        module.)  Add a line to /etc/modules.conf to automatically
@@ -122,12 +112,17 @@ Here are the installation steps in detail:
        config3270.sh.  Inspect the output script it produces,
        /tmp/mkdev3270, and then run that script.  This will create the
        necessary character special device files and make the necessary
-       changes to /etc/inittab.  Then notify /sbin/init that /etc/inittab
-       has changed, by issuing the telinit command with the q operand:
+       changes to /etc/inittab.  If you have selected DEVFS, the driver
+       itself creates the device files, and /tmp/mkdev3270 only changes
+       /etc/inittab.
+
+       Then notify /sbin/init that /etc/inittab has changed, by issuing
+       the telinit command with the q operand:
                cd /usr/src/linux/Documentation/s390
                sh config3270.sh
                sh /tmp/mkdev3270
                telinit q
+
        This should be sufficient for your first time.  If your 3270
        configuration has changed and you're reusing config3270, you
        should follow these steps:
index 8d7047a3576a3916c59dd2862f7111c77942fd98..515e2f431487104d22a8015fd0ab2ee054585188 100644 (file)
@@ -37,10 +37,14 @@ ls $P > /dev/null 2>&1 || exit 1
 echo "#!/bin/sh" > $SCR || exit 1
 echo " " >> $SCR
 echo "# Script built by /sbin/config3270" >> $SCR
-echo rm -rf "$D/$SUBD/*" >> $SCR
+if [ ! -d /dev/dasd ]; then
+       echo rm -rf "$D/$SUBD/*" >> $SCR
+fi
 echo "grep -v $TTY $INITTAB > $NINITTAB" > $SCRTMP || exit 1
 echo "echo $ADDNOTE >> $NINITTAB" >> $SCRTMP
-echo mkdir -p $D/$SUBD >> $SCR
+if [ ! -d /dev/dasd ]; then
+       echo mkdir -p $D/$SUBD >> $SCR
+fi
 
 # Now query the tub3270 driver for 3270 device information
 # and add appropriate mknod and mingetty lines to our files
@@ -48,13 +52,19 @@ echo what=config > $P
 while read devno maj min;do
        if [ $min = 0 ]; then
                fsmaj=$maj
-               echo mknod $D/$TUB c $fsmaj 0 >> $SCR
-               echo chmod 666 $D/$TUB >> $SCR
+               if [ ! -d /dev/dasd ]; then
+                       echo mknod $D/$TUB c $fsmaj 0 >> $SCR
+                       echo chmod 666 $D/$TUB >> $SCR
+               fi
        elif [ $maj = CONSOLE ]; then
-               echo mknod $D/$TUB$devno c $fsmaj $min >> $SCR
+               if [ ! -d /dev/dasd ]; then
+                       echo mknod $D/$TUB$devno c $fsmaj $min >> $SCR
+               fi
        else
-               echo mknod $D/$TTY$devno c $maj $min >>$SCR
-               echo mknod $D/$TUB$devno c $fsmaj $min >> $SCR
+               if [ ! -d /dev/dasd ]; then
+                       echo mknod $D/$TTY$devno c $maj $min >>$SCR
+                       echo mknod $D/$TUB$devno c $fsmaj $min >> $SCR
+               fi
                echo "echo t$min$GETTYLINE $TTY$devno >> $NINITTAB" >> $SCRTMP
        fi
 done < $P
index 0d6d2824900dc0aba1209398132bc009fbde2f93..387d058c3f95d4e718dfa52037c1d719e7f3bec3 100644 (file)
@@ -69,8 +69,8 @@ DRIVER PARAMETER
   Some functions for the cm8738 can be configured in Kernel Configuration
   or modules parameters. Set these parameters to 1 to enable.
 
-  mpu_io:      I/O ports base for MPU-401, 0 if disabled.
-  fm_io:       I/O ports base for OPL-3, 0 if disabled.
+  mpuio:       I/O ports base for MPU-401, 0 if disabled.
+  fmio:                I/O ports base for OPL-3, 0 if disabled.
   spdif_inverse:Inverse the S/PDIF-in signal, this depends on your
                CD-ROM or DVD-ROM.
   spdif_loop:   Enable S/PDIF loop, this route S/PDIF-in to S/PDIF-out
@@ -80,8 +80,6 @@ DRIVER PARAMETER
                 rear-out.
   use_line_as_bass:Enable this if you want to use line-in as
                 bass-out.
-  modem:       You will need to set this parameter if you want to use
-               the HSP modem. You need install the pctel.o, the modem
-               driver itself.
   joystick:    Enable joystick. You will need to install Linux joystick
                driver.
+
diff --git a/Documentation/sound/WaveArtist b/Documentation/sound/WaveArtist
new file mode 100644 (file)
index 0000000..f4f3407
--- /dev/null
@@ -0,0 +1,170 @@
+
+ (the following is from the armlinux CVS)
+
+ WaveArtist mixer and volume levels can be accessed via these commands:
+
+  nn30 read registers nn, where nn = 00 - 09 for mixer settings
+                                             0a - 13 for channel volumes
+  mm31 write the volume setting in pairs, where mm = (nn - 10) / 2
+  rr32 write the mixer settings in pairs, where rr = nn/2
+  xx33 reset all settings to default
+  0y34 select mono source, y=0 = left, y=1 = right
+
+                                           bits
+ nn  15  14 13 12 11   10    9     8     7    6     5     4     3     2     1     0
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 00 | 0 | 0  0  1  1 | left line mixer gain       | left aux1 mixer gain        |lmute|
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 01 | 0 | 0  1  0  1 | left aux2 mixer gain       | right 2 left mic gain       |mmute|
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 02 | 0 | 0  1  1  1 | left mic mixer gain        | left mic  | left mixer gain |dith |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 03 | 0 | 1  0  0  1 | left mixer input select                |lrfg | left ADC gain   |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 04 | 0 | 1  0  1  1 | right line mixer gain      | right aux1 mixer gain       |rmute|
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 05 | 0 | 1  1  0  1 | right aux2 mixer gain      | left 2 right mic gain       |test |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 06 | 0 | 1  1  1  1 | right mic mixer gain       | right mic |right mixer gain |rbyps|
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 07 | 1 | 0  0  0  1 | right mixer select                     |rrfg | right ADC gain  |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 08 | 1 | 0  0  1  1 | mono mixer gain            |right ADC mux sel|left ADC mux sel |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 09 | 1 | 0  1  0  1 |loopb|left linout|loop|ADCch|TxFch|OffCD|test |loopb|loopb|osamp|
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 0a | 0 | left PCM channel volume                                                     |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 0b | 0 | right PCM channel volume                                                    |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 0c | 0 | left FM channel volume                                                      |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 0d | 0 | right FM channel volume                                                     |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 0e | 0 | left wavetable channel volume                                               |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 0f | 0 | right wavetable channel volume                                              |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 10 | 0 | left PCM expansion channel volume                                           |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 11 | 0 | right PCM expansion channel volume                                          |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 12 | 0 | left FM expansion channel volume                                            |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 13 | 0 | right FM expansion channel volume                                           |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+
+ lmute: left mute
+ mmute: mono mute
+ dith: dithds
+ lrfg:
+ rmute: right mute
+ rbyps: right bypass
+ rrfg:
+ ADCch:
+ TxFch:
+ OffCD:
+ osamp:
+
+ And the following diagram is derived from the description in the CVS archive:
+
+ MIC L (mouthpiece)
+   +------+
+ -->PreAmp>-\
+   +--^---+ |
+      |     |
+    r2b4-5  |                                +--------+
+       /----*-------------------------------->5       |
+       |                                     |        |
+       | /----------------------------------->4       |
+       | |                                   |        |
+       | | /--------------------------------->3 1of5  |  +---+
+       | | |                                 |  mux   >-->AMP>--> ADC L
+       | | | /------------------------------->2       |  +-^-+
+       | | | |                               |        |    |
+ Line  | | | | +----+  +------+  +---+  /---->1       |  r3b3-0
+ ------------*->mute>--> Gain >-->   |  |    |        |
+  L    | | |   +----+  +------+  |   |  |  *->0       |
+       | | |                     |   |  |    +---^----+
+ Aux2  | | |   +----+  +------+  |   |  |        |
+ ----------*--->mute>--> Gain >--> M |  |     r8b0-2
+  L    | |     +----+  +------+  |   |  |
+       | |                       |   |  \------\
+ Aux1  | |     +----+  +------+  |   |         |
+ --------*----->mute>--> Gain >--> I |         |
+  L    |       +----+  +------+  |   |         |
+       |                         |   |         |
+       |       +----+  +------+  |   |  +---+  |
+       *------->mute>--> Gain >--> X >-->AMP>--*
+       |       +----+  +------+  |   |  +-^-+  |
+       |                         |   |    |    |
+       |       +----+  +------+  |   |  r2b1-3 |  
+       | /----->mute>--> Gain >--> E |         |
+       | |     +----+  +------+  |   |         |
+       | |                       |   |         |
+       | |     +----+  +------+  |   |         |
+       | | /--->mute>--> Gain >--> R |         |
+       | | |   +----+  +------+  |   |         |
+       | | |                     |   |         |   r9b8-9
+       | | |   +----+  +------+  |   |         |     |
+       | | | /->mute>--> Gain >-->   |         | +---v---+
+       | | | | +----+  +------+  +---+       /-*->0      |
+ DAC   | | | |                               |   |       |
+ ------------*----------------------------------->?      |  +----+
+  L    | | |                                 |   |  Mux  >-->mute>--> L output
+       | | |                                 | /->?      |  +--^-+
+       | | |                                 | | |       |     |
+       | | |                           /--------->?      |   r0b0
+       | | |                           |     | | +-------+
+       | | |                           |     | |
+ Mono  | | |                           |     | | +-------+
+ ----------*                           |     \--->       |  +----+
+       | | |                           |       | |  Mix  >-->mute>--> Mono output
+       | | |                           |       *->       |  +--^-+
+       | | |                           |       | +-------+     |
+       | | |                           |       |             r1b0
+ DAC   | | |                           |       | +-------+
+ ------------*-------------------------*--------->1      |  +----+
+  R    | | | |                                 | |  Mux  >-->mute>--> R output
+       | | | | +----+  +------+  +---+         *->0      |  +--^-+
+       | | | \->mute>--> Gain >-->   |         | +---^---+     |
+       | | |   +----+  +------+  |   |         |     |       r5b0
+       | | |                     |   |         |   r6b0
+       | | |   +----+  +------+  |   |         |
+       | | \--->mute>--> Gain >--> M |         |
+       | |     +----+  +------+  |   |         |
+       | |                       |   |         |
+       | |     +----+  +------+  |   |         |
+       | *----->mute>--> Gain >--> I |         |
+       | |     +----+  +------+  |   |         |
+       | |                       |   |         |
+       | |     +----+  +------+  |   |  +---+  |
+       \------->mute>--> Gain >--> X >-->AMP>--*
+         |     +----+  +------+  |   |  +-^-+  |
+      /--/                       |   |    |    |
+ Aux1 |        +----+  +------+  |   |  r6b1-3 |
+ -------*------>mute>--> Gain >--> E |         |
+  R   | |      +----+  +------+  |   |         |
+      | |                        |   |         |
+ Aux2 | |      +----+  +------+  |   |  /------/
+ ---------*---->mute>--> Gain >--> R |  |
+  R   | | |    +----+  +------+  |   |  |
+      | | |                      |   |  |    +--------+
+ Line | | |    +----+  +------+  |   |  |  *->0       |
+ -----------*-->mute>--> Gain >-->   |  |    |        |
+  R   | | | |  +----+  +------+  +---+  \---->1       |
+      | | | |                                |        |
+      | | | \-------------------------------->2       |  +---+
+      | | |                                  |  Mux   >-->AMP>--> ADC R
+      | | \---------------------------------->3       |  +-^-+
+      | |                                    |        |    |
+      | \------------------------------------>4       |  r7b3-0
+      |                                      |        |
+      \-----*-------------------------------->5       |
+            |                                +---^----+
+    r6b4-5  |                                    |
+      |     |                                  r8b3-5
+   +--v---+ |
+ -->PreAmp>-/
+   +------+
+ MIC R (electret mic)
index c035ad76cfdd64c00858f2889736f20432ef0971..dffda29c8799c1a2c0709a362400487fb5cc6047 100644 (file)
@@ -11,6 +11,7 @@ The following watchdog drivers are currently implemented:
        ICS     WDT501-P (no fan tachometer)
        ICS     WDT500-P
        Software Only
+       SA1100 Internal Watchdog
        Berkshire Products PC Watchdog Revision A & C (by Ken Hollis)
 
 
@@ -35,6 +36,9 @@ to use "panic=60" as a boot argument as well.
 The wdt card cannot be safely probed for. Instead you need to pass
 wdt=ioaddr,irq as a boot parameter - eg "wdt=0x240,11".
 
+The SA1100 watchdog module can be configured with the "sa1100_margin"
+commandline argument which specifies timeout value in seconds.
+
 The i810 TCO watchdog modules can be configured with the "i810_margin"
 commandline argument which specifies the counter initial value. The counter
 is decremented every 0.6 seconds and default to 50 (30 seconds). Values can
@@ -47,15 +51,15 @@ documentation for the 82801AA and 82801AB datasheet).
 
 Features
 --------
-               WDT501P         WDT500P         Software        Berkshire       i810 TCO
-Reboot Timer      X               X                X               X               X
-External Reboot           X               X                o               o               o
-I/O Port Monitor   o              o                o               X               o
-Temperature       X               o                o               X               o
-Fan Speed          X              o                o               o               o
-Power Under       X               o                o               o               o
-Power Over         X               o                o               o               o
-Overheat           X               o                o               o               o
+               WDT501P         WDT500P         Software        Berkshire       i810 TCO        SA1100WD
+Reboot Timer      X               X                X               X               X               X
+External Reboot           X               X                o               o               o               X
+I/O Port Monitor   o              o                o               X               o               o
+Temperature       X               o                o               X               o               o
+Fan Speed          X              o                o               o               o               o
+Power Under       X               o                o               o               o               o
+Power Over         X               o                o               o               o               o
+Overheat           X               o                o               o               o               o
 
 The external event interfaces on the WDT boards are not currently supported.
 Minor numbers are however allocated for it.
index 48d31d582119478ed787156e9e5cb59e7c21e44f..e92639f69493b98b407229a6ff1e8f7c648f1a51 100644 (file)
@@ -1475,6 +1475,14 @@ L:     linux-usb-devel@lists.sourceforge.net
 W:     http://alpha.dyndns.org/ov511/
 S:     Maintained
 
+USB SE401 DRIVER
+P:     Jeroen Vreeken
+M:     pe1rxq@amsat.org
+L:     linux-usb-users@lists.sourceforge.net
+L:     linux-usb-devel@lists.sourceforge.net
+W:     http://www.chello.nl/~j.vreeken/se401/
+S:     Maintained
+
 USB PEGASUS DRIVER
 P:     Petko Manolov
 M:     petkan@dce.bg
index 1f94e2650962b9cb945cf621dec9ff1a2f19f270..53e019fcc45de8506f5cb0020f2caf27f963f3a9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 10
-EXTRAVERSION =-pre4
+EXTRAVERSION =-pre5
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
index 15580530db8d98fb62b7720692276594c3cbfb05..8e840106b0562e8ca8015e7b805cbd849290850f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  linux/arch/arm/kernel/arthur.c
  *
- *  Copyright (C) 1998, 1999, 2000 Philip Blundell
+ *  Copyright (C) 1998, 1999, 2000, 2001 Philip Blundell
  *
  * Arthur personality
  */
@@ -58,7 +58,7 @@ static void arthur_lcall7(int nr, struct pt_regs *regs)
 {
        struct siginfo info;
        info.si_signo = SIGSWI;
-       info.si_code = nr;
+       info.si_errno = nr;
        /* Bounce it to the emulator */
        send_sig_info(SIGSWI, &info, current);
 }
index ac24e4bf546eaef58ea577b3d30e465e2f6d944e..5c9d87a7d00be45bde4921250d174dae818cc580 100644 (file)
@@ -124,7 +124,7 @@ void machine_power_off(void)
                pm_power_off();
 }
 
-void machine_restart(void * __unused)
+void machine_restart(char * __unused)
 {
        /*
         * Clean and disable cache, and turn off interrupts
index 9301c82b4a3409ba3e5ed95eee273e70ec0b421b..34e413447b544a3c1e16c2800b089c4371f352c3 100644 (file)
@@ -63,8 +63,8 @@ ENTRY(__raw_readsl)
                strne   ip, [r1], #4
                movne   ip, r3, lsr #8
                bne     7b
-               strb    ip, [r1], #1
-               mov     ip, ip, lsr #8
                strh    ip, [r1], #2
+               mov     ip, ip, lsr #16
+               strb    ip, [r1]
                mov     pc, lr
 
index 5b89804766e1390aabe6f33e73218c51355b0a49..12092e2562f2900a8776788823e3cd4d05bd1628 100644 (file)
@@ -25,31 +25,30 @@ ENTRY(__raw_writesl)
 
 2:             bic     r1, r1, #3
                cmp     ip, #2
-               ldr     ip, [r1], #4
-               mov     ip, ip, lsr #16
-               blt     4f
-               bgt     5f
+               ldr     r3, [r1], #4
+               bgt     4f
+               blt     5f
 
-3:             ldr     r3, [r1], #4
+3:             mov     ip, r3, lsr #16
+               ldr     r3, [r1], #4
                orr     ip, ip, r3, lsl #16
                str     ip, [r0]
-               mov     ip, r3, lsr #16
                subs    r2, r2, #1
                bne     3b
                mov     pc, lr
 
-4:             ldr     r3, [r1], #4
+4:             mov     ip, r3, lsr #24
+               ldr     r3, [r1], #4
                orr     ip, ip, r3, lsl #8
                str     ip, [r0]
-               mov     ip, r3, lsr #24
                subs    r2, r2, #1
                bne     4b
                mov     pc, lr
 
-5:             ldr     r3, [r1], #4
+5:             mov     ip, r3, lsr #8
+               ldr     r3, [r1], #4
                orr     ip, ip, r3, lsl #24
                str     ip, [r0]
-               mov     ip, r3, lsr #8
                subs    r2, r2, #1
                bne     5b
                mov     pc, lr
index 3b89befcf67f0a72597de466b42835a6ed7fcd63..2ce96db0a047f8e04cd4db9dfa299544cb2b062f 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/proc_fs.h>
+#include <linux/bitops.h>
 #include <linux/init.h>
 
 #include <asm/system.h>
@@ -366,8 +367,7 @@ do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *reg
        ai_multi += 1;
 
        /* count the number of registers in the mask to be transferred */
-       for (regbits = REGMASK_BITS(instr), nr_regs = 0; regbits; regbits >>= 1)
-               nr_regs += 4;
+       nr_regs = hweight16(REGMASK_BITS(instr)) * 4;
 
        rn = RN_BITS(instr);
        newaddr = eaddr = regs->uregs[rn];
@@ -385,10 +385,12 @@ do_alignment_ldmstm(unsigned long addr, unsigned long instr, struct pt_regs *reg
         * This is a "hint" - we already have eaddr worked out by the
         * processor for us.
         */
-       if (addr != eaddr)
+       if (addr != eaddr) {
                printk(KERN_ERR "LDMSTM: PC = %08lx, instr = %08lx, "
                        "addr = %08lx, eaddr = %08lx\n",
                         instruction_pointer(regs), instr, addr, eaddr);
+               show_regs(regs);
+       }
 
        for (regbits = REGMASK_BITS(instr), rd = 0; regbits; regbits >>= 1, rd += 1)
                if (regbits & 1) {
index 0e5b1a227b2ecac34612d4a46f8f4c4b4c87512a..79a87f34bfa59058e1ac7fd1ebb3bc126ed6209e 100644 (file)
@@ -26,7 +26,8 @@ $(TOPDIR)/include/asm-arm/constants.h: constants-hdr getconstants.c
 # directories
 
 dep:
-       $(TOPDIR)/scripts/mkdep getconstants.c | sed s,getconstants.o,$(TOPDIR)/include/asm-arm/constants.h, > .depend
+       $(TOPDIR)/scripts/mkdep $(CFLAGS) $(EXTRA_CFLAGS) -- getconstants.c |\
+        sed s,getconstants.o,$(TOPDIR)/include/asm-arm/constants.h, > .depend
        $(MAKE) all
 
 .PHONY:        all dep
index 676bdaa8a4f0788f4874fe3fa409ec1cf2ccf58d..4903916c292569908f021202ff065e8ab4a43071 100644 (file)
@@ -6,7 +6,7 @@
 # To add an entry into this database, please see Documentation/arm/README,
 # or contact rmk@arm.linux.org.uk
 #
-# Last update: Thu Aug 9 22:46:02 2001
+# Last update: Thu Aug 23 12:38:13 2001
 #
 # machine_is_xxx       CONFIG_xxxx             MACH_TYPE_xxx           number
 #
@@ -31,7 +31,7 @@ itsy                  SA1100_ITSY             ITSY                    18
 l7200                  ARCH_L7200              L7200                   19
 pleb                   SA1100_PLEB             PLEB                    20
 integrator             ARCH_INTEGRATOR         INTEGRATOR              21
-bitsy                  SA1100_BITSY            BITSY                   22
+h3600                  SA1100_H3600            H3600                   22
 ixp1200                        ARCH_IXP1200            IXP1200                 23
 p720t                  ARCH_P720T              P720T                   24
 assabet                        SA1100_ASSABET          ASSABET                 25
@@ -89,7 +89,7 @@ venus                 ARCH_VENUS              VENUS                   76
 tardis                 ARCH_TARDIS             TARDIS                  77
 mercury                        ARCH_MERCURY            MERCURY                 78
 empeg                  SA1100_EMPEG            EMPEG                   79
-adi_eb                 ARCH_I80200FCC          I80200FCC               80
+adi_evb                        ARCH_I80200FCC          I80200FCC               80
 itt_cpb                        SA1100_ITT_CPB          ITT_CPB                 81
 svc                    SA1100_SVC              SVC                     82
 alpha2                 SA1100_ALPHA2           ALPHA2                  84
@@ -115,3 +115,10 @@ gator                      SA1100_GATOR            GATOR                   103
 granite                        ARCH_GRANITE            GRANITE                 104
 consus                 SA1100_CONSUS           CONSUS                  105
 aaec2000_aaed20                ARCH_AAEC2000_AAED2000  AAEC2000_AAED2000       106
+cdb89712               ARCH_CDB89712           CDB89712                107
+graphicsmaster         SA1100_GRAPHICSMASTER   GRAPHICSMASTER          108
+adsbitsy               SA1100_ADSBITSY         ADSBITSY                109
+cotulla_idp            ARCH_COTULLA_IDP        COTULLA_IDP             110
+plce                   ARCH_PLCE               PLCE                    111
+pt_system3             SA1100_PT_SYSTEM3       PT_SYSTEM3              112
+medalb                 ARCH_MEDALB             MEDALB                  113
index 7ad21812667d9d6b7097a4c9fbb1b40f90f91823..f7c6694c3098709e52029980877c7d61855af3ca 100644 (file)
@@ -175,6 +175,7 @@ CONFIG_IP_MULTICAST=y
 #
 # CONFIG_PHONE is not set
 # CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
 
 #
 # ATA/IDE/MFM/RLL support
index 3ab1b3a931cff0b6bce78ea8cb2083a8b8a5cbd0..37d09163b133b6c3f97ed5a76c922a68bbb3dee1 100644 (file)
@@ -769,9 +769,32 @@ static inline void parse_mem_cmdline (char ** cmdline_p)
        }
 }
 
+
+
+#define PFN_UP(x)      (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define PFN_DOWN(x)    ((x) >> PAGE_SHIFT)
+#define PFN_PHYS(x)    ((x) << PAGE_SHIFT)
+
+/*
+ * 128MB for vmalloc and initrd
+ */
+#define VMALLOC_RESERVE        (unsigned long)(128 << 20)
+#define MAXMEM         (unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE)
+#define MAXMEM_PFN     PFN_DOWN(MAXMEM)
+#define MAX_NONPAE_PFN (1 << 20)
+
+/* On x86 for 1GB low mem the bootmem_bitmap is at worst 32k
+ * that is big but nothing to worry about.  This must be in the kernels
+ * initial page tables so don't even try to get fancy where we allocate it.
+ * This data must be aligned on a page boundary so since I don't
+ * have a handlig __aligned_page_size attribute I allocate an extra
+ * PAGE_SIZE -1 bytes.
+ */
+static unsigned char bootmem_bitmap[((MAXMEM_PFN +7)/8) + PAGE_SIZE -1] __initdata = { 0 };
+
 void __init setup_arch(char **cmdline_p)
 {
-       unsigned long bootmap_size, low_mem_size;
+       unsigned long bootmap_pfn, low_mem_size;
        unsigned long start_pfn, max_pfn, max_low_pfn;
        int i;
 
@@ -805,30 +828,18 @@ void __init setup_arch(char **cmdline_p)
        init_mm.end_data = (unsigned long) &_edata;
        init_mm.brk = (unsigned long) &_end;
 
-       code_resource.start = virt_to_bus(&_text);
-       code_resource.end = virt_to_bus(&_etext)-1;
-       data_resource.start = virt_to_bus(&_etext);
-       data_resource.end = virt_to_bus(&_edata)-1;
+       code_resource.start = virt_to_phys(&_text);
+       code_resource.end = virt_to_phys(&_etext)-1;
+       data_resource.start = virt_to_phys(&_etext);
+       data_resource.end = virt_to_phys(&_edata)-1;
 
        parse_mem_cmdline(cmdline_p);
 
-#define PFN_UP(x)      (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-#define PFN_DOWN(x)    ((x) >> PAGE_SHIFT)
-#define PFN_PHYS(x)    ((x) << PAGE_SHIFT)
-
-/*
- * 128MB for vmalloc and initrd
- */
-#define VMALLOC_RESERVE        (unsigned long)(128 << 20)
-#define MAXMEM         (unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE)
-#define MAXMEM_PFN     PFN_DOWN(MAXMEM)
-#define MAX_NONPAE_PFN (1 << 20)
-
        /*
         * partially used pages are not usable - thus
         * we are rounding upwards:
         */
-       start_pfn = PFN_UP(__pa(&_end));
+       start_pfn = PFN_UP(virt_to_phys(&_end));
 
        /*
         * Find the highest page frame number we have available
@@ -883,7 +894,8 @@ void __init setup_arch(char **cmdline_p)
        /*
         * Initialize the boot-time allocator (with low memory only):
         */
-       bootmap_size = init_bootmem(start_pfn, max_low_pfn);
+       bootmap_pfn = PFN_UP(virt_to_phys(&bootmem_bitmap));
+       init_bootmem(bootmap_pfn, max_low_pfn);
 
        /*
         * Register fully available low RAM pages with the bootmem allocator.
@@ -919,14 +931,32 @@ void __init setup_arch(char **cmdline_p)
                size = last_pfn - curr_pfn;
                free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
        }
-       /*
-        * Reserve the bootmem bitmap itself as well. We do this in two
-        * steps (first step was init_bootmem()) because this catches
-        * the (very unlikely) case of us accidentally initializing the
-        * bootmem allocator with an invalid RAM area.
+       /* 
+        * Reserve the kernel memory.
+        */
+       reserve_bootmem(HIGH_MEMORY, PFN_PHYS(start_pfn) + 
+               PAGE_SIZE-1 - (HIGH_MEMORY));
+
+       /* 
+        * Reserve the initrd 
         */
-       reserve_bootmem(HIGH_MEMORY, (PFN_PHYS(start_pfn) +
-                        bootmap_size + PAGE_SIZE-1) - (HIGH_MEMORY));
+#ifdef CONFIG_BLK_DEV_INITRD
+       initrd_start = 0;
+       initrd_end = 0;
+       if (LOADER_TYPE && INITRD_START && INITRD_SIZE) {
+               if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
+                       reserve_bootmem(INITRD_START, INITRD_SIZE);
+                       initrd_start = INITRD_START + PAGE_OFFSET;
+                       initrd_end = initrd_start + INITRD_SIZE;
+               }
+               else {
+                       printk(KERN_ERR "initrd extends beyond end of memory "
+                           "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
+                           INITRD_START + INITRD_SIZE,
+                           max_low_pfn << PAGE_SHIFT);
+               }
+       }
+#endif
 
        /*
         * reserve physical page 0 - it's a special BIOS page on many boxes,
@@ -962,23 +992,6 @@ void __init setup_arch(char **cmdline_p)
        init_apic_mappings();
 #endif
 
-#ifdef CONFIG_BLK_DEV_INITRD
-       if (LOADER_TYPE && INITRD_START) {
-               if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
-                       reserve_bootmem(INITRD_START, INITRD_SIZE);
-                       initrd_start =
-                               INITRD_START ? INITRD_START + PAGE_OFFSET : 0;
-                       initrd_end = initrd_start+INITRD_SIZE;
-               }
-               else {
-                       printk(KERN_ERR "initrd extends beyond end of memory "
-                           "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
-                           INITRD_START + INITRD_SIZE,
-                           max_low_pfn << PAGE_SHIFT);
-                       initrd_start = 0;
-               }
-       }
-#endif
 
        /*
         * Request address space for all standard RAM and ROM resources
index ed699b7b4e763f9db5d6c0b5de91502f040beee6..0385a00d0086461af0fb74a3c74c30e07c48c0b2 100644 (file)
@@ -313,7 +313,7 @@ do_sigbus:
        tsk->thread.cr2 = address;
        tsk->thread.error_code = error_code;
        tsk->thread.trap_no = 14;
-       info.si_code = SIGBUS;
+       info.si_signo = SIGBUS;
        info.si_errno = 0;
        info.si_code = BUS_ADRERR;
        info.si_addr = (void *)address;
index e8b7b4fef45e05e26e8db479cae595ab18dfb728..9c389fec3795545f7aa1e9c1b4dfe9aaa131ba85 100644 (file)
@@ -51,22 +51,22 @@ unsigned char amiga_vblank;
 unsigned char amiga_psfreq;
 struct amiga_hw_present amiga_hw_present;
 
-static const char s_a500[] __initdata = "A500";
-static const char s_a500p[] __initdata = "A500+";
-static const char s_a600[] __initdata = "A600";
-static const char s_a1000[] __initdata = "A1000";
-static const char s_a1200[] __initdata = "A1200";
-static const char s_a2000[] __initdata = "A2000";
-static const char s_a2500[] __initdata = "A2500";
-static const char s_a3000[] __initdata = "A3000";
-static const char s_a3000t[] __initdata = "A3000T";
-static const char s_a3000p[] __initdata = "A3000+";
-static const char s_a4000[] __initdata = "A4000";
-static const char s_a4000t[] __initdata = "A4000T";
-static const char s_cdtv[] __initdata = "CDTV";
-static const char s_cd32[] __initdata = "CD32";
-static const char s_draco[] __initdata = "Draco";
-static const char *amiga_models[] __initdata = {
+static char s_a500[] __initdata = "A500";
+static char s_a500p[] __initdata = "A500+";
+static char s_a600[] __initdata = "A600";
+static char s_a1000[] __initdata = "A1000";
+static char s_a1200[] __initdata = "A1200";
+static char s_a2000[] __initdata = "A2000";
+static char s_a2500[] __initdata = "A2500";
+static char s_a3000[] __initdata = "A3000";
+static char s_a3000t[] __initdata = "A3000T";
+static char s_a3000p[] __initdata = "A3000+";
+static char s_a4000[] __initdata = "A4000";
+static char s_a4000t[] __initdata = "A4000T";
+static char s_cdtv[] __initdata = "CDTV";
+static char s_cd32[] __initdata = "CD32";
+static char s_draco[] __initdata = "Draco";
+static char *amiga_models[] __initdata = {
     s_a500, s_a500p, s_a600, s_a1000, s_a1200, s_a2000, s_a2500, s_a3000,
     s_a3000t, s_a3000p, s_a4000, s_a4000t, s_cdtv, s_cd32, s_draco,
 };
index 9f765bdeee00af9c3fce2db8d77cad13413f43fc..1ba24b7030fb6af116dbc35e77413c0cb2767984 100644 (file)
@@ -711,7 +711,10 @@ CONFIG_USB_BLUETOOTH=m
 CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
 CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
 CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_HP8200e=y
+CONFIG_USB_STORAGE_SDDR09=y
 CONFIG_USB_ACM=m
 CONFIG_USB_PRINTER=m
 
@@ -742,10 +745,10 @@ CONFIG_USB_DABUSB=m
 #
 # USB Network adaptors
 #
-CONFIG_USB_PLUSB=m
 CONFIG_USB_PEGASUS=m
 CONFIG_USB_CATC=m
-CONFIG_USB_NET1080=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_USBNET=m
 
 #
 # USB port drivers
index e7a281fd55e3b7ddd18ee3e5c69f90e60c820138..b3ec650b66187718bfa4487e143c0880b428c77d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.77 2001/04/05 12:44:34 davem Exp $
+/* $Id: head.S,v 1.78 2001/08/30 03:22:00 kanoj Exp $
  * head.S: Initial boot code for the Sparc64 port of Linux.
  *
  * Copyright (C) 1996,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -488,13 +488,6 @@ tlb_fixup_done:
        call    __bzero
         sub    %o1, %o0, %o1
 
-       /* Now clear empty_zero_page */
-       sethi   %hi(8192), %o1
-       or      %o1, %lo(8192), %o1
-       sethi   %hi(KERNBASE), %g3
-       call    __bzero
-        or     %g3, %lo(KERNBASE), %o0
-
        mov     %l6, %o1                        ! OpenPROM stack
        call    prom_init
         mov    %l7, %o0                        ! OpenPROM cif handler
@@ -647,12 +640,13 @@ set_worklist:
        ret
         restore
 
+/*
+ * The following skips make sure the trap table in ttable.S is aligned
+ * on a 32K boundary as required by the v9 specs for TBA register.
+ */
 sparc64_boot_end:
        .skip   0x2000 + _start - sparc64_boot_end
 bootup_user_stack_end:
-
-       .globl  empty_bad_page
-empty_bad_page:
        .skip   0x2000
 
 #ifdef CONFIG_SBUS
index 21e02899a5fafed2199f789de924d456dc4fabba..f21d3927492dd8459ef8c0f3b174b947edd34fa8 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: ioctl32.c,v 1.121 2001/08/03 14:27:21 davem Exp $
+/* $Id: ioctl32.c,v 1.123 2001/09/02 03:52:07 davem Exp $
  * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
  *
  * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
@@ -3735,6 +3735,7 @@ COMPATIBLE_IOCTL(KDSKBENT)
 COMPATIBLE_IOCTL(KDGKBSENT)
 COMPATIBLE_IOCTL(KDSKBSENT)
 COMPATIBLE_IOCTL(KDGKBDIACR)
+COMPATIBLE_IOCTL(KDKBDREP)
 COMPATIBLE_IOCTL(KDSKBDIACR)
 COMPATIBLE_IOCTL(KDGKBLED)
 COMPATIBLE_IOCTL(KDSKBLED)
index 60e058a4961603f08015fa475bcb9ca30c3754d0..a2a49becc8a9e67045a9fa407312f5dc38c78a64 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sparc64_ksyms.c,v 1.110 2001/08/18 08:08:13 davem Exp $
+/* $Id: sparc64_ksyms.c,v 1.111 2001/08/30 03:22:00 kanoj Exp $
  * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -208,7 +208,6 @@ EXPORT_SYMBOL(sbus_dma_sync_sg);
 EXPORT_SYMBOL(ebus_chain);
 EXPORT_SYMBOL(isa_chain);
 EXPORT_SYMBOL(pci_memspace_mask);
-EXPORT_SYMBOL(empty_zero_page);
 EXPORT_SYMBOL(outsb);
 EXPORT_SYMBOL(outsw);
 EXPORT_SYMBOL(outsl);
index 0eebbc3773e2b927b7b7a55af8a04691cee96597..b913046a50cf91c63ff8a978c0bd30d33cf678de 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: blockops.S,v 1.31 2001/04/05 11:08:12 davem Exp $
+/* $Id: blockops.S,v 1.34 2001/09/03 01:34:18 kanoj Exp $
  * blockops.S: UltraSparc block zero optimized routines.
  *
  * Copyright (C) 1996, 1998, 1999, 2000 David S. Miller (davem@redhat.com)
index a0e97d39a211b1b06326e4a6d6e3ea45b4d80152..78b9fab138057e80cce0a07c2f456ed6744e063b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.56 2001/08/27 18:42:07 kanoj Exp $
+/* $Id: fault.c,v 1.58 2001/09/01 00:11:16 kanoj Exp $
  * arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
 #include <asm/openprom.h>
 #include <asm/oplib.h>
 #include <asm/uaccess.h>
+#include <asm/asi.h>
+#include <asm/lsu.h>
 
 #define ELEMENTS(arr) (sizeof (arr)/sizeof (arr[0]))
 
 extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS];
 
+/*
+ * To debug kernel during syscall entry.
+ */
 void syscall_trace_entry(struct pt_regs *regs)
 {
        printk("scall entry: %s[%d]/cpu%d: %d\n", current->comm, current->pid, smp_processor_id(), (int) regs->u_regs[UREG_G1]);
 }
 
+/*
+ * To debug kernel during syscall exit.
+ */
 void syscall_trace_exit(struct pt_regs *regs)
 {
        printk("scall exit: %s[%d]/cpu%d: %d\n", current->comm, current->pid, smp_processor_id(), (int) regs->u_regs[UREG_G1]);
 }
 
+/*
+ * To debug kernel to catch accesses to certain virtual/physical addresses.
+ * Mode = 0 selects physical watchpoints, mode = 1 selects virtual watchpoints.
+ * flags = VM_READ watches memread accesses, flags = VM_WRITE watches memwrite accesses.
+ * Caller passes in a 64bit aligned addr, with mask set to the bytes that need to be
+ * watched. This is only useful on a single cpu machine for now. After the watchpoint
+ * is detected, the process causing it will be killed, thus preventing an infinite loop.
+ */
+void set_brkpt(unsigned long addr, unsigned char mask, int flags, int mode)
+{
+       unsigned long lsubits = LSU_CONTROL_IC|LSU_CONTROL_DC|LSU_CONTROL_IM|LSU_CONTROL_DM;
+
+       __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
+                            "membar    #Sync"
+                            : /* no outputs */
+                            : "r" (addr), "r" (mode ? VIRT_WATCHPOINT : PHYS_WATCHPOINT),
+                              "i" (ASI_DMMU));
+       lsubits |= ((unsigned long)mask << (mode ? 25 : 33));
+       if (flags & VM_READ)
+               lsubits |= (mode ? LSU_CONTROL_VR : LSU_CONTROL_PR);
+       if (flags & VM_WRITE)
+               lsubits |= (mode ? LSU_CONTROL_VW : LSU_CONTROL_PW);
+       __asm__ __volatile__("stxa %0, [%%g0] %1\n\t"
+                            "membar #Sync"
+                            : /* no outputs */
+                            : "r" (lsubits), "i" (ASI_LSU_CONTROL)
+                            : "memory");
+}
+
 /* Nice, simple, prom library does all the sweating for us. ;) */
 unsigned long __init prom_probe_memory (void)
 {
@@ -180,7 +217,7 @@ static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code,
        unsigned long g2;
        unsigned char asi = ASI_P;
  
-       if (!insn)
+       if ((!insn) && (regs->tstate & TSTATE_PRIV))
                goto cannot_handle;
 
        /* If user insn could be read (thus insn is zero), that
index 5de75ebd2baa14a8fdeba18ce385a72e0a2d1461..41c723a7e3f55c34743dbee2b965b30a1bf364d9 100644 (file)
@@ -1,4 +1,4 @@
-/*  $Id: init.c,v 1.186 2001/08/23 05:14:57 kanoj Exp $
+/*  $Id: init.c,v 1.189 2001/09/02 23:27:18 kanoj Exp $
  *  arch/sparc64/mm/init.c
  *
  *  Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu)
@@ -54,6 +54,8 @@ extern char __init_begin, __init_end, _start, _end, etext, edata;
 extern unsigned int sparc_ramdisk_image;
 extern unsigned int sparc_ramdisk_size;
 
+struct page *mem_map_zero;
+
 int do_check_pgt_cache(int low, int high)
 {
         int freed = 0;
@@ -129,28 +131,6 @@ void flush_icache_range(unsigned long start, unsigned long end)
        }
 }
 
-/*
- * BAD_PAGE is the page that is used for page faults when linux
- * is out-of-memory. Older versions of linux just did a
- * do_exit(), but using this instead means there is less risk
- * for a process dying in kernel mode, possibly leaving an inode
- * unused etc..
- *
- * BAD_PAGETABLE is the accompanying page-table: it is initialized
- * to point to BAD_PAGE entries.
- *
- * ZERO_PAGE is a special page that is used for zero-initialized
- * data and COW.
- */
-pte_t __bad_page(void)
-{
-       memset((void *) &empty_bad_page, 0, PAGE_SIZE);
-       return pte_mkdirty(mk_pte_phys((((unsigned long) &empty_bad_page) 
-                                       - ((unsigned long)&empty_zero_page)
-                                       + phys_base),
-                                      PAGE_SHARED));
-}
-
 void show_mem(void)
 {
        printk("Mem-info:\n");
@@ -304,7 +284,7 @@ static void inherit_prom_mappings(void)
 
        phys_page &= _PAGE_PADDR;
        phys_page += ((unsigned long)&prom_boot_page -
-                     (unsigned long)&empty_zero_page);
+                     (unsigned long)KERNBASE);
 
        if (tlb_type == spitfire) {
                /* Lock this into i/d tlb entry 59 */
@@ -345,7 +325,7 @@ static void inherit_prom_mappings(void)
                BUG();
        }
 
-       tte_vaddr = (unsigned long) &empty_zero_page;
+       tte_vaddr = (unsigned long) KERNBASE;
 
        /* Spitfire Errata #32 workaround */
        __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
@@ -375,7 +355,7 @@ static void inherit_prom_mappings(void)
        remap_func((tlb_type == spitfire ?
                    (spitfire_get_dtlb_data(sparc64_highest_locked_tlbent()) & _PAGE_PADDR) :
                    (cheetah_get_litlb_data(sparc64_highest_locked_tlbent()) & _PAGE_PADDR)),
-                  (unsigned long) &empty_zero_page,
+                  (unsigned long) KERNBASE,
                   prom_get_mmu_ihandle());
 
        /* Flush out that temporary mapping. */
@@ -398,7 +378,7 @@ static void inherit_prom_mappings(void)
                unsigned long size = trans[i].size;
 
                if (vaddr < 0xf0000000UL) {
-                       unsigned long avoid_start = (unsigned long) &empty_zero_page;
+                       unsigned long avoid_start = (unsigned long) KERNBASE;
                        unsigned long avoid_end = avoid_start + (4 * 1024 * 1024);
 
                        if (vaddr < avoid_start) {
@@ -1057,7 +1037,7 @@ unsigned long __init bootmem_init(unsigned long *pages_avail)
         * 4MB locked TLB translation.
         */
        start_pfn  = PAGE_ALIGN((unsigned long) &_end) -
-               ((unsigned long) &empty_zero_page);
+               ((unsigned long) KERNBASE);
 
        /* Adjust up to the physical address where the kernel begins. */
        start_pfn += phys_base;
@@ -1142,7 +1122,7 @@ void __init paging_init(void)
        unsigned long alias_base = phys_base + PAGE_OFFSET;
        unsigned long second_alias_page = 0;
        unsigned long pt, flags, end_pfn, pages_avail;
-       unsigned long shift = alias_base - ((unsigned long)&empty_zero_page);
+       unsigned long shift = alias_base - ((unsigned long)KERNBASE);
        unsigned long real_end;
 
        set_bit(0, mmu_context_bmap);
@@ -1438,7 +1418,7 @@ void __init mem_init(void)
 
        addr = PAGE_OFFSET + phys_base;
        last = PAGE_ALIGN((unsigned long)&_end) -
-               ((unsigned long) &empty_zero_page);
+               ((unsigned long) KERNBASE);
        last += PAGE_OFFSET + phys_base;
        while (addr < last) {
                set_bit(__pa(addr) >> 22, sparc64_valid_addr_bitmap);
@@ -1450,7 +1430,20 @@ void __init mem_init(void)
        max_mapnr = last_valid_pfn - (phys_base >> PAGE_SHIFT);
        high_memory = __va(last_valid_pfn << PAGE_SHIFT);
 
-       num_physpages = free_all_bootmem();
+       num_physpages = free_all_bootmem() - 1;
+
+       /*
+        * Set up the zero page, mark it reserved, so that page count
+        * is not manipulated when freeing the page from user ptes.
+        */
+       mem_map_zero = _alloc_pages(GFP_KERNEL, 0);
+       if (mem_map_zero == NULL) {
+               prom_printf("paging_init: Cannot alloc zero page.\n");
+               prom_halt();
+       }
+       SetPageReserved(mem_map_zero);
+       clear_page(page_address(mem_map_zero));
+
        codepages = (((unsigned long) &etext) - ((unsigned long)&_start));
        codepages = PAGE_ALIGN(codepages) >> PAGE_SHIFT;
        datapages = (((unsigned long) &edata) - ((unsigned long)&etext));
@@ -1464,7 +1457,7 @@ void __init mem_init(void)
                extern pgd_t empty_pg_dir[1024];
                unsigned long addr = (unsigned long)empty_pg_dir;
                unsigned long alias_base = phys_base + PAGE_OFFSET -
-                       (long)(&empty_zero_page);
+                       (long)(KERNBASE);
                
                memset(empty_pg_dir, 0, sizeof(empty_pg_dir));
                addr += alias_base;
@@ -1486,16 +1479,20 @@ void __init mem_init(void)
 
 void free_initmem (void)
 {
-       unsigned long addr;
+       unsigned long addr, initend;
 
-       addr = (unsigned long)(&__init_begin);
-       for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
+       /*
+        * The init section is aligned to 8k in vmlinux.lds. Page align for >8k pagesizes.
+        */
+       addr = PAGE_ALIGN((unsigned long)(&__init_begin));
+       initend = (unsigned long)(&__init_end) & PAGE_MASK;
+       for (; addr < initend; addr += PAGE_SIZE) {
                unsigned long page;
                struct page *p;
 
                page = (addr +
                        ((unsigned long) __va(phys_base)) -
-                       ((unsigned long) &empty_zero_page));
+                       ((unsigned long) KERNBASE));
                p = virt_to_page(page);
 
                ClearPageReserved(p);
index b9b25bb84ceab2bba84908ad30eb7c9fe7d2fb09..f0169fb0039949cfb7f4e2cc480e403338c48592 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: ultra.S,v 1.54 2001/03/22 07:26:04 davem Exp $
+/* $Id: ultra.S,v 1.56 2001/08/30 10:10:32 davem Exp $
  * ultra.S: Don't expand these all over the place...
  *
  * Copyright (C) 1997, 2000 David S. Miller (davem@redhat.com)
@@ -302,7 +302,7 @@ __flush_dcache_page:        /* %o0=kaddr, %o1=flush_icache */
         nop
 
 flush_dcpage_cheetah:
-       sethi           %hi(8192), %o4
+       sethi           %hi(PAGE_SIZE), %o4
 1:     subcc           %o4, (1 << 5), %o4
        stxa            %g0, [%o0 + %o4] ASI_DCACHE_INVALIDATE
        membar          #Sync
@@ -440,13 +440,13 @@ xcall_flush_tlb_mm:
        retry
 
 xcall_flush_tlb_range:
-       sethi           %hi(8192 - 1), %g2
-       or              %g2, %lo(8192 - 1), %g2
+       sethi           %hi(PAGE_SIZE - 1), %g2
+       or              %g2, %lo(PAGE_SIZE - 1), %g2
        andn            %g1, %g2, %g1
        andn            %g7, %g2, %g7
        sub             %g7, %g1, %g3
        add             %g2, 1, %g2
-       srlx            %g3, 13, %g4
+       srlx            %g3, PAGE_SHIFT, %g4
        cmp             %g4, 96
 
        bgu,pn          %icc, xcall_flush_tlb_mm
index 12e9c234e386adf0fe90b90bc60bc227d413dc8a..343fbee58df0103e7c7bdfd00ca3e64b4bec0e2a 100644 (file)
@@ -5,7 +5,6 @@ ENTRY(_start)
 
 SECTIONS
 {
-  empty_zero_page = 0x0000000000400000;
   swapper_pmd_dir = 0x0000000000402000;
   empty_pg_dir = 0x0000000000403000;
   . = 0x4000;
index b0327f71aa66a33d3bf9965c627c2a4d0b4173ff..297d350b0544c527dcf79fd23c076bc2c3368d1a 100644 (file)
  * - s/suser/capable/
  */
 
+/*
+ * 2001/08/26 -- Paul Gortmaker - fix insmod oops on machines with no
+ * floppy controller (lingering task on list after module is gone... boom.)
+ */
+
 #define FLOPPY_SANITY_CHECK
 #undef  FLOPPY_SILENT_DCL_CLEAR
 
@@ -4144,7 +4149,7 @@ static int __init floppy_setup(char *str)
        return 0;
 }
 
-static int have_no_fdc= -EIO;
+static int have_no_fdc= -ENODEV;
 
 
 int __init floppy_init(void)
@@ -4200,7 +4205,6 @@ int __init floppy_init(void)
                del_timer(&fd_timeout);
                blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
                devfs_unregister_blkdev(MAJOR_NR,"fd");
-               del_timer(&fd_timeout);
                return -EBUSY;
        }
 
@@ -4259,9 +4263,7 @@ int __init floppy_init(void)
        if (have_no_fdc) 
        {
                DPRINT("no floppy controllers found\n");
-               floppy_tq.routine = (void *)(void *) empty;
-               mark_bh(IMMEDIATE_BH);
-               schedule();
+               run_task_queue(&tq_immediate);
                if (usage_count)
                        floppy_release_irq_and_dma();
                blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
@@ -4472,6 +4474,7 @@ MODULE_PARM(FLOPPY_IRQ,"i");
 MODULE_PARM(FLOPPY_DMA,"i");
 MODULE_AUTHOR("Alain L. Knaff");
 MODULE_SUPPORTED_DEVICE("fd");
+MODULE_LICENSE("GPL");
 
 #else
 
index 8f33ed372443130d3c9f7a60c9c6787fd2e40b21..829c9c515a9cd0bd9cbd398ede2a0ee5608204d2 100644 (file)
@@ -108,28 +108,11 @@ static void ppc6_wr_data_byte(PPC *ppc, u8 data);
 static u8 ppc6_rd_data_byte(PPC *ppc);
 static u8 ppc6_rd_port(PPC *ppc, u8 port);
 static void ppc6_wr_port(PPC *ppc, u8 port, u8 data);
-static u8 ppc6_rd_reg(PPC *ppc, u8 reg);
-static void ppc6_wr_reg(PPC *ppc, u8 reg, u8 data);
-static u8 ppc6_version(PPC *ppc);
 static void ppc6_rd_data_blk(PPC *ppc, u8 *data, long count);
 static void ppc6_wait_for_fifo(PPC *ppc);
 static void ppc6_wr_data_blk(PPC *ppc, u8 *data, long count);
 static void ppc6_rd_port16_blk(PPC *ppc, u8 port, u8 *data, long length);
-static u16 ppc6_rd_port16(PPC *ppc, u8 port);
-static void ppc6_wr_port16(PPC *ppc, u8 port, u16 data);
 static void ppc6_wr_port16_blk(PPC *ppc, u8 port, u8 *data, long length);
-static u8 ppc6_rd_eeprom_reg(PPC *ppc);
-static void ppc6_wr_eeprom_reg(PPC *ppc, u8 data);
-static void ppc6_eeprom_start(PPC *ppc);
-static void ppc6_eeprom_end(PPC *ppc);
-static void ppc6_set_cs(PPC *ppc);
-static void ppc6_reset_cs(PPC *ppc);
-static u8 ppc6_rd_eeprom_bit(PPC *ppc);
-static void ppc6_eeprom_ready_wait(PPC *ppc);
-static void ppc6_wr_eeprom_bit(PPC *ppc, u8 bit);
-static u16 ppc6_eeprom_read(PPC *ppc, u8 addr);
-static u8 ppc6_irq_test(PPC *ppc);
-static u8 ppc6_rd_extout(PPC *ppc);
 static void ppc6_wr_extout(PPC *ppc, u8 regdata);
 static int ppc6_open(PPC *ppc);
 static void ppc6_close(PPC *ppc);
@@ -304,7 +287,7 @@ static void ppc6_wr_data_byte(PPC *ppc, u8 data)
 
 static u8 ppc6_rd_data_byte(PPC *ppc)
 {
-       u8 data;
+       u8 data = 0;
 
        switch(ppc->mode)
        {
@@ -393,33 +376,6 @@ static void ppc6_wr_port(PPC *ppc, u8 port, u8 data)
 
 //***************************************************************************
 
-static u8 ppc6_rd_reg(PPC *ppc, u8 reg)
-{
-       ppc6_send_cmd(ppc,(u8)(reg | ACCESS_REG | ACCESS_READ));
-
-       return(ppc6_rd_data_byte(ppc));
-}
-
-//***************************************************************************
-
-static void ppc6_wr_reg(PPC *ppc, u8 reg, u8 data)
-{
-       ppc6_send_cmd(ppc,(u8)(reg | ACCESS_REG | ACCESS_WRITE));
-
-       ppc6_wr_data_byte(ppc, data);
-}
-
-//***************************************************************************
-
-static u8 ppc6_version(PPC *ppc)
-{
-       ppc6_send_cmd(ppc,(REG_VERSION | ACCESS_REG | ACCESS_READ));
-
-       return(ppc6_rd_data_byte(ppc) & 0x3F);
-}
-
-//***************************************************************************
-
 static void ppc6_rd_data_blk(PPC *ppc, u8 *data, long count)
 {
        switch(ppc->mode)
@@ -708,44 +664,6 @@ static void ppc6_rd_port16_blk(PPC *ppc, u8 port, u8 *data, long length)
 
 //***************************************************************************
 
-static u16 ppc6_rd_port16(PPC *ppc, u8 port)
-{
-       u16 data;
-
-       ppc6_send_cmd(ppc, (CMD_PREFIX_SET | PREFIX_IO16));
-
-       ppc6_send_cmd(ppc, (u8)(port | ACCESS_PORT | ACCESS_READ));
-
-       data = ppc6_rd_data_byte(ppc);
-
-       ppc6_send_cmd(ppc, (u8)(port | ACCESS_PORT | ACCESS_READ));
-
-       data += (u16)ppc6_rd_data_byte(ppc) << 8;
-
-       ppc6_send_cmd(ppc, (CMD_PREFIX_RESET | PREFIX_IO16));
-
-       return(data);
-}
-
-//***************************************************************************
-
-static void ppc6_wr_port16(PPC *ppc, u8 port, u16 data)
-{
-       ppc6_send_cmd(ppc, (CMD_PREFIX_SET | PREFIX_IO16));
-
-       ppc6_send_cmd(ppc, (u8)(port | ACCESS_PORT | ACCESS_WRITE));
-
-       ppc6_wr_data_byte(ppc, (u8)data);
-
-       ppc6_send_cmd(ppc, (u8)(port | ACCESS_PORT | ACCESS_WRITE));
-
-       ppc6_wr_data_byte(ppc, (u8)(data >> 8));
-
-       ppc6_send_cmd(ppc, (CMD_PREFIX_RESET | PREFIX_IO16));
-}
-
-//***************************************************************************
-
 static void ppc6_wr_port16_blk(PPC *ppc, u8 port, u8 *data, long length)
 {
        length = length << 1;
@@ -766,148 +684,6 @@ static void ppc6_wr_port16_blk(PPC *ppc, u8 port, u8 *data, long length)
 
 //***************************************************************************
 
-static u8 ppc6_rd_eeprom_reg(PPC *ppc)
-{
-       ppc6_send_cmd(ppc, (REG_EEPROM | ACCESS_REG | ACCESS_READ));
-
-       return(ppc6_rd_data_byte(ppc));
-}
-
-//***************************************************************************
-
-static void ppc6_wr_eeprom_reg(PPC *ppc, u8 data)
-{
-       ppc6_send_cmd(ppc, (REG_EEPROM | ACCESS_REG | ACCESS_WRITE));
-
-       ppc6_wr_data_byte(ppc, data);
-}
-
-//***************************************************************************
-
-static void ppc6_eeprom_start(PPC *ppc)
-{
-       ppc6_wr_eeprom_reg(ppc, EEPROM_EN);
-}
-
-//***************************************************************************
-
-static void ppc6_eeprom_end(PPC *ppc)
-{
-       ppc6_wr_eeprom_reg(ppc, 0);
-}
-
-//***************************************************************************
-
-static void ppc6_set_cs(PPC *ppc)
-{
-       ppc6_wr_eeprom_reg(ppc, (u8)(ppc6_rd_eeprom_reg(ppc) | EEPROM_CS));
-}
-
-//***************************************************************************
-
-static void ppc6_reset_cs(PPC *ppc)
-{
-       ppc6_wr_eeprom_reg(ppc, (u8)(ppc6_rd_eeprom_reg(ppc) & ~EEPROM_CS));
-}
-
-//***************************************************************************
-
-static u8 ppc6_rd_eeprom_bit(PPC *ppc)
-{
-       ppc6_send_cmd(ppc, (REG_STATUS | ACCESS_REG | ACCESS_READ));
-
-       if (ppc6_rd_data_byte(ppc) & STATUS_EEPROM_DO)
-               return(1);
-       else
-               return(0);
-}
-
-//***************************************************************************
-
-static void ppc6_eeprom_ready_wait(PPC *ppc)
-{
-       ppc6_set_cs(ppc);
-
-       while(ppc6_rd_eeprom_bit(ppc));
-
-       ppc6_reset_cs(ppc);
-}
-
-//***************************************************************************
-
-static void ppc6_wr_eeprom_bit(PPC *ppc, u8 bit)
-{
-       u8 eereg;
-
-       eereg = ppc6_rd_eeprom_reg(ppc);
-
-       eereg &= ~(EEPROM_SK | EEPROM_DI);
-
-       if (bit & 1)
-               eereg |= EEPROM_DI;
-
-       ppc6_wr_eeprom_reg(ppc, eereg);
-
-       eereg |= EEPROM_SK;
-
-       ppc6_wr_eeprom_reg(ppc, eereg);
-
-       eereg &= ~EEPROM_SK;
-
-       ppc6_wr_eeprom_reg(ppc, eereg);
-}
-
-//***************************************************************************
-
-static u16 ppc6_eeprom_read(PPC *ppc, u8 addr)
-{
-       int i;
-       u16 data;
-
-       ppc6_set_cs(ppc);
-
-       ppc6_wr_eeprom_bit(ppc, 1); // Start bit
-
-       ppc6_wr_eeprom_bit(ppc, 1); // opcode 10 (read)
-       ppc6_wr_eeprom_bit(ppc, 0);
-
-       for(i=0; i<6; i++)
-               ppc6_wr_eeprom_bit(ppc, (u8)((addr >> (5 - i)) & 1));
-
-       data = 0;
-
-       for(i=0; i<16; i++)
-       {
-               ppc6_wr_eeprom_bit(ppc,0);
-
-               data = (data << 1) | ppc6_rd_eeprom_bit(ppc);
-       }
-
-       ppc6_reset_cs(ppc);
-
-       return(data);
-}
-
-//***************************************************************************
-
-static u8 ppc6_irq_test(PPC *ppc)
-{
-       ppc6_send_cmd(ppc,(REG_STATUS | ACCESS_REG | ACCESS_READ));
-
-       return(ppc6_rd_data_byte(ppc) & STATUS_IRQA);
-}
-
-//***************************************************************************
-
-static u8 ppc6_rd_extout(PPC *ppc)
-{
-       ppc6_send_cmd(ppc,(REG_VERSION | ACCESS_REG | ACCESS_READ));
-
-       return((ppc6_rd_data_byte(ppc) & 0xC0) >> 6);
-}
-
-//***************************************************************************
-
 static void ppc6_wr_extout(PPC *ppc, u8 regdata)
 {
        ppc6_send_cmd(ppc,(REG_VERSION | ACCESS_REG | ACCESS_WRITE));
index 9afe806b540816bd46d07274d1a8aae92e511b2b..843478e29de7f810efeb53ccf317d696f7b18755 100644 (file)
@@ -100,7 +100,7 @@ static int rd_hardsec[NUM_RAMDISKS];                /* Size of real blocks in bytes */
 static int rd_blocksizes[NUM_RAMDISKS];                /* Size of 1024 byte blocks :)  */
 static int rd_kbsize[NUM_RAMDISKS];            /* Size in blocks of 1024 bytes */
 static devfs_handle_t devfs_handle;
-static struct inode *rd_inode[NUM_RAMDISKS];   /* Protected device inodes */
+static struct block_device *rd_bdev[NUM_RAMDISKS];/* Protected device data */
 
 /*
  * Parameters for the boot-loading of the RAM disk.  These are set by
@@ -259,7 +259,7 @@ static int rd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, un
                        /* special: we want to release the ramdisk memory,
                           it's not like with the other blockdevices where
                           this ioctl only flushes away the buffer cache. */
-                       if ((atomic_read(&inode->i_bdev->bd_openers) > 2))
+                       if ((atomic_read(rd_bdev[minor]->bd_openers) > 2))
                                return -EBUSY;
                        destroy_buffers(inode->i_rdev);
                        rd_blocksizes[minor] = 0;
@@ -305,7 +305,6 @@ static int initrd_release(struct inode *inode,struct file *file)
        lock_kernel();
        if (!--initrd_users) {
                blkdev_put(inode->i_bdev, BDEV_FILE);
-               iput(inode);
                free_initrd_mem(initrd_start, initrd_end);
                initrd_start = 0;
        }
@@ -324,8 +323,10 @@ static struct file_operations initrd_fops = {
 
 static int rd_open(struct inode * inode, struct file * filp)
 {
+       int unit = DEVICE_NR(inode->i_rdev);
+
 #ifdef CONFIG_BLK_DEV_INITRD
-       if (DEVICE_NR(inode->i_rdev) == INITRD_MINOR) {
+       if (unit == INITRD_MINOR) {
                if (!initrd_start) return -ENODEV;
                initrd_users++;
                filp->f_op = &initrd_fops;
@@ -333,16 +334,15 @@ static int rd_open(struct inode * inode, struct file * filp)
        }
 #endif
 
-       if (DEVICE_NR(inode->i_rdev) >= NUM_RAMDISKS)
+       if (unit >= NUM_RAMDISKS)
                return -ENXIO;
 
        /*
         * Immunize device against invalidate_buffers() and prune_icache().
         */
-       if (rd_inode[DEVICE_NR(inode->i_rdev)] == NULL) {
-               if (!inode->i_bdev) return -ENXIO;
-               if ((rd_inode[DEVICE_NR(inode->i_rdev)] = igrab(inode)) != NULL)
-                       atomic_inc(&rd_inode[DEVICE_NR(inode->i_rdev)]->i_bdev->bd_openers);
+       if (rd_bdev[unit] == NULL) {
+               rd_bdev[unit] = bdget(kdev_t_to_nr(inode->i_rdev));
+               atomic_inc(&rd_bdev[unit]->bd_openers);
        }
 
        MOD_INC_USE_COUNT;
@@ -369,12 +369,11 @@ static void __exit rd_cleanup (void)
        int i;
 
        for (i = 0 ; i < NUM_RAMDISKS; i++) {
-               if (rd_inode[i]) {
-                       /* withdraw invalidate_buffers() and prune_icache() immunity */
-                       atomic_dec(&rd_inode[i]->i_bdev->bd_openers);
-                       /* remove stale pointer to module address space */
-                       rd_inode[i]->i_bdev->bd_op = NULL;
-                       iput(rd_inode[i]);
+               struct block_device *bdev = rd_bdev[i];
+               rd_bdev[i] = NULL;
+               if (bdev) {
+                       blkdev_put(bdev);
+                       bdput(bdev);
                }
                destroy_buffers(MKDEV(MAJOR_NR, i));
        }
index bc486408144956be117eaef9c808d1fe61f0bd5f..523da30853e5807270fc3ada38fb403aa4e46a6f 100644 (file)
@@ -3,6 +3,6 @@ comment 'Bluetooth device drivers'
 
 dep_tristate 'HCI USB driver' CONFIG_BLUEZ_HCIUSB $CONFIG_BLUEZ $CONFIG_USB
 dep_tristate 'HCI UART driver' CONFIG_BLUEZ_HCIUART $CONFIG_BLUEZ
-dep_tristate 'HCI EMU (virtual device) driver' CONFIG_BLUEZ_HCIEMU $CONFIG_BLUEZ
+dep_tristate 'HCI VHCI virtual HCI device driver' CONFIG_BLUEZ_HCIVHCI $CONFIG_BLUEZ
 
 endmenu
index cd0247c80f38438b49fc25db55faec6211a0987d..6a259502186e7ad8a5b5ffd7748d05dd427c1fa8 100644 (file)
@@ -6,6 +6,6 @@ O_TARGET        := bluetooth.o
 
 obj-$(CONFIG_BLUEZ_HCIUSB)     += hci_usb.o
 obj-$(CONFIG_BLUEZ_HCIUART)    += hci_uart.o
-obj-$(CONFIG_BLUEZ_HCIEMU)     += hci_emu.o
+obj-$(CONFIG_BLUEZ_HCIVHCI)    += hci_vhci.o
 
 include $(TOPDIR)/Rules.make
diff --git a/drivers/bluetooth/hci_emu.c b/drivers/bluetooth/hci_emu.c
deleted file mode 100644 (file)
index 87066ff..0000000
+++ /dev/null
@@ -1,330 +0,0 @@
-/* 
-   BlueZ - Bluetooth protocol stack for Linux
-   Copyright (C) 2000-2001 Qualcomm Incorporated
-
-   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation;
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
-   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
-   SOFTWARE IS DISCLAIMED.
-*/
-
-/*
- * BlueZ HCI virtual device driver.
- *
- * $Id: hci_emu.c,v 1.1 2001/06/01 08:12:10 davem Exp $ 
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/fcntl.h>
-#include <linux/init.h>
-#include <linux/random.h>
-
-#include <linux/skbuff.h>
-#include <linux/miscdevice.h>
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
-
-#include <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/bluez.h>
-#include <net/bluetooth/hci_core.h>
-#include <net/bluetooth/hci_emu.h>
-
-/* HCI device part */
-
-int hci_emu_open(struct hci_dev *hdev)
-{
-       hdev->flags |= HCI_RUNNING;
-       return 0;
-}
-
-int hci_emu_flush(struct hci_dev *hdev)
-{
-       struct hci_emu_struct *hci_emu = (struct hci_emu_struct *) hdev->driver_data;
-       bluez_skb_queue_purge(&hci_emu->readq);
-       return 0;
-}
-
-int hci_emu_close(struct hci_dev *hdev)
-{
-       hdev->flags &= ~HCI_RUNNING;
-       hci_emu_flush(hdev);
-       return 0;
-}
-
-int hci_emu_send_frame(struct sk_buff *skb)
-{
-       struct hci_dev* hdev = (struct hci_dev *) skb->dev;
-       struct hci_emu_struct *hci_emu;
-
-       if (!hdev) {
-               ERR("Frame for uknown device (hdev=NULL)");
-               return -ENODEV;
-       }
-
-       if (!(hdev->flags & HCI_RUNNING))
-               return -EBUSY;
-
-       hci_emu = (struct hci_emu_struct *) hdev->driver_data;
-
-       memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
-       skb_queue_tail(&hci_emu->readq, skb);
-
-       if (hci_emu->flags & HCI_EMU_FASYNC)
-               kill_fasync(&hci_emu->fasync, SIGIO, POLL_IN);
-       wake_up_interruptible(&hci_emu->read_wait);
-
-       return 0;
-}
-
-/* Character device part */
-
-/* Poll */
-static unsigned int hci_emu_chr_poll(struct file *file, poll_table * wait)
-{  
-       struct hci_emu_struct *hci_emu = (struct hci_emu_struct *) file->private_data;
-
-       poll_wait(file, &hci_emu->read_wait, wait);
-       if (skb_queue_len(&hci_emu->readq))
-               return POLLIN | POLLRDNORM;
-
-       return POLLOUT | POLLWRNORM;
-}
-
-/* Get packet from user space buffer(already verified) */
-static __inline__ ssize_t hci_emu_get_user(struct hci_emu_struct *hci_emu, const char *buf, size_t count)
-{
-       struct sk_buff *skb;
-
-       if (count > HCI_EMU_MAX_FRAME)
-               return -EINVAL;
-
-       if (!(skb = bluez_skb_alloc(count, GFP_KERNEL)))
-               return -ENOMEM;
-       
-       copy_from_user(skb_put(skb, count), buf, count); 
-
-       skb->dev = (void *) &hci_emu->hdev;
-       skb->pkt_type = *((__u8 *) skb->data);
-       skb_pull(skb, 1);
-
-       hci_recv_frame(skb);
-
-       return count;
-} 
-
-/* Write */
-static ssize_t hci_emu_chr_write(struct file * file, const char * buf, 
-                            size_t count, loff_t *pos)
-{
-       struct hci_emu_struct *hci_emu = (struct hci_emu_struct *) file->private_data;
-
-       if (verify_area(VERIFY_READ, buf, count))
-               return -EFAULT;
-
-       return hci_emu_get_user(hci_emu, buf, count);
-}
-
-/* Put packet to user space buffer(already verified) */
-static __inline__ ssize_t hci_emu_put_user(struct hci_emu_struct *hci_emu,
-                                      struct sk_buff *skb, char *buf, int count)
-{
-       int len = count, total = 0;
-       char *ptr = buf;
-
-       len = MIN(skb->len, len); 
-       copy_to_user(ptr, skb->data, len); 
-       total += len;
-
-       hci_emu->hdev.stat.byte_tx += len;
-       switch (skb->pkt_type) {
-               case HCI_COMMAND_PKT:
-                       hci_emu->hdev.stat.cmd_tx++;
-                       break;
-
-               case HCI_ACLDATA_PKT:
-                       hci_emu->hdev.stat.acl_tx++;
-                       break;
-
-               case HCI_SCODATA_PKT:
-                       hci_emu->hdev.stat.cmd_tx++;
-                       break;
-       };
-
-       return total;
-}
-
-/* Read */
-static ssize_t hci_emu_chr_read(struct file * file, char * buf, size_t count, loff_t *pos)
-{
-       struct hci_emu_struct *hci_emu = (struct hci_emu_struct *) file->private_data;
-       DECLARE_WAITQUEUE(wait, current);
-       struct sk_buff *skb;
-       ssize_t ret = 0;
-
-       add_wait_queue(&hci_emu->read_wait, &wait);
-       while (count) {
-               current->state = TASK_INTERRUPTIBLE;
-
-               /* Read frames from device queue */
-               if (!(skb = skb_dequeue(&hci_emu->readq))) {
-                       if (file->f_flags & O_NONBLOCK) {
-                               ret = -EAGAIN;
-                               break;
-                       }
-                       if (signal_pending(current)) {
-                               ret = -ERESTARTSYS;
-                               break;
-                       }
-
-                       /* Nothing to read, let's sleep */
-                       schedule();
-                       continue;
-               }
-
-               if (!verify_area(VERIFY_WRITE, buf, count))
-                       ret = hci_emu_put_user(hci_emu, skb, buf, count);
-               else
-                       ret = -EFAULT;
-
-               bluez_skb_free(skb);
-               break;
-       }
-
-       current->state = TASK_RUNNING;
-       remove_wait_queue(&hci_emu->read_wait, &wait);
-
-       return ret;
-}
-
-static int hci_emu_chr_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-       return -EINVAL;
-}
-
-static int hci_emu_chr_fasync(int fd, struct file *file, int on)
-{
-       struct hci_emu_struct *hci_emu = (struct hci_emu_struct *) file->private_data;
-       int ret;
-
-       if ((ret = fasync_helper(fd, file, on, &hci_emu->fasync)) < 0)
-               return ret; 
-       if (on)
-               hci_emu->flags |= HCI_EMU_FASYNC;
-       else 
-               hci_emu->flags &= ~HCI_EMU_FASYNC;
-
-       return 0;
-}
-
-static int hci_emu_chr_open(struct inode *inode, struct file * file)
-{
-       struct hci_emu_struct *hci_emu = NULL; 
-       struct hci_dev *hdev;
-
-       if (!(hci_emu = kmalloc(sizeof(struct hci_emu_struct), GFP_KERNEL)))
-               return -ENOMEM;
-
-       memset(hci_emu, 0, sizeof(struct hci_emu_struct));
-
-       skb_queue_head_init(&hci_emu->readq);
-       init_waitqueue_head(&hci_emu->read_wait);
-
-       /* Initialize and register HCI device */
-       hdev = &hci_emu->hdev;
-
-       hdev->type = HCI_EMU;
-       hdev->driver_data = hci_emu;
-
-       hdev->open  = hci_emu_open;
-       hdev->close = hci_emu_close;
-       hdev->flush = hci_emu_flush;
-       hdev->send  = hci_emu_send_frame;
-
-       if (hci_register_dev(hdev) < 0) {
-               kfree(hci_emu);
-               return -EBUSY;
-       }
-
-       file->private_data = hci_emu;
-       return 0;   
-}
-
-static int hci_emu_chr_close(struct inode *inode, struct file *file)
-{
-       struct hci_emu_struct *hci_emu = (struct hci_emu_struct *) file->private_data;
-
-       if (hci_unregister_dev(&hci_emu->hdev) < 0) {
-               ERR("Can't unregister HCI device %s", hci_emu->hdev.name);
-       }
-
-       kfree(hci_emu);
-       file->private_data = NULL;
-
-       return 0;
-}
-
-static struct file_operations hci_emu_fops = {
-       owner:  THIS_MODULE,    
-       llseek: no_llseek,
-       read:   hci_emu_chr_read,
-       write:  hci_emu_chr_write,
-       poll:   hci_emu_chr_poll,
-       ioctl:  hci_emu_chr_ioctl,
-       open:   hci_emu_chr_open,
-       release:hci_emu_chr_close,
-       fasync: hci_emu_chr_fasync              
-};
-
-static struct miscdevice hci_emu_miscdev=
-{
-        HCI_EMU_MINOR,
-        "hci_emu",
-        &hci_emu_fops
-};
-
-int __init hci_emu_init(void)
-{
-       INF("BlueZ HCI EMU driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",  
-               BLUEZ_VER);
-       INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-
-       if (misc_register(&hci_emu_miscdev)) {
-               ERR("Can't register misc device %d\n", HCI_EMU_MINOR);
-               return -EIO;
-       }
-
-       return 0;
-}
-
-void hci_emu_cleanup(void)
-{
-       misc_deregister(&hci_emu_miscdev);
-}
-
-module_init(hci_emu_init);
-module_exit(hci_emu_cleanup);
index f5ef6d5ddbc32f9ffc29997d5aeba61151916811..bc709e0ebe68c1a9b80a9e4e8d5d496f0d0975ad 100644 (file)
@@ -25,8 +25,9 @@
 /*
  * BlueZ HCI UART driver.
  *
- * $Id: hci_uart.c,v 1.1 2001/06/01 08:12:10 davem Exp $    
+ * $Id: hci_uart.c,v 1.5 2001/07/05 18:42:44 maxk Exp $    
  */
+#define VERSION "1.0"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -84,7 +85,7 @@ int n_hci_flush(struct hci_dev *hdev)
        DBG("hdev %p tty %p", hdev, tty);
 
        /* Drop TX queue */
-       bluez_skb_queue_purge(&n_hci->txq);
+       skb_queue_purge(&n_hci->txq);
 
        /* Flush any pending characters in the driver and discipline. */
        if (tty->ldisc.flush_buffer)
@@ -139,7 +140,7 @@ int n_hci_tx_wakeup(struct n_hci *n_hci)
 
                if (len == skb->len) {
                        /* Full frame was sent */
-                       bluez_skb_free(skb);
+                       kfree_skb(skb);
                } else {
                        /* Subtract sent part and requeue  */
                        skb_pull(skb, len);
@@ -334,7 +335,7 @@ static inline int n_hci_check_data_len(struct n_hci *n_hci, int len)
                hci_recv_frame(n_hci->rx_skb);
        } else if (len > room) {
                ERR("Data length is to large");
-               bluez_skb_free(n_hci->rx_skb);
+               kfree_skb(n_hci->rx_skb);
                n_hci->hdev.stat.err_rx++;
        } else {
                n_hci->rx_state = WAIT_DATA;
@@ -356,7 +357,7 @@ static inline void n_hci_rx(struct n_hci *n_hci, const __u8 * data, char *flags,
        hci_sco_hdr   *sh;
        register int len, type, dlen;
 
-       DBG("count %d state %d rx_count %d", count, n_hci->rx_state, n_hci->rx_count);
+       DBG("count %d state %ld rx_count %ld", count, n_hci->rx_state, n_hci->rx_count);
 
        n_hci->hdev.stat.byte_rx += count;
 
@@ -441,7 +442,7 @@ static inline void n_hci_rx(struct n_hci *n_hci, const __u8 * data, char *flags,
                ptr++; count--;
 
                /* Allocate packet */
-               if (!(n_hci->rx_skb = bluez_skb_alloc(HCI_MAX_READ, GFP_ATOMIC))) {
+               if (!(n_hci->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
                        ERR("Can't allocate mem for new packet");
 
                        n_hci->rx_state = WAIT_PACKET_TYPE;
@@ -536,7 +537,7 @@ int __init n_hci_init(void)
        int err;
 
        INF("BlueZ HCI UART driver ver %s Copyright (C) 2000,2001 Qualcomm Inc", 
-               BLUEZ_VER);
+               VERSION);
        INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
 
        /* Register the tty discipline */
@@ -573,3 +574,7 @@ void n_hci_cleanup(void)
 
 module_init(n_hci_init);
 module_exit(n_hci_cleanup);
+
+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
+MODULE_DESCRIPTION("BlueZ HCI UART driver ver " VERSION);
+MODULE_LICENSE("GPL");
index 2fe52aa4da231a641c9c246acc88469a9226f695..8e87a8995acc74745874abe494da6bd025953736 100644 (file)
@@ -28,8 +28,9 @@
  *    Copyright (c) 2000 Greg Kroah-Hartman        <greg@kroah.com>
  *    Copyright (c) 2000 Mark Douglas Corner       <mcorner@umich.edu>
  *
- * $Id: hci_usb.c,v 1.1 2001/06/01 08:12:10 davem Exp $    
+ * $Id: hci_usb.c,v 1.5 2001/07/05 18:42:44 maxk Exp $    
  */
+#define VERSION "1.0"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -106,7 +107,7 @@ static void hci_usb_free_bufs(struct hci_usb *husb)
                usb_free_urb(husb->write_urb);
 
        if (husb->intr_skb)
-               bluez_skb_free(husb->intr_skb);
+               kfree_skb(husb->intr_skb);
 }
 
 /* ------- Interface to HCI layer ------ */
@@ -139,8 +140,8 @@ int hci_usb_flush(struct hci_dev *hdev)
        DBG("%s", hdev->name);
 
        /* Drop TX queues */
-       bluez_skb_queue_purge(&husb->tx_ctrl_q);
-       bluez_skb_queue_purge(&husb->tx_write_q);
+       skb_queue_purge(&husb->tx_ctrl_q);
+       skb_queue_purge(&husb->tx_write_q);
 
        return 0;
 }
@@ -173,7 +174,7 @@ void hci_usb_ctrl_wakeup(struct hci_usb *husb)
                goto done;
 
        if (hci_usb_ctrl_msg(husb, skb)){
-               bluez_skb_free(skb);
+               kfree_skb(skb);
                goto done;
        }
 
@@ -271,7 +272,7 @@ static void hci_usb_ctrl(struct urb *urb)
                DBG("%s ctrl status: %d", hdev->name, urb->status);
 
        clear_bit(HCI_TX_CTRL, &husb->tx_state);
-       bluez_skb_free(skb);
+       kfree_skb(skb);
 
        /* Wake up device */
        hci_usb_ctrl_wakeup(husb);
@@ -294,7 +295,7 @@ static void hci_usb_bulk_write(struct urb *urb)
                DBG("%s bulk write status: %d", hdev->name, urb->status);
 
        clear_bit(HCI_TX_WRITE, &husb->tx_state);
-       bluez_skb_free(skb);
+       kfree_skb(skb);
 
        /* Wake up device */
        hci_usb_write_wakeup(husb);
@@ -352,7 +353,7 @@ static void hci_usb_intr(struct urb *urb)
                if (count > husb->intr_count) {
                        ERR("%s bad frame len %d (expected %d)", husb->hdev.name, count, husb->intr_count);
 
-                       bluez_skb_free(skb);
+                       kfree_skb(skb);
                        husb->intr_skb = NULL;
                        husb->intr_count = 0;
                        return;
@@ -563,7 +564,7 @@ static void * hci_usb_probe(struct usb_device *udev, unsigned int ifnum, const s
 
        ep = bulk_in_ep;
        pipe = usb_rcvbulkpipe(udev, ep->bEndpointAddress);
-       size = HCI_USB_MAX_READ;
+       size = HCI_MAX_FRAME_SIZE;
 
        if (!(buf = kmalloc(size, GFP_KERNEL))) {
                ERR("Can't allocate: read buffer");
@@ -652,7 +653,7 @@ int hci_usb_init(void)
        int err;
 
        INF("BlueZ HCI USB driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",  
-               BLUEZ_VER);
+               VERSION);
        INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
 
        if ((err = usb_register(&hci_usb_driver)) < 0)
@@ -668,3 +669,7 @@ void hci_usb_cleanup(void)
 
 module_init(hci_usb_init);
 module_exit(hci_usb_cleanup);
+
+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
+MODULE_DESCRIPTION("BlueZ HCI USB driver ver " VERSION);
+MODULE_LICENSE("GPL");
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
new file mode 100644 (file)
index 0000000..dc47bbc
--- /dev/null
@@ -0,0 +1,340 @@
+/* 
+   BlueZ - Bluetooth protocol stack for Linux
+   Copyright (C) 2000-2001 Qualcomm Incorporated
+
+   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License version 2 as
+   published by the Free Software Foundation;
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
+   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
+   SOFTWARE IS DISCLAIMED.
+*/
+
+/*
+ * BlueZ HCI virtual device driver.
+ *
+ * $Id: hci_vhci.c,v 1.3 2001/08/03 04:19:50 maxk Exp $ 
+ */
+#define VERSION "1.0"
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/fcntl.h>
+#include <linux/init.h>
+#include <linux/random.h>
+
+#include <linux/skbuff.h>
+#include <linux/miscdevice.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/bluez.h>
+#include <net/bluetooth/hci_core.h>
+#include <net/bluetooth/hci_vhci.h>
+
+/* HCI device part */
+
+int hci_vhci_open(struct hci_dev *hdev)
+{
+       hdev->flags |= HCI_RUNNING;
+       return 0;
+}
+
+int hci_vhci_flush(struct hci_dev *hdev)
+{
+       struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) hdev->driver_data;
+       skb_queue_purge(&hci_vhci->readq);
+       return 0;
+}
+
+int hci_vhci_close(struct hci_dev *hdev)
+{
+       hdev->flags &= ~HCI_RUNNING;
+       hci_vhci_flush(hdev);
+       return 0;
+}
+
+int hci_vhci_send_frame(struct sk_buff *skb)
+{
+       struct hci_dev* hdev = (struct hci_dev *) skb->dev;
+       struct hci_vhci_struct *hci_vhci;
+
+       if (!hdev) {
+               ERR("Frame for uknown device (hdev=NULL)");
+               return -ENODEV;
+       }
+
+       if (!(hdev->flags & HCI_RUNNING))
+               return -EBUSY;
+
+       hci_vhci = (struct hci_vhci_struct *) hdev->driver_data;
+
+       memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
+       skb_queue_tail(&hci_vhci->readq, skb);
+
+       if (hci_vhci->flags & VHCI_FASYNC)
+               kill_fasync(&hci_vhci->fasync, SIGIO, POLL_IN);
+       wake_up_interruptible(&hci_vhci->read_wait);
+
+       return 0;
+}
+
+/* Character device part */
+
+/* Poll */
+static unsigned int hci_vhci_chr_poll(struct file *file, poll_table * wait)
+{  
+       struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
+
+       poll_wait(file, &hci_vhci->read_wait, wait);
+       if (skb_queue_len(&hci_vhci->readq))
+               return POLLIN | POLLRDNORM;
+
+       return POLLOUT | POLLWRNORM;
+}
+
+/* Get packet from user space buffer(already verified) */
+static inline ssize_t hci_vhci_get_user(struct hci_vhci_struct *hci_vhci, const char *buf, size_t count)
+{
+       struct sk_buff *skb;
+
+       if (count > HCI_MAX_FRAME_SIZE)
+               return -EINVAL;
+
+       if (!(skb = bluez_skb_alloc(count, GFP_KERNEL)))
+               return -ENOMEM;
+       
+       copy_from_user(skb_put(skb, count), buf, count); 
+
+       skb->dev = (void *) &hci_vhci->hdev;
+       skb->pkt_type = *((__u8 *) skb->data);
+       skb_pull(skb, 1);
+
+       hci_recv_frame(skb);
+
+       return count;
+} 
+
+/* Write */
+static ssize_t hci_vhci_chr_write(struct file * file, const char * buf, 
+                            size_t count, loff_t *pos)
+{
+       struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
+
+       if (verify_area(VERIFY_READ, buf, count))
+               return -EFAULT;
+
+       return hci_vhci_get_user(hci_vhci, buf, count);
+}
+
+/* Put packet to user space buffer(already verified) */
+static inline ssize_t hci_vhci_put_user(struct hci_vhci_struct *hci_vhci,
+                                      struct sk_buff *skb, char *buf, int count)
+{
+       int len = count, total = 0;
+       char *ptr = buf;
+
+       len = MIN(skb->len, len); 
+       copy_to_user(ptr, skb->data, len); 
+       total += len;
+
+       hci_vhci->hdev.stat.byte_tx += len;
+       switch (skb->pkt_type) {
+               case HCI_COMMAND_PKT:
+                       hci_vhci->hdev.stat.cmd_tx++;
+                       break;
+
+               case HCI_ACLDATA_PKT:
+                       hci_vhci->hdev.stat.acl_tx++;
+                       break;
+
+               case HCI_SCODATA_PKT:
+                       hci_vhci->hdev.stat.cmd_tx++;
+                       break;
+       };
+
+       return total;
+}
+
+/* Read */
+static ssize_t hci_vhci_chr_read(struct file * file, char * buf, size_t count, loff_t *pos)
+{
+       struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
+       DECLARE_WAITQUEUE(wait, current);
+       struct sk_buff *skb;
+       ssize_t ret = 0;
+
+       add_wait_queue(&hci_vhci->read_wait, &wait);
+       while (count) {
+               current->state = TASK_INTERRUPTIBLE;
+
+               /* Read frames from device queue */
+               if (!(skb = skb_dequeue(&hci_vhci->readq))) {
+                       if (file->f_flags & O_NONBLOCK) {
+                               ret = -EAGAIN;
+                               break;
+                       }
+                       if (signal_pending(current)) {
+                               ret = -ERESTARTSYS;
+                               break;
+                       }
+
+                       /* Nothing to read, let's sleep */
+                       schedule();
+                       continue;
+               }
+
+               if (!verify_area(VERIFY_WRITE, buf, count))
+                       ret = hci_vhci_put_user(hci_vhci, skb, buf, count);
+               else
+                       ret = -EFAULT;
+
+               kfree_skb(skb);
+               break;
+       }
+
+       current->state = TASK_RUNNING;
+       remove_wait_queue(&hci_vhci->read_wait, &wait);
+
+       return ret;
+}
+
+static loff_t hci_vhci_chr_lseek(struct file * file, loff_t offset, int origin)
+{
+       return -ESPIPE;
+}
+
+static int hci_vhci_chr_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+       return -EINVAL;
+}
+
+static int hci_vhci_chr_fasync(int fd, struct file *file, int on)
+{
+       struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
+       int ret;
+
+       if ((ret = fasync_helper(fd, file, on, &hci_vhci->fasync)) < 0)
+               return ret; 
+       if (on)
+               hci_vhci->flags |= VHCI_FASYNC;
+       else 
+               hci_vhci->flags &= ~VHCI_FASYNC;
+
+       return 0;
+}
+
+static int hci_vhci_chr_open(struct inode *inode, struct file * file)
+{
+       struct hci_vhci_struct *hci_vhci = NULL; 
+       struct hci_dev *hdev;
+
+       if (!(hci_vhci = kmalloc(sizeof(struct hci_vhci_struct), GFP_KERNEL)))
+               return -ENOMEM;
+
+       memset(hci_vhci, 0, sizeof(struct hci_vhci_struct));
+
+       skb_queue_head_init(&hci_vhci->readq);
+       init_waitqueue_head(&hci_vhci->read_wait);
+
+       /* Initialize and register HCI device */
+       hdev = &hci_vhci->hdev;
+
+       hdev->type = HCI_VHCI;
+       hdev->driver_data = hci_vhci;
+
+       hdev->open  = hci_vhci_open;
+       hdev->close = hci_vhci_close;
+       hdev->flush = hci_vhci_flush;
+       hdev->send  = hci_vhci_send_frame;
+
+       if (hci_register_dev(hdev) < 0) {
+               kfree(hci_vhci);
+               return -EBUSY;
+       }
+
+       file->private_data = hci_vhci;
+       return 0;   
+}
+
+static int hci_vhci_chr_close(struct inode *inode, struct file *file)
+{
+       struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
+
+       if (hci_unregister_dev(&hci_vhci->hdev) < 0) {
+               ERR("Can't unregister HCI device %s", hci_vhci->hdev.name);
+       }
+
+       kfree(hci_vhci);
+       file->private_data = NULL;
+
+       return 0;
+}
+
+static struct file_operations hci_vhci_fops = {
+       owner:  THIS_MODULE,    
+       llseek: hci_vhci_chr_lseek,
+       read:   hci_vhci_chr_read,
+       write:  hci_vhci_chr_write,
+       poll:   hci_vhci_chr_poll,
+       ioctl:  hci_vhci_chr_ioctl,
+       open:   hci_vhci_chr_open,
+       release:hci_vhci_chr_close,
+       fasync: hci_vhci_chr_fasync             
+};
+
+static struct miscdevice hci_vhci_miscdev=
+{
+        VHCI_MINOR,
+        "hci_vhci",
+        &hci_vhci_fops
+};
+
+int __init hci_vhci_init(void)
+{
+       INF("BlueZ VHCI driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",  
+               VERSION);
+       INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
+
+       if (misc_register(&hci_vhci_miscdev)) {
+               ERR("Can't register misc device %d\n", VHCI_MINOR);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+void hci_vhci_cleanup(void)
+{
+       misc_deregister(&hci_vhci_miscdev);
+}
+
+module_init(hci_vhci_init);
+module_exit(hci_vhci_cleanup);
+
+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
+MODULE_DESCRIPTION("BlueZ VHCI driver ver " VERSION);
+MODULE_LICENSE("GPL");
index b71f023aa699f7d55f601c84394837f9ec424090..702f687709b88e2120b1f4607a0a9d59c98e0db6 100644 (file)
 #include <linux/major.h>
 #include <linux/devfs_fs_kernel.h>
 
-#ifndef AZT_KERNEL_PRIOR_2_1
 #include <linux/init.h>
-#endif
 
 #include <asm/system.h>
 #include <asm/io.h>
 
-#ifdef AZT_KERNEL_PRIOR_2_1
-#include <asm/segment.h>
-#else
 #include <asm/uaccess.h>
 static int aztcd_blocksizes[1] = {2048};
-#endif
 
 
 /*###########################################################################
@@ -245,11 +239,6 @@ static int aztcd_blocksizes[1] = {2048};
 
 #define azt_port aztcd  /*needed for the modutils*/
 
-#ifndef AZT_KERNEL_PRIOR_2_1 
-#define  memcpy_fromfs copy_from_user
-#define  memcpy_tofs   copy_to_user
-#endif
-
 /*##########################################################################
   Type Definitions
   ##########################################################################
@@ -298,9 +287,7 @@ static volatile int azt_read_count = 1;
 
 static int azt_port = AZT_BASE_ADDR;
 
-#ifndef AZT_KERNEL_PRIOR_2_1
 MODULE_PARM(azt_port, "i");
-#endif
 
 static int azt_port_auto[16] = AZT_BASE_AUTO;
 
@@ -364,11 +351,7 @@ static void do_aztcd_request(request_queue_t *);
 static void azt_invalidate_buffers(void);
 int         aztcd_open(struct inode *ip, struct file *fp);
 
-#ifdef AZT_KERNEL_PRIOR_2_1
-static void aztcd_release(struct inode * inode, struct file * file);
-#else
 static int  aztcd_release(struct inode * inode, struct file * file);
-#endif
 
 int       aztcd_init(void);
 
@@ -1111,7 +1094,7 @@ static int check_aztcd_media_change(kdev_t full_dev)
  * Kernel IO-controls
 */
 static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
-{       int i, st;
+{       int i;
        struct azt_Toc qInfo;
        struct cdrom_ti ti;
        struct cdrom_tochdr tocHdr;
@@ -1175,9 +1158,8 @@ static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsi
 #ifdef AZT_DEBUG
                  printk("aztcd ioctl MULTISESSION\n");
 #endif
-                 st = verify_area(VERIFY_WRITE, (void*) arg, sizeof(struct cdrom_multisession));
-                 if (st) return st;
-                 memcpy_fromfs(&ms, (void*) arg, sizeof(struct cdrom_multisession));
+                 if(copy_from_user(&ms, (void*) arg, sizeof(struct cdrom_multisession)))
+                       return -EFAULT;
                  if (ms.addr_format == CDROM_MSF) 
                     { ms.addr.msf.minute = azt_bcd2bin(DiskInfo.lastSession.min);
                       ms.addr.msf.second = azt_bcd2bin(DiskInfo.lastSession.sec);
@@ -1188,7 +1170,8 @@ static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsi
                  else
                       return -EINVAL;
                  ms.xa_flag = DiskInfo.xa;
-                 memcpy_tofs((void*) arg, &ms, sizeof(struct cdrom_multisession));
+                 if(copy_to_user((void*) arg, &ms, sizeof(struct cdrom_multisession)))
+                       return -EFAULT;
 #ifdef AZT_DEBUG 
                  if (ms.addr_format == CDROM_MSF) 
                       printk("aztcd multisession xa:%d, msf:%02x:%02x.%02x [%02x:%02x.%02x])\n",
@@ -1203,9 +1186,8 @@ static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsi
                  return 0;
                }
        case CDROMPLAYTRKIND:     /* Play a track.  This currently ignores index. */
-               st = verify_area(VERIFY_READ, (void *) arg, sizeof ti);
-               if (st) return st;
-               memcpy_fromfs(&ti, (void *) arg, sizeof ti);
+               if(copy_from_user(&ti, (void *) arg, sizeof ti))
+                       return -EFAULT;
                if (ti.cdti_trk0 < DiskInfo.first
                        || ti.cdti_trk0 > DiskInfo.last
                        || ti.cdti_trk1 < ti.cdti_trk0)
@@ -1234,9 +1216,8 @@ printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
                  aztAudioStatus = CDROM_AUDIO_NO_STATUS;
                }
 */
-               st = verify_area(VERIFY_READ, (void *) arg, sizeof msf);
-               if (st) return st;
-               memcpy_fromfs(&msf, (void *) arg, sizeof msf);
+               if(copy_from_user(&msf, (void *) arg, sizeof msf))
+                       return -EFAULT;
                /* convert to bcd */
                azt_bin2bcd(&msf.cdmsf_min0);
                azt_bin2bcd(&msf.cdmsf_sec0);
@@ -1264,16 +1245,14 @@ azt_Play.end.min, azt_Play.end.sec, azt_Play.end.frame);
                break;
 
        case CDROMREADTOCHDR:        /* Read the table of contents header */
-               st = verify_area(VERIFY_WRITE, (void *) arg, sizeof tocHdr);
-               if (st) return st;
                tocHdr.cdth_trk0 = DiskInfo.first;
                tocHdr.cdth_trk1 = DiskInfo.last;
-               memcpy_tofs((void *) arg, &tocHdr, sizeof tocHdr);
+               if(copy_to_user((void *) arg, &tocHdr, sizeof tocHdr))
+                       return -EFAULT;
                break;
        case CDROMREADTOCENTRY:      /* Read an entry in the table of contents */
-               st = verify_area(VERIFY_WRITE, (void *) arg, sizeof entry);
-               if (st) return st;
-               memcpy_fromfs(&entry, (void *) arg, sizeof entry);
+               if(copy_from_user(&entry, (void *) arg, sizeof entry))
+                       return -EFAULT;
                if ((!aztTocUpToDate)||aztDiskChanged) aztUpdateToc();
                if (entry.cdte_track == CDROM_LEADOUT)
                  tocPtr = &Toc[DiskInfo.last + 1];
@@ -1295,19 +1274,13 @@ azt_Play.end.min, azt_Play.end.sec, azt_Play.end.frame);
                else
                { return -EINVAL;
                }
-               memcpy_tofs((void *) arg, &entry, sizeof entry);
+               if(copy_to_user((void *) arg, &entry, sizeof entry))
+                       return -EFAULT;
                break;
        case CDROMSUBCHNL:   /* Get subchannel info */
-               st = verify_area(VERIFY_WRITE, (void *) arg, sizeof(struct cdrom_subchnl));
-               if (st) { 
-#ifdef AZT_DEBUG
-                         printk("aztcd: exiting aztcd_ioctl - Error 1 - Command:%x\n",cmd);
-#endif
-                         return st;
-                       }  
-               memcpy_fromfs(&subchnl, (void *) arg, sizeof (struct cdrom_subchnl));
-               if (aztGetQChannelInfo(&qInfo) < 0)
-               if (st) { 
+               if(copy_from_user(&subchnl, (void *) arg, sizeof (struct cdrom_subchnl)))
+                       return -EFAULT;
+               if (aztGetQChannelInfo(&qInfo) < 0) {
 #ifdef AZT_DEBUG
                          printk("aztcd: exiting aztcd_ioctl - Error 3 - Command:%x\n",cmd);
 #endif
@@ -1331,15 +1304,15 @@ azt_Play.end.min, azt_Play.end.sec, azt_Play.end.frame);
                  subchnl.cdsc_reladdr.msf.second = azt_bcd2bin(qInfo.trackTime.sec);
                  subchnl.cdsc_reladdr.msf.frame  = azt_bcd2bin(qInfo.trackTime.frame);
                }
-               memcpy_tofs((void *) arg, &subchnl, sizeof (struct cdrom_subchnl));
+               if(copy_to_user((void *) arg, &subchnl, sizeof (struct cdrom_subchnl)))
+                       return -EFAULT;
                break;
        case CDROMVOLCTRL:   /* Volume control 
         * With my Aztech CD268-01A volume control does not work, I can only
           turn the channels on (any value !=0) or off (value==0). Maybe it
            works better with your drive */
-                st=verify_area(VERIFY_READ,(void *) arg, sizeof(volctrl));
-                if (st) return (st);
-                memcpy_fromfs(&volctrl,(char *) arg,sizeof(volctrl));
+                if(copy_from_user(&volctrl,(char *) arg,sizeof(volctrl)))
+                       return -EFAULT;
                azt_Play.start.min = 0x21;
                azt_Play.start.sec = 0x84;
                azt_Play.start.frame = volctrl.channel0;
@@ -1377,9 +1350,9 @@ azt_Play.end.min, azt_Play.end.sec, azt_Play.end.frame);
 #if AZT_PRIVATE_IOCTLS 
        case CDROMREADCOOKED: /*read data in mode 1 (2048 Bytes)*/
        case CDROMREADRAW:    /*read data in mode 2 (2336 Bytes)*/
-               { st = verify_area(VERIFY_WRITE, (void *) arg, sizeof buf);
-                 if (st) return st;
-                 memcpy_fromfs(&msf, (void *) arg, sizeof msf);
+               { 
+                 if(copy_from_user(&msf, (void *) arg, sizeof msf))
+                       return -EFAULT;
                  /* convert to bcd */
                  azt_bin2bcd(&msf.cdmsf_min0);
                  azt_bin2bcd(&msf.cdmsf_sec0);
@@ -1401,21 +1374,22 @@ azt_Play.end.min, azt_Play.end.sec, azt_Play.end.frame);
                       { if (sendAztCmd(ACMD_PLAY_READ_RAW, &azt_Play)) return -1;
                         DTEN_LOW;
                         insb(DATA_PORT,buf,CD_FRAMESIZE_RAW);
-                        memcpy_tofs((void *) arg, &buf, CD_FRAMESIZE_RAW);
+                        if(copy_to_user((void *) arg, &buf, CD_FRAMESIZE_RAW))
+                               return -EFAULT;
                       }  
                  }
                  else /*CDROMREADCOOKED*/
                  { if (sendAztCmd(ACMD_PLAY_READ, &azt_Play)) return -1;
                    DTEN_LOW;
                    insb(DATA_PORT,buf,CD_FRAMESIZE);
-                   memcpy_tofs((void *) arg, &buf, CD_FRAMESIZE);
+                   if(copy_to_user((void *) arg, &buf, CD_FRAMESIZE))
+                       return -EFAULT;
                  }
                 } 
                 break;
        case CDROMSEEK:    /*seek msf address*/
-               st = verify_area(VERIFY_READ,  (void *) arg, sizeof msf);
-               if (st) return st;
-               memcpy_fromfs(&msf, (void *) arg, sizeof msf);
+               if(copy_from_user(&msf, (void *) arg, sizeof msf))
+                       return -EFAULT;
                /* convert to bcd */
                azt_bin2bcd(&msf.cdmsf_min0);
                azt_bin2bcd(&msf.cdmsf_sec0);
@@ -1586,11 +1560,7 @@ err_out:
 /*
  * On close, we flush all azt blocks from the buffer cache.
  */
-#ifdef AZT_KERNEL_PRIOR_2_1
-static void aztcd_release(struct inode * inode, struct file * file)
-#else
 static int  aztcd_release(struct inode * inode, struct file * file)
-#endif
 { 
 #ifdef AZT_DEBUG
   printk("aztcd: executing aztcd_release\n");
@@ -1604,11 +1574,7 @@ static int  aztcd_release(struct inode * inode, struct file * file)
            aztSendCmd(ACMD_EJECT);
         CLEAR_TIMER;
   }
-#ifdef AZT_KERNEL_PRIOR_2_1
-  return;
-#else
   return 0;
-#endif
 }
 
 
@@ -1800,9 +1766,7 @@ int __init aztcd_init(void)
                 return -EIO;
        }
        blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
-#ifndef AZT_KERNEL_PRIOR_2_1
        blksize_size[MAJOR_NR] = aztcd_blocksizes;
-#endif
        read_ahead[MAJOR_NR] = 4;
        register_disk(NULL, MKDEV(MAJOR_NR,0), 1, &azt_fops, 0);
 
@@ -2284,3 +2248,6 @@ static void azt_bin2bcd(unsigned char *p)
 static int azt_bcd2bin(unsigned char bcd)
 {       return (bcd >> 4) * 10 + (bcd & 0xF);
 }
+
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
index 5f48b5099e78a85f8434dbe3b4a26d9df788e39d..fcece8741b5346f5080726fbd765c89b59041bb9 100644 (file)
 #define MAJOR_NR CDU31A_CDROM_MAJOR
 #include <linux/blk.h>
 
-#define CDU31A_READAHEAD 4  /* 128 sector, 64kB, 32 reads read-ahead */
+#define CDU31A_READAHEAD 4     /* 128 sector, 64kB, 32 reads read-ahead */
 #define CDU31A_MAX_CONSECUTIVE_ATTENTIONS 10
 
 #define DEBUG 0
 ** Default is polled and no DMA.  DMA is not recommended for double-speed
 ** drives.
 */
-static struct
-{
-   unsigned short base;         /* I/O Base Address */
-   short          int_num;      /* Interrupt Number (-1 means scan for it,
-                                   0 means don't use) */
-} cdu31a_addresses[] __initdata =
-{
-#if 0  /* No autoconfig any more. See Note at beginning
-          of this file. */
-   { 0x340,     0 },    /* Standard configuration Sony Interface */
-   { 0x1f88,    0 },    /* Fusion CD-16 */
-   { 0x230,     0 },    /* SoundBlaster 16 card */
-   { 0x360,     0 },    /* Secondary standard Sony Interface */
-   { 0x320,     0 },    /* Secondary standard Sony Interface */
-   { 0x330,     0 },    /* Secondary standard Sony Interface */
-   { 0x634,     0 },    /* Sound FX SC400 */
-   { 0x654,     0 },    /* Sound FX SC400 */
-#endif
-   { 0 }
+static struct {
+       unsigned short base;    /* I/O Base Address */
+       short int_num;          /* Interrupt Number (-1 means scan for it,
+                                  0 means don't use) */
+} cdu31a_addresses[] __initdata = {
+       {0}
 };
 
 static int handle_sony_cd_attention(void);
@@ -220,17 +207,16 @@ static int scd_spinup(void);
 /*static int scd_open(struct inode *inode, struct file *filp);*/
 static int scd_open(struct cdrom_device_info *, int);
 static void do_sony_cd_cmd(unsigned char cmd,
-                           unsigned char *params,
-                           unsigned int num_params,
-                           unsigned char *result_buffer,
-                           unsigned int *result_size);
-static void size_to_buf(unsigned int size,
-                        unsigned char *buf);
+                          unsigned char *params,
+                          unsigned int num_params,
+                          unsigned char *result_buffer,
+                          unsigned int *result_size);
+static void size_to_buf(unsigned int size, unsigned char *buf);
 
 /* Parameters for the read-ahead. */
-static unsigned int sony_next_block;      /* Next 512 byte block offset */
-static unsigned int sony_blocks_left = 0; /* Number of 512 byte blocks left
-                                             in the current read command. */
+static unsigned int sony_next_block;   /* Next 512 byte block offset */
+static unsigned int sony_blocks_left = 0;      /* Number of 512 byte blocks left
+                                                  in the current read command. */
 
 
 /* The base I/O address of the Sony Interface.  This is a variable (not a
@@ -252,48 +238,48 @@ static volatile unsigned short sony_cd_read_reg;
 static volatile unsigned short sony_cd_fifost_reg;
 
 
-static int sony_spun_up = 0;               /* Has the drive been spun up? */
+static int sony_spun_up = 0;   /* Has the drive been spun up? */
 
-static int sony_speed = 0;                 /* Last wanted speed */
+static int sony_speed = 0;     /* Last wanted speed */
 
-static int sony_xa_mode = 0;               /* Is an XA disk in the drive
-                                             and the drive a CDU31A? */
+static int sony_xa_mode = 0;   /* Is an XA disk in the drive
+                                  and the drive a CDU31A? */
 
-static int sony_raw_data_mode = 1;         /* 1 if data tracks, 0 if audio.
-                                              For raw data reads. */
+static int sony_raw_data_mode = 1;     /* 1 if data tracks, 0 if audio.
+                                          For raw data reads. */
 
-static unsigned int sony_usage = 0;        /* How many processes have the
-                                              drive open. */
+static unsigned int sony_usage = 0;    /* How many processes have the
+                                          drive open. */
 
-static int sony_pas_init = 0;             /* Initialize the Pro-Audio
-                                             Spectrum card? */
+static int sony_pas_init = 0;  /* Initialize the Pro-Audio
+                                  Spectrum card? */
 
-static struct s_sony_session_toc single_toc;  /* Holds the
-                                                table of
-                                                contents. */
+static struct s_sony_session_toc single_toc;   /* Holds the
+                                                  table of
+                                                  contents. */
 
-static struct s_all_sessions_toc sony_toc; /* entries gathered from all
-                                                sessions */
+static struct s_all_sessions_toc sony_toc;     /* entries gathered from all
+                                                  sessions */
 
-static int sony_toc_read = 0;             /* Has the TOC been read for
-                                             the drive? */
+static int sony_toc_read = 0;  /* Has the TOC been read for
+                                  the drive? */
 
-static struct s_sony_subcode last_sony_subcode; /* Points to the last
-                                                   subcode address read */
+static struct s_sony_subcode last_sony_subcode;        /* Points to the last
+                                                  subcode address read */
 
-static volatile int sony_inuse = 0;  /* Is the drive in use?  Only one operation
-                                       at a time allowed */
+static volatile int sony_inuse = 0;    /* Is the drive in use?  Only one operation
+                                          at a time allowed */
 
 static DECLARE_WAIT_QUEUE_HEAD(sony_wait);     /* Things waiting for the drive */
 
-static struct task_struct *has_cd_task = NULL;  /* The task that is currently
+static struct task_struct *has_cd_task = NULL; /* The task that is currently
                                                   using the CDROM drive, or
                                                   NULL if none. */
 
-static int is_double_speed = 0; /* does the drive support double speed ? */
-static int is_a_cdu31a = 1;     /* Is the drive a CDU31A? */
+static int is_double_speed = 0;        /* does the drive support double speed ? */
+static int is_a_cdu31a = 1;    /* Is the drive a CDU31A? */
 
-static int is_auto_eject = 1;   /* Door has been locked? 1=No/0=Yes */
+static int is_auto_eject = 1;  /* Door has been locked? 1=No/0=Yes */
 
 /*
  * The audio status uses the values from read subchannel data as specified
@@ -319,7 +305,7 @@ MODULE_PARM(cdu31a_irq, "i");
    interrupts. */
 DECLARE_WAIT_QUEUE_HEAD(cdu31a_irq_wait);
 
-static int curr_control_reg = 0; /* Current value of the control register */
+static int curr_control_reg = 0;       /* Current value of the control register */
 
 /* A disk changed variable.  When a disk change is detected, it will
    all be set to TRUE.  As the upper layers ask for disk_changed status
@@ -348,25 +334,23 @@ static int abort_read_started = 0;
  * This routine returns 1 if the disk has been changed since the last
  * check or 0 if it hasn't.
  */
-static int
-scd_disk_change(kdev_t full_dev)
+static int scd_disk_change(kdev_t full_dev)
 {
-   int retval;
+       int retval;
 
-   retval = disk_changed;
-   disk_changed = 0;
+       retval = disk_changed;
+       disk_changed = 0;
 
-   return retval;
+       return retval;
 }
 
 /*
  * Uniform cdrom interface function
  * report back, if disc has changed from time of last request.
  */
-static int
-scd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
+static int scd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
 {
-  return scd_disk_change(cdi->dev);
+       return scd_disk_change(cdi->dev);
 }
 
 /*
@@ -375,56 +359,51 @@ scd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
  */
 static int scd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
 {
-  if (CDSL_CURRENT != slot_nr) {
-     /* we have no changer support */
-     return -EINVAL;
-  }
-  if (scd_spinup() == 0) {
-         sony_spun_up = 1;
-  }
-  return sony_spun_up ? CDS_DISC_OK : CDS_DRIVE_NOT_READY;
+       if (CDSL_CURRENT != slot_nr) {
+               /* we have no changer support */
+               return -EINVAL;
+       }
+       if (scd_spinup() == 0) {
+               sony_spun_up = 1;
+       }
+       return sony_spun_up ? CDS_DISC_OK : CDS_DRIVE_NOT_READY;
 }
 
-static inline void
-enable_interrupts(void)
+static inline void enable_interrupts(void)
 {
-   curr_control_reg |= (  SONY_ATTN_INT_EN_BIT
-                        | SONY_RES_RDY_INT_EN_BIT
-                        | SONY_DATA_RDY_INT_EN_BIT);
-   outb(curr_control_reg, sony_cd_control_reg);
+       curr_control_reg |= (SONY_ATTN_INT_EN_BIT
+                            | SONY_RES_RDY_INT_EN_BIT
+                            | SONY_DATA_RDY_INT_EN_BIT);
+       outb(curr_control_reg, sony_cd_control_reg);
 }
 
-static inline void
-disable_interrupts(void)
+static inline void disable_interrupts(void)
 {
-   curr_control_reg &= ~(  SONY_ATTN_INT_EN_BIT
-                         | SONY_RES_RDY_INT_EN_BIT
-                         | SONY_DATA_RDY_INT_EN_BIT);
-   outb(curr_control_reg, sony_cd_control_reg);
+       curr_control_reg &= ~(SONY_ATTN_INT_EN_BIT
+                             | SONY_RES_RDY_INT_EN_BIT
+                             | SONY_DATA_RDY_INT_EN_BIT);
+       outb(curr_control_reg, sony_cd_control_reg);
 }
 
 /*
  * Wait a little while (used for polling the drive).  If in initialization,
  * setting a timeout doesn't work, so just loop for a while.
  */
-static inline void
-sony_sleep(void)
+static inline void sony_sleep(void)
 {
-   unsigned long flags;
+       unsigned long flags;
+
+       if (cdu31a_irq <= 0) {
+               current->state = TASK_INTERRUPTIBLE;
+               schedule_timeout(0);
+       } else {                /* Interrupt driven */
 
-   if (cdu31a_irq <= 0)
-   {
-      current->state = TASK_INTERRUPTIBLE;
-      schedule_timeout(0);
-   }
-   else /* Interrupt driven */
-   {
-      save_flags(flags);
-      cli();
-      enable_interrupts();
-      interruptible_sleep_on(&cdu31a_irq_wait);
-      restore_flags(flags);
-   }
+               save_flags(flags);
+               cli();
+               enable_interrupts();
+               interruptible_sleep_on(&cdu31a_irq_wait);
+               restore_flags(flags);
+       }
 }
 
 
@@ -432,272 +411,276 @@ sony_sleep(void)
  * The following are convenience routine to read various status and set
  * various conditions in the drive.
  */
-static inline int
-is_attention(void)
+static inline int is_attention(void)
 {
-   return((inb(sony_cd_status_reg) & SONY_ATTN_BIT) != 0);
+       return ((inb(sony_cd_status_reg) & SONY_ATTN_BIT) != 0);
 }
 
-static inline int
-is_busy(void)
+static inline int is_busy(void)
 {
-   return((inb(sony_cd_status_reg) & SONY_BUSY_BIT) != 0);
+       return ((inb(sony_cd_status_reg) & SONY_BUSY_BIT) != 0);
 }
 
-static inline int
-is_data_ready(void)
+static inline int is_data_ready(void)
 {
-   return((inb(sony_cd_status_reg) & SONY_DATA_RDY_BIT) != 0);
+       return ((inb(sony_cd_status_reg) & SONY_DATA_RDY_BIT) != 0);
 }
 
-static inline int
-is_data_requested(void)
+static inline int is_data_requested(void)
 {
-   return((inb(sony_cd_status_reg) & SONY_DATA_REQUEST_BIT) != 0);
+       return ((inb(sony_cd_status_reg) & SONY_DATA_REQUEST_BIT) != 0);
 }
 
-static inline int
-is_result_ready(void)
+static inline int is_result_ready(void)
 {
-   return((inb(sony_cd_status_reg) & SONY_RES_RDY_BIT) != 0);
+       return ((inb(sony_cd_status_reg) & SONY_RES_RDY_BIT) != 0);
 }
 
-static inline int
-is_param_write_rdy(void)
+static inline int is_param_write_rdy(void)
 {
-   return((inb(sony_cd_fifost_reg) & SONY_PARAM_WRITE_RDY_BIT) != 0);
+       return ((inb(sony_cd_fifost_reg) & SONY_PARAM_WRITE_RDY_BIT) != 0);
 }
 
-static inline int
-is_result_reg_not_empty(void)
+static inline int is_result_reg_not_empty(void)
 {
-   return((inb(sony_cd_fifost_reg) & SONY_RES_REG_NOT_EMP_BIT) != 0);
+       return ((inb(sony_cd_fifost_reg) & SONY_RES_REG_NOT_EMP_BIT) != 0);
 }
 
-static inline void
-reset_drive(void)
+static inline void reset_drive(void)
 {
-   curr_control_reg = 0;
-   readahead_dataleft = 0;
-   sony_toc_read = 0;
-   outb(SONY_DRIVE_RESET_BIT, sony_cd_control_reg);
+       curr_control_reg = 0;
+       readahead_dataleft = 0;
+       sony_toc_read = 0;
+       outb(SONY_DRIVE_RESET_BIT, sony_cd_control_reg);
 }
 
 /*
  * Uniform cdrom interface function
  * reset drive and return when it is ready
  */
-static int scd_reset(struct cdrom_device_info * cdi)
+static int scd_reset(struct cdrom_device_info *cdi)
 {
-  int retry_count;
+       int retry_count;
 
-  reset_drive();
+       reset_drive();
 
-  retry_count = jiffies + SONY_RESET_TIMEOUT;
-  while (time_before(jiffies, retry_count) && (!is_attention()))
-  {
-     sony_sleep();
-  }
+       retry_count = jiffies + SONY_RESET_TIMEOUT;
+       while (time_before(jiffies, retry_count) && (!is_attention())) {
+               sony_sleep();
+       }
 
-  return 0;
+       return 0;
 }
 
-static inline void
-clear_attention(void)
+static inline void clear_attention(void)
 {
-   outb(curr_control_reg | SONY_ATTN_CLR_BIT, sony_cd_control_reg);
+       outb(curr_control_reg | SONY_ATTN_CLR_BIT, sony_cd_control_reg);
 }
 
-static inline void
-clear_result_ready(void)
+static inline void clear_result_ready(void)
 {
-   outb(curr_control_reg | SONY_RES_RDY_CLR_BIT, sony_cd_control_reg);
+       outb(curr_control_reg | SONY_RES_RDY_CLR_BIT, sony_cd_control_reg);
 }
 
-static inline void
-clear_data_ready(void)
+static inline void clear_data_ready(void)
 {
-   outb(curr_control_reg | SONY_DATA_RDY_CLR_BIT, sony_cd_control_reg);
+       outb(curr_control_reg | SONY_DATA_RDY_CLR_BIT,
+            sony_cd_control_reg);
 }
 
-static inline void
-clear_param_reg(void)
+static inline void clear_param_reg(void)
 {
-   outb(curr_control_reg | SONY_PARAM_CLR_BIT, sony_cd_control_reg);
+       outb(curr_control_reg | SONY_PARAM_CLR_BIT, sony_cd_control_reg);
 }
 
-static inline unsigned char
-read_status_register(void)
+static inline unsigned char read_status_register(void)
 {
-   return(inb(sony_cd_status_reg));
+       return (inb(sony_cd_status_reg));
 }
 
-static inline unsigned char
-read_result_register(void)
+static inline unsigned char read_result_register(void)
 {
-   return(inb(sony_cd_result_reg));
+       return (inb(sony_cd_result_reg));
 }
 
-static inline unsigned char
-read_data_register(void)
+static inline unsigned char read_data_register(void)
 {
-   return(inb(sony_cd_read_reg));
+       return (inb(sony_cd_read_reg));
 }
 
-static inline void
-write_param(unsigned char param)
+static inline void write_param(unsigned char param)
 {
-   outb(param, sony_cd_param_reg);
+       outb(param, sony_cd_param_reg);
 }
 
-static inline void
-write_cmd(unsigned char cmd)
+static inline void write_cmd(unsigned char cmd)
 {
-   outb(curr_control_reg | SONY_RES_RDY_INT_EN_BIT, sony_cd_control_reg);
-   outb(cmd, sony_cd_cmd_reg);
+       outb(curr_control_reg | SONY_RES_RDY_INT_EN_BIT,
+            sony_cd_control_reg);
+       outb(cmd, sony_cd_cmd_reg);
 }
 
-static void
-cdu31a_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-   unsigned char val;
-
-   if (abort_read_started)
-   {
-      /* We might be waiting for an abort to finish.  Don't
-         disable interrupts yet, though, because we handle
-         this one here. */
-      /* Clear out the result registers. */
-      while (is_result_reg_not_empty())
-      {
-         val = read_result_register();
-      }
-      clear_data_ready();
-      clear_result_ready();
-
-      /* Clear out the data */
-      while (is_data_requested())
-      {
-         val = read_data_register();
-      }
-      abort_read_started = 0;
-
-      /* If something was waiting, wake it up now. */
-      if (waitqueue_active(&cdu31a_irq_wait))
-      {
-         disable_interrupts();
-         wake_up(&cdu31a_irq_wait);
-      }
-   }
-   else if (waitqueue_active(&cdu31a_irq_wait))
-   {
-      disable_interrupts();
-      wake_up(&cdu31a_irq_wait);
-   }
-   else
-   {
-      disable_interrupts();
-      printk("CDU31A: Got an interrupt but nothing was waiting\n");
-   }
+static void cdu31a_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+       unsigned char val;
+
+       if (abort_read_started) {
+               /* We might be waiting for an abort to finish.  Don't
+                  disable interrupts yet, though, because we handle
+                  this one here. */
+               /* Clear out the result registers. */
+               while (is_result_reg_not_empty()) {
+                       val = read_result_register();
+               }
+               clear_data_ready();
+               clear_result_ready();
+
+               /* Clear out the data */
+               while (is_data_requested()) {
+                       val = read_data_register();
+               }
+               abort_read_started = 0;
+
+               /* If something was waiting, wake it up now. */
+               if (waitqueue_active(&cdu31a_irq_wait)) {
+                       disable_interrupts();
+                       wake_up(&cdu31a_irq_wait);
+               }
+       } else if (waitqueue_active(&cdu31a_irq_wait)) {
+               disable_interrupts();
+               wake_up(&cdu31a_irq_wait);
+       } else {
+               disable_interrupts();
+               printk
+                   ("CDU31A: Got an interrupt but nothing was waiting\n");
+       }
 }
 
 /*
  * give more verbose error messages
  */
-static unsigned char *translate_error( unsigned char err_code )
-{
-   static unsigned char errbuf[80];
-
-   switch (err_code) {
-     case 0x10: return "illegal command ";
-     case 0x11: return "illegal parameter ";
-
-     case 0x20: return "not loaded ";
-     case 0x21: return "no disc ";
-     case 0x22: return "not spinning ";
-     case 0x23: return "spinning ";
-     case 0x25: return "spindle servo ";
-     case 0x26: return "focus servo ";
-     case 0x29: return "eject mechanism ";
-     case 0x2a: return "audio playing ";
-     case 0x2c: return "emergency eject ";
-
-     case 0x30: return "focus ";
-     case 0x31: return "frame sync ";
-     case 0x32: return "subcode address ";
-     case 0x33: return "block sync ";
-     case 0x34: return "header address ";
-
-     case 0x40: return "illegal track read ";
-     case 0x41: return "mode 0 read ";
-     case 0x42: return "illegal mode read ";
-     case 0x43: return "illegal block size read ";
-     case 0x44: return "mode read ";
-     case 0x45: return "form read ";
-     case 0x46: return "leadout read ";
-     case 0x47: return "buffer overrun ";
-
-     case 0x53: return "unrecoverable CIRC ";
-     case 0x57: return "unrecoverable LECC ";
-
-     case 0x60: return "no TOC ";
-     case 0x61: return "invalid subcode data ";
-     case 0x63: return "focus on TOC read ";
-     case 0x64: return "frame sync on TOC read ";
-     case 0x65: return "TOC data ";
-
-     case 0x70: return "hardware failure ";
-     case 0x91: return "leadin ";
-     case 0x92: return "leadout ";
-     case 0x93: return "data track ";
-   }
-   sprintf(errbuf, "unknown 0x%02x ", err_code);
-   return errbuf;
+static unsigned char *translate_error(unsigned char err_code)
+{
+       static unsigned char errbuf[80];
+
+       switch (err_code) {
+       case 0x10:
+               return "illegal command ";
+       case 0x11:
+               return "illegal parameter ";
+
+       case 0x20:
+               return "not loaded ";
+       case 0x21:
+               return "no disc ";
+       case 0x22:
+               return "not spinning ";
+       case 0x23:
+               return "spinning ";
+       case 0x25:
+               return "spindle servo ";
+       case 0x26:
+               return "focus servo ";
+       case 0x29:
+               return "eject mechanism ";
+       case 0x2a:
+               return "audio playing ";
+       case 0x2c:
+               return "emergency eject ";
+
+       case 0x30:
+               return "focus ";
+       case 0x31:
+               return "frame sync ";
+       case 0x32:
+               return "subcode address ";
+       case 0x33:
+               return "block sync ";
+       case 0x34:
+               return "header address ";
+
+       case 0x40:
+               return "illegal track read ";
+       case 0x41:
+               return "mode 0 read ";
+       case 0x42:
+               return "illegal mode read ";
+       case 0x43:
+               return "illegal block size read ";
+       case 0x44:
+               return "mode read ";
+       case 0x45:
+               return "form read ";
+       case 0x46:
+               return "leadout read ";
+       case 0x47:
+               return "buffer overrun ";
+
+       case 0x53:
+               return "unrecoverable CIRC ";
+       case 0x57:
+               return "unrecoverable LECC ";
+
+       case 0x60:
+               return "no TOC ";
+       case 0x61:
+               return "invalid subcode data ";
+       case 0x63:
+               return "focus on TOC read ";
+       case 0x64:
+               return "frame sync on TOC read ";
+       case 0x65:
+               return "TOC data ";
+
+       case 0x70:
+               return "hardware failure ";
+       case 0x91:
+               return "leadin ";
+       case 0x92:
+               return "leadout ";
+       case 0x93:
+               return "data track ";
+       }
+       sprintf(errbuf, "unknown 0x%02x ", err_code);
+       return errbuf;
 }
 
 /*
  * Set the drive parameters so the drive will auto-spin-up when a
  * disk is inserted.
  */
-static void
-set_drive_params(int want_doublespeed)
-{
-   unsigned char res_reg[12];
-   unsigned int res_size;
-   unsigned char params[3];
-
-
-   params[0] = SONY_SD_AUTO_SPIN_DOWN_TIME;
-   params[1] = 0x00; /* Never spin down the drive. */
-   do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                  params,
-                  2,
-                  res_reg,
-                  &res_size);
-   if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
-   {
-      printk("  Unable to set spin-down time: 0x%2.2x\n", res_reg[1]);
-   }
-
-   params[0] = SONY_SD_MECH_CONTROL;
-   params[1] = SONY_AUTO_SPIN_UP_BIT; /* Set auto spin up */
-
-   if (is_auto_eject) params[1] |= SONY_AUTO_EJECT_BIT;
-   
-   if (is_double_speed && want_doublespeed)
-   {
-      params[1] |= SONY_DOUBLE_SPEED_BIT; /* Set the drive to double speed if 
-                                             possible */
-   }
-   do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                  params,
-                  2,
-                  res_reg,
-                  &res_size);
-   if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
-   {
-      printk("  Unable to set mechanical parameters: 0x%2.2x\n", res_reg[1]);
-   }
+static void set_drive_params(int want_doublespeed)
+{
+       unsigned char res_reg[12];
+       unsigned int res_size;
+       unsigned char params[3];
+
+
+       params[0] = SONY_SD_AUTO_SPIN_DOWN_TIME;
+       params[1] = 0x00;       /* Never spin down the drive. */
+       do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
+                      params, 2, res_reg, &res_size);
+       if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
+               printk("  Unable to set spin-down time: 0x%2.2x\n",
+                      res_reg[1]);
+       }
+
+       params[0] = SONY_SD_MECH_CONTROL;
+       params[1] = SONY_AUTO_SPIN_UP_BIT;      /* Set auto spin up */
+
+       if (is_auto_eject)
+               params[1] |= SONY_AUTO_EJECT_BIT;
+
+       if (is_double_speed && want_doublespeed) {
+               params[1] |= SONY_DOUBLE_SPEED_BIT;     /* Set the drive to double speed if 
+                                                          possible */
+       }
+       do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
+                      params, 2, res_reg, &res_size);
+       if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
+               printk("  Unable to set mechanical parameters: 0x%2.2x\n",
+                      res_reg[1]);
+       }
 }
 
 /*
@@ -706,13 +689,13 @@ set_drive_params(int want_doublespeed)
  */
 static int scd_select_speed(struct cdrom_device_info *cdi, int speed)
 {
-  if (speed == 0)
-    sony_speed = 1;
-  else 
-    sony_speed = speed - 1;
+       if (speed == 0)
+               sony_speed = 1;
+       else
+               sony_speed = speed - 1;
 
-  set_drive_params(sony_speed);
-  return 0;
+       set_drive_params(sony_speed);
+       return 0;
 }
 
 /*
@@ -721,77 +704,69 @@ static int scd_select_speed(struct cdrom_device_info *cdi, int speed)
  */
 static int scd_lock_door(struct cdrom_device_info *cdi, int lock)
 {
-   if (lock == 0 && sony_usage == 1)
-   {
-      /* Unlock the door, only if nobody is using the drive */
-      is_auto_eject = 1;
-   } else {
-      is_auto_eject = 0;
-   }
-   set_drive_params(sony_speed);
-   return 0;
+       if (lock == 0 && sony_usage == 1) {
+               /* Unlock the door, only if nobody is using the drive */
+               is_auto_eject = 1;
+       } else {
+               is_auto_eject = 0;
+       }
+       set_drive_params(sony_speed);
+       return 0;
 }
 
 /*
  * This code will reset the drive and attempt to restore sane parameters.
  */
-static void
-restart_on_error(void)
-{
-   unsigned char res_reg[12];
-   unsigned int res_size;
-   unsigned int retry_count;
-
-
-   printk("cdu31a: Resetting drive on error\n");
-   reset_drive();
-   retry_count = jiffies + SONY_RESET_TIMEOUT;
-   while (time_before(jiffies, retry_count) && (!is_attention()))
-   {
-      sony_sleep();
-   }
-   set_drive_params(sony_speed);
-   do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-   if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
-   {
-      printk("cdu31a: Unable to spin up drive: 0x%2.2x\n", res_reg[1]);
-   }
-
-   current->state = TASK_INTERRUPTIBLE;
-   schedule_timeout(2*HZ);
-
-   sony_get_toc();
+static void restart_on_error(void)
+{
+       unsigned char res_reg[12];
+       unsigned int res_size;
+       unsigned int retry_count;
+
+
+       printk("cdu31a: Resetting drive on error\n");
+       reset_drive();
+       retry_count = jiffies + SONY_RESET_TIMEOUT;
+       while (time_before(jiffies, retry_count) && (!is_attention())) {
+               sony_sleep();
+       }
+       set_drive_params(sony_speed);
+       do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
+       if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
+               printk("cdu31a: Unable to spin up drive: 0x%2.2x\n",
+                      res_reg[1]);
+       }
+
+       current->state = TASK_INTERRUPTIBLE;
+       schedule_timeout(2 * HZ);
+
+       sony_get_toc();
 }
 
 /*
  * This routine writes data to the parameter register.  Since this should
  * happen fairly fast, it is polled with no OS waits between.
  */
-static int
-write_params(unsigned char *params,
-             int num_params)
+static int write_params(unsigned char *params, int num_params)
 {
-   unsigned int retry_count;
+       unsigned int retry_count;
 
 
-   retry_count = SONY_READY_RETRIES;
-   while ((retry_count > 0) && (!is_param_write_rdy()))
-   {
-      retry_count--;
-   }
-   if (!is_param_write_rdy())
-   {
-      return -EIO;
-   }
+       retry_count = SONY_READY_RETRIES;
+       while ((retry_count > 0) && (!is_param_write_rdy())) {
+               retry_count--;
+       }
+       if (!is_param_write_rdy()) {
+               return -EIO;
+       }
 
-   while (num_params > 0)
-   {
-      write_param(*params);
-      params++;
-      num_params--;
-   }
+       while (num_params > 0) {
+               write_param(*params);
+               params++;
+               num_params--;
+       }
 
-   return 0;
+       return 0;
 }
 
 
@@ -802,134 +777,125 @@ write_params(unsigned char *params,
  * the drive manual.
  */
 static void
-get_result(unsigned char *result_buffer,
-           unsigned int *result_size)
-{
-   unsigned char a, b;
-   int i;
-   unsigned int retry_count;
-
-
-   while (handle_sony_cd_attention())
-      ;
-   /* Wait for the result data to be ready */
-   retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-   while (time_before(jiffies, retry_count) && (is_busy() || (!(is_result_ready()))))
-   {
-      sony_sleep();
-
-      while (handle_sony_cd_attention())
-         ;
-   }
-   if (is_busy() || (!(is_result_ready())))
-   {
+get_result(unsigned char *result_buffer, unsigned int *result_size)
+{
+       unsigned char a, b;
+       int i;
+       unsigned int retry_count;
+
+
+       while (handle_sony_cd_attention());
+       /* Wait for the result data to be ready */
+       retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
+       while (time_before(jiffies, retry_count)
+              && (is_busy() || (!(is_result_ready())))) {
+               sony_sleep();
+
+               while (handle_sony_cd_attention());
+       }
+       if (is_busy() || (!(is_result_ready()))) {
 #if DEBUG
-      printk("CDU31A timeout out %d\n", __LINE__);
+               printk("CDU31A timeout out %d\n", __LINE__);
 #endif
-      result_buffer[0] = 0x20;
-      result_buffer[1] = SONY_TIMEOUT_OP_ERR;
-      *result_size = 2;
-      return;
-   }
-
-   /*
-    * Get the first two bytes.  This determines what else needs
-    * to be done.
-    */
-   clear_result_ready();
-   a = read_result_register();
-   *result_buffer = a;
-   result_buffer++;
-
-   /* Check for block error status result. */
-   if ((a & 0xf0) == 0x50)
-   {
-      *result_size = 1;
-      return;
-   }
-
-   b = read_result_register();
-   *result_buffer = b;
-   result_buffer++;
-   *result_size = 2;
-
-   /*
-    * 0x20 means an error occurred.  Byte 2 will have the error code.
-    * Otherwise, the command succeeded, byte 2 will have the count of
-    * how many more status bytes are coming.
-    *
-    * The result register can be read 10 bytes at a time, a wait for
-    * result ready to be asserted must be done between every 10 bytes.
-    */
-   if ((a & 0xf0) != 0x20)
-   {
-      if (b > 8)
-      {
-         for (i=0; i<8; i++)
-         {
-            *result_buffer = read_result_register();
-            result_buffer++;
-            (*result_size)++;
-         }
-         b = b - 8;
-
-         while (b > 10)
-         {
-            retry_count = SONY_READY_RETRIES;
-            while ((retry_count > 0) && (!is_result_ready()))
-            {
-               retry_count--;
-            }
-            if (!is_result_ready())
-            {
+               result_buffer[0] = 0x20;
+               result_buffer[1] = SONY_TIMEOUT_OP_ERR;
+               *result_size = 2;
+               return;
+       }
+
+       /*
+        * Get the first two bytes.  This determines what else needs
+        * to be done.
+        */
+       clear_result_ready();
+       a = read_result_register();
+       *result_buffer = a;
+       result_buffer++;
+
+       /* Check for block error status result. */
+       if ((a & 0xf0) == 0x50) {
+               *result_size = 1;
+               return;
+       }
+
+       b = read_result_register();
+       *result_buffer = b;
+       result_buffer++;
+       *result_size = 2;
+
+       /*
+        * 0x20 means an error occurred.  Byte 2 will have the error code.
+        * Otherwise, the command succeeded, byte 2 will have the count of
+        * how many more status bytes are coming.
+        *
+        * The result register can be read 10 bytes at a time, a wait for
+        * result ready to be asserted must be done between every 10 bytes.
+        */
+       if ((a & 0xf0) != 0x20) {
+               if (b > 8) {
+                       for (i = 0; i < 8; i++) {
+                               *result_buffer = read_result_register();
+                               result_buffer++;
+                               (*result_size)++;
+                       }
+                       b = b - 8;
+
+                       while (b > 10) {
+                               retry_count = SONY_READY_RETRIES;
+                               while ((retry_count > 0)
+                                      && (!is_result_ready())) {
+                                       retry_count--;
+                               }
+                               if (!is_result_ready()) {
 #if DEBUG
-               printk("CDU31A timeout out %d\n", __LINE__);
+                                       printk("CDU31A timeout out %d\n",
+                                              __LINE__);
 #endif
-               result_buffer[0] = 0x20;
-               result_buffer[1] = SONY_TIMEOUT_OP_ERR;
-               *result_size = 2;
-               return;
-            }
-
-            clear_result_ready();
-                                
-            for (i=0; i<10; i++)
-            {
-               *result_buffer = read_result_register();
-               result_buffer++;
-               (*result_size)++;
-            }
-            b = b - 10;
-         }
-
-         if (b > 0)
-         {
-            retry_count = SONY_READY_RETRIES;
-            while ((retry_count > 0) && (!is_result_ready()))
-            {
-               retry_count--;
-            }
-            if (!is_result_ready())
-            {
+                                       result_buffer[0] = 0x20;
+                                       result_buffer[1] =
+                                           SONY_TIMEOUT_OP_ERR;
+                                       *result_size = 2;
+                                       return;
+                               }
+
+                               clear_result_ready();
+
+                               for (i = 0; i < 10; i++) {
+                                       *result_buffer =
+                                           read_result_register();
+                                       result_buffer++;
+                                       (*result_size)++;
+                               }
+                               b = b - 10;
+                       }
+
+                       if (b > 0) {
+                               retry_count = SONY_READY_RETRIES;
+                               while ((retry_count > 0)
+                                      && (!is_result_ready())) {
+                                       retry_count--;
+                               }
+                               if (!is_result_ready()) {
 #if DEBUG
-               printk("CDU31A timeout out %d\n", __LINE__);
+                                       printk("CDU31A timeout out %d\n",
+                                              __LINE__);
 #endif
-               result_buffer[0] = 0x20;
-               result_buffer[1] = SONY_TIMEOUT_OP_ERR;
-               *result_size = 2;
-               return;
-            }
-         }
-      }
-
-      while (b > 0)
-      {
-         *result_buffer = read_result_register();
-         result_buffer++;
-         (*result_size)++;
-         b--;
-      }
-   }
+                                       result_buffer[0] = 0x20;
+                                       result_buffer[1] =
+                                           SONY_TIMEOUT_OP_ERR;
+                                       *result_size = 2;
+                                       return;
+                               }
+                       }
+               }
+
+               while (b > 0) {
+                       *result_buffer = read_result_register();
+                       result_buffer++;
+                       (*result_size)++;
+                       b--;
+               }
+       }
 }
 
 /*
@@ -939,95 +905,81 @@ get_result(unsigned char *result_buffer,
  */
 static void
 do_sony_cd_cmd(unsigned char cmd,
-               unsigned char *params,
-               unsigned int num_params,
-               unsigned char *result_buffer,
-               unsigned int *result_size)
-{
-   unsigned int retry_count;
-   int num_retries;
-   int recursive_call;
-   unsigned long flags;
-
-
-   save_flags(flags);
-   cli();
-   if (current != has_cd_task) /* Allow recursive calls to this routine */
-   {
-      while (sony_inuse)
-      {
-         interruptible_sleep_on(&sony_wait);
-         if (signal_pending(current))
-         {
-            result_buffer[0] = 0x20;
-            result_buffer[1] = SONY_SIGNAL_OP_ERR;
-            *result_size = 2;
-            restore_flags(flags);
-            return;
-         }
-      }
-      sony_inuse = 1;
-      has_cd_task = current;
-      recursive_call = 0;
-   }
-   else
-   {
-      recursive_call = 1;
-   }
-
-   num_retries = 0;
+              unsigned char *params,
+              unsigned int num_params,
+              unsigned char *result_buffer, unsigned int *result_size)
+{
+       unsigned int retry_count;
+       int num_retries;
+       int recursive_call;
+       unsigned long flags;
+
+
+       save_flags(flags);
+       cli();
+       if (current != has_cd_task) {   /* Allow recursive calls to this routine */
+               while (sony_inuse) {
+                       interruptible_sleep_on(&sony_wait);
+                       if (signal_pending(current)) {
+                               result_buffer[0] = 0x20;
+                               result_buffer[1] = SONY_SIGNAL_OP_ERR;
+                               *result_size = 2;
+                               restore_flags(flags);
+                               return;
+                       }
+               }
+               sony_inuse = 1;
+               has_cd_task = current;
+               recursive_call = 0;
+       } else {
+               recursive_call = 1;
+       }
+
+       num_retries = 0;
 retry_cd_operation:
 
-   while (handle_sony_cd_attention())
-      ;
-
-   sti();
-   
-   retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-   while (time_before(jiffies, retry_count) && (is_busy()))
-   {
-      sony_sleep();
-      
-      while (handle_sony_cd_attention())
-         ;
-   }
-   if (is_busy())
-   {
-#if DEBUG
-      printk("CDU31A timeout out %d\n", __LINE__);
-#endif
-      result_buffer[0] = 0x20;
-      result_buffer[1] = SONY_TIMEOUT_OP_ERR;
-      *result_size = 2;
-   }
-   else
-   {
-      clear_result_ready();
-      clear_param_reg();
-
-      write_params(params, num_params);
-      write_cmd(cmd);
+       while (handle_sony_cd_attention());
 
-      get_result(result_buffer, result_size);
-   }
+       sti();
 
-   if (   ((result_buffer[0] & 0xf0) == 0x20)
-       && (num_retries < MAX_CDU31A_RETRIES))
-   {
-      num_retries++;
-      current->state = TASK_INTERRUPTIBLE;
-      schedule_timeout(HZ/10);  /* Wait .1 seconds on retries */
-      goto retry_cd_operation;
-   }
+       retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
+       while (time_before(jiffies, retry_count) && (is_busy())) {
+               sony_sleep();
 
-   if (!recursive_call)
-   {
-      has_cd_task = NULL;
-      sony_inuse = 0;
-      wake_up_interruptible(&sony_wait);
-   }
-
-   restore_flags(flags);
+               while (handle_sony_cd_attention());
+       }
+       if (is_busy()) {
+#if DEBUG
+               printk("CDU31A timeout out %d\n", __LINE__);
+#endif
+               result_buffer[0] = 0x20;
+               result_buffer[1] = SONY_TIMEOUT_OP_ERR;
+               *result_size = 2;
+       } else {
+               clear_result_ready();
+               clear_param_reg();
+
+               write_params(params, num_params);
+               write_cmd(cmd);
+
+               get_result(result_buffer, result_size);
+       }
+
+       if (((result_buffer[0] & 0xf0) == 0x20)
+           && (num_retries < MAX_CDU31A_RETRIES)) {
+               num_retries++;
+               current->state = TASK_INTERRUPTIBLE;
+               schedule_timeout(HZ / 10);      /* Wait .1 seconds on retries */
+               goto retry_cd_operation;
+       }
+
+       if (!recursive_call) {
+               has_cd_task = NULL;
+               sony_inuse = 0;
+               wake_up_interruptible(&sony_wait);
+       }
+
+       restore_flags(flags);
 }
 
 
@@ -1040,120 +992,114 @@ retry_cd_operation:
  * a 0), and returns a 0 if it happens too many times.  This will help
  * prevent a lockup.
  */
-static int
-handle_sony_cd_attention(void)
+static int handle_sony_cd_attention(void)
 {
-   unsigned char atten_code;
-   static int num_consecutive_attentions = 0;
-   volatile int val;
+       unsigned char atten_code;
+       static int num_consecutive_attentions = 0;
+       volatile int val;
 
 
 #if 0*DEBUG
-   printk("Entering handle_sony_cd_attention\n");
+       printk("Entering handle_sony_cd_attention\n");
 #endif
-   if (is_attention())
-   {
-      if (num_consecutive_attentions > CDU31A_MAX_CONSECUTIVE_ATTENTIONS)
-      {
-         printk("cdu31a: Too many consecutive attentions: %d\n",
-                num_consecutive_attentions);
-         num_consecutive_attentions = 0;
+       if (is_attention()) {
+               if (num_consecutive_attentions >
+                   CDU31A_MAX_CONSECUTIVE_ATTENTIONS) {
+                       printk
+                           ("cdu31a: Too many consecutive attentions: %d\n",
+                            num_consecutive_attentions);
+                       num_consecutive_attentions = 0;
 #if DEBUG
-         printk("Leaving handle_sony_cd_attention at %d\n", __LINE__);
+                       printk("Leaving handle_sony_cd_attention at %d\n",
+                              __LINE__);
 #endif
-         return(0);
-      }
-
-      clear_attention();
-      atten_code = read_result_register();
-
-      switch (atten_code)
-      {
-       /* Someone changed the CD.  Mark it as changed */
-      case SONY_MECH_LOADED_ATTN:
-         disk_changed = 1;
-        sony_toc_read = 0;
-         sony_audio_status = CDROM_AUDIO_NO_STATUS;
-         sony_blocks_left = 0;
-         break;
-
-      case SONY_SPIN_DOWN_COMPLETE_ATTN:
-         /* Mark the disk as spun down. */
-         sony_spun_up = 0;
-         break;
-
-      case SONY_AUDIO_PLAY_DONE_ATTN:
-         sony_audio_status = CDROM_AUDIO_COMPLETED;
-         read_subcode();
-         break;
-
-      case SONY_EJECT_PUSHED_ATTN:
-         if (is_auto_eject)
-         {
-            sony_audio_status = CDROM_AUDIO_INVALID;
-         }
-         break;
-
-      case SONY_LEAD_IN_ERR_ATTN:
-      case SONY_LEAD_OUT_ERR_ATTN:
-      case SONY_DATA_TRACK_ERR_ATTN:
-      case SONY_AUDIO_PLAYBACK_ERR_ATTN:
-         sony_audio_status = CDROM_AUDIO_ERROR;
-         break;
-      }
-
-      num_consecutive_attentions++;
+                       return (0);
+               }
+
+               clear_attention();
+               atten_code = read_result_register();
+
+               switch (atten_code) {
+                       /* Someone changed the CD.  Mark it as changed */
+               case SONY_MECH_LOADED_ATTN:
+                       disk_changed = 1;
+                       sony_toc_read = 0;
+                       sony_audio_status = CDROM_AUDIO_NO_STATUS;
+                       sony_blocks_left = 0;
+                       break;
+
+               case SONY_SPIN_DOWN_COMPLETE_ATTN:
+                       /* Mark the disk as spun down. */
+                       sony_spun_up = 0;
+                       break;
+
+               case SONY_AUDIO_PLAY_DONE_ATTN:
+                       sony_audio_status = CDROM_AUDIO_COMPLETED;
+                       read_subcode();
+                       break;
+
+               case SONY_EJECT_PUSHED_ATTN:
+                       if (is_auto_eject) {
+                               sony_audio_status = CDROM_AUDIO_INVALID;
+                       }
+                       break;
+
+               case SONY_LEAD_IN_ERR_ATTN:
+               case SONY_LEAD_OUT_ERR_ATTN:
+               case SONY_DATA_TRACK_ERR_ATTN:
+               case SONY_AUDIO_PLAYBACK_ERR_ATTN:
+                       sony_audio_status = CDROM_AUDIO_ERROR;
+                       break;
+               }
+
+               num_consecutive_attentions++;
 #if DEBUG
-      printk("Leaving handle_sony_cd_attention at %d\n", __LINE__);
+               printk("Leaving handle_sony_cd_attention at %d\n",
+                      __LINE__);
 #endif
-      return(1);
-   }
-   else if (abort_read_started)
-   {
-      while (is_result_reg_not_empty())
-      {
-         val = read_result_register();
-      }
-      clear_data_ready();
-      clear_result_ready();
-      /* Clear out the data */
-      while (is_data_requested())
-      {
-         val = read_data_register();
-      }
-      abort_read_started = 0;
+               return (1);
+       } else if (abort_read_started) {
+               while (is_result_reg_not_empty()) {
+                       val = read_result_register();
+               }
+               clear_data_ready();
+               clear_result_ready();
+               /* Clear out the data */
+               while (is_data_requested()) {
+                       val = read_data_register();
+               }
+               abort_read_started = 0;
 #if DEBUG
-      printk("Leaving handle_sony_cd_attention at %d\n", __LINE__);
+               printk("Leaving handle_sony_cd_attention at %d\n",
+                      __LINE__);
 #endif
-      return(1);
-   }
+               return (1);
+       }
 
-   num_consecutive_attentions = 0;
+       num_consecutive_attentions = 0;
 #if 0*DEBUG
-   printk("Leaving handle_sony_cd_attention at %d\n", __LINE__);
+       printk("Leaving handle_sony_cd_attention at %d\n", __LINE__);
 #endif
-   return(0);
+       return (0);
 }
 
 
 /* Convert from an integer 0-99 to BCD */
-static inline unsigned int
-int_to_bcd(unsigned int val)
+static inline unsigned int int_to_bcd(unsigned int val)
 {
-   int retval;
+       int retval;
 
 
-   retval = (val / 10) << 4;
-   retval = retval | val % 10;
-   return(retval);
+       retval = (val / 10) << 4;
+       retval = retval | val % 10;
+       return (retval);
 }
 
 
 /* Convert from BCD to an integer from 0-99 */
-static unsigned int
-bcd_to_int(unsigned int bcd)
+static unsigned int bcd_to_int(unsigned int bcd)
 {
-   return((((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f));
+       return ((((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f));
 }
 
 
@@ -1161,32 +1107,30 @@ bcd_to_int(unsigned int bcd)
  * Convert a logical sector value (like the OS would want to use for
  * a block device) to an MSF format.
  */
-static void
-log_to_msf(unsigned int log, unsigned char *msf)
+static void log_to_msf(unsigned int log, unsigned char *msf)
 {
-   log = log + LOG_START_OFFSET;
-   msf[0] = int_to_bcd(log / 4500);
-   log = log % 4500;
-   msf[1] = int_to_bcd(log / 75);
-   msf[2] = int_to_bcd(log % 75);
+       log = log + LOG_START_OFFSET;
+       msf[0] = int_to_bcd(log / 4500);
+       log = log % 4500;
+       msf[1] = int_to_bcd(log / 75);
+       msf[2] = int_to_bcd(log % 75);
 }
 
 
 /*
  * Convert an MSF format to a logical sector.
  */
-static unsigned int
-msf_to_log(unsigned char *msf)
+static unsigned int msf_to_log(unsigned char *msf)
 {
-   unsigned int log;
+       unsigned int log;
 
 
-   log = msf[2];
-   log += msf[1] * 75;
-   log += msf[0] * 4500;
-   log = log - LOG_START_OFFSET;
+       log = msf[2];
+       log += msf[1] * 75;
+       log += msf[0] * 4500;
+       log = log - LOG_START_OFFSET;
 
-   return log;
+       return log;
 }
 
 
@@ -1194,14 +1138,12 @@ msf_to_log(unsigned char *msf)
  * Take in integer size value and put it into a buffer like
  * the drive would want to see a number-of-sector value.
  */
-static void
-size_to_buf(unsigned int size,
-            unsigned char *buf)
+static void size_to_buf(unsigned int size, unsigned char *buf)
 {
-   buf[0] = size / 65536;
-   size = size % 65536;
-   buf[1] = size / 256;
-   buf[2] = size % 256;
+       buf[0] = size / 65536;
+       size = size % 65536;
+       buf[1] = size / 256;
+       buf[2] = size % 256;
 }
 
 /* Starts a read operation. Returns 0 on success and 1 on failure. 
@@ -1211,430 +1153,380 @@ size_to_buf(unsigned int size,
    operation if the requested sector is not the next one from the
    drive. */
 static int
-start_request(unsigned int sector,
-              unsigned int nsect,
-              int          read_nsect_only)
+start_request(unsigned int sector, unsigned int nsect, int read_nsect_only)
 {
-   unsigned char params[6];
-   unsigned int read_size;
-   unsigned int retry_count;
+       unsigned char params[6];
+       unsigned int read_size;
+       unsigned int retry_count;
 
 
 #if DEBUG
-   printk("Entering start_request\n");
+       printk("Entering start_request\n");
 #endif
-   log_to_msf(sector, params);
-   /* If requested, read exactly what was asked. */
-   if (read_nsect_only)
-   {
-      read_size = nsect;
-   }
-   /*
-    * If the full read-ahead would go beyond the end of the media, trim
-    * it back to read just till the end of the media.
-    */
-   else if ((sector + nsect) >= sony_toc.lead_out_start_lba)
-   {
-      read_size = sony_toc.lead_out_start_lba - sector;
-   }
-   /* Read the full readahead amount. */
-   else
-   {
-      read_size = CDU31A_READAHEAD / 4;
-   }
-   size_to_buf(read_size, &params[3]);
-
-   /*
-    * Clear any outstanding attentions and wait for the drive to
-    * complete any pending operations.
-    */
-   while (handle_sony_cd_attention())
-      ;
-
-   retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-   while (time_before(jiffies, retry_count) && (is_busy()))
-   {
-      sony_sleep();
-      
-      while (handle_sony_cd_attention())
-         ;
-   }
-
-   if (is_busy())
-   {
-      printk("CDU31A: Timeout while waiting to issue command\n");
+       log_to_msf(sector, params);
+       /* If requested, read exactly what was asked. */
+       if (read_nsect_only) {
+               read_size = nsect;
+       }
+       /*
+        * If the full read-ahead would go beyond the end of the media, trim
+        * it back to read just till the end of the media.
+        */
+       else if ((sector + nsect) >= sony_toc.lead_out_start_lba) {
+               read_size = sony_toc.lead_out_start_lba - sector;
+       }
+       /* Read the full readahead amount. */
+       else {
+               read_size = CDU31A_READAHEAD / 4;
+       }
+       size_to_buf(read_size, &params[3]);
+
+       /*
+        * Clear any outstanding attentions and wait for the drive to
+        * complete any pending operations.
+        */
+       while (handle_sony_cd_attention());
+
+       retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
+       while (time_before(jiffies, retry_count) && (is_busy())) {
+               sony_sleep();
+
+               while (handle_sony_cd_attention());
+       }
+
+       if (is_busy()) {
+               printk("CDU31A: Timeout while waiting to issue command\n");
 #if DEBUG
-      printk("Leaving start_request at %d\n", __LINE__);
+               printk("Leaving start_request at %d\n", __LINE__);
 #endif
-      return(1);
-   }
-   else
-   {
-      /* Issue the command */
-      clear_result_ready();
-      clear_param_reg();
-
-      write_params(params, 6);
-      write_cmd(SONY_READ_BLKERR_STAT_CMD);
-
-      sony_blocks_left = read_size * 4;
-      sony_next_block = sector * 4;
-      readahead_dataleft = 0;
-      readahead_bad = 0;
+               return (1);
+       } else {
+               /* Issue the command */
+               clear_result_ready();
+               clear_param_reg();
+
+               write_params(params, 6);
+               write_cmd(SONY_READ_BLKERR_STAT_CMD);
+
+               sony_blocks_left = read_size * 4;
+               sony_next_block = sector * 4;
+               readahead_dataleft = 0;
+               readahead_bad = 0;
 #if DEBUG
-      printk("Leaving start_request at %d\n", __LINE__);
+               printk("Leaving start_request at %d\n", __LINE__);
 #endif
-      return(0);
-   }
+               return (0);
+       }
 #if DEBUG
-   printk("Leaving start_request at %d\n", __LINE__);
+       printk("Leaving start_request at %d\n", __LINE__);
 #endif
 }
 
 /* Abort a pending read operation.  Clear all the drive status and
    readahead variables. */
-static void
-abort_read(void)
-{
-   unsigned char result_reg[2];
-   int           result_size;
-   volatile int  val;
-
-
-   do_sony_cd_cmd(SONY_ABORT_CMD, NULL, 0, result_reg, &result_size);
-   if ((result_reg[0] & 0xf0) == 0x20)
-   {
-      printk("CDU31A: Error aborting read, %s error\n",
-             translate_error(
-             result_reg[1]));
-   }
-
-   while (is_result_reg_not_empty())
-   {
-      val = read_result_register();
-   }
-   clear_data_ready();
-   clear_result_ready();
-   /* Clear out the data */
-   while (is_data_requested())
-   {
-      val = read_data_register();
-   }
-
-   sony_blocks_left = 0;
-   readahead_dataleft = 0;
-   readahead_bad = 0;
+static void abort_read(void)
+{
+       unsigned char result_reg[2];
+       int result_size;
+       volatile int val;
+
+
+       do_sony_cd_cmd(SONY_ABORT_CMD, NULL, 0, result_reg, &result_size);
+       if ((result_reg[0] & 0xf0) == 0x20) {
+               printk("CDU31A: Error aborting read, %s error\n",
+                      translate_error(result_reg[1]));
+       }
+
+       while (is_result_reg_not_empty()) {
+               val = read_result_register();
+       }
+       clear_data_ready();
+       clear_result_ready();
+       /* Clear out the data */
+       while (is_data_requested()) {
+               val = read_data_register();
+       }
+
+       sony_blocks_left = 0;
+       readahead_dataleft = 0;
+       readahead_bad = 0;
 }
 
 /* Called when the timer times out.  This will abort the
    pending read operation. */
-static void
-handle_abort_timeout(unsigned long data)
+static void handle_abort_timeout(unsigned long data)
 {
-   unsigned long flags;
+       unsigned long flags;
 
 #if DEBUG
-   printk("Entering handle_abort_timeout\n");
+       printk("Entering handle_abort_timeout\n");
 #endif
-   save_flags(flags);
-   cli();
-   /* If it is in use, ignore it. */
-   if (!sony_inuse)
-   {
-      /* We can't use abort_read(), because it will sleep
-         or schedule in the timer interrupt.  Just start
-         the operation, finish it on the next access to
-         the drive. */
-      clear_result_ready();
-      clear_param_reg();
-      write_cmd(SONY_ABORT_CMD);
-
-      sony_blocks_left = 0;
-      readahead_dataleft = 0;
-      readahead_bad = 0;
-      abort_read_started = 1;
-   }
-   restore_flags(flags);
+       save_flags(flags);
+       cli();
+       /* If it is in use, ignore it. */
+       if (!sony_inuse) {
+               /* We can't use abort_read(), because it will sleep
+                  or schedule in the timer interrupt.  Just start
+                  the operation, finish it on the next access to
+                  the drive. */
+               clear_result_ready();
+               clear_param_reg();
+               write_cmd(SONY_ABORT_CMD);
+
+               sony_blocks_left = 0;
+               readahead_dataleft = 0;
+               readahead_bad = 0;
+               abort_read_started = 1;
+       }
+       restore_flags(flags);
 #if DEBUG
-   printk("Leaving handle_abort_timeout\n");
+       printk("Leaving handle_abort_timeout\n");
 #endif
 }
 
 /* Actually get data and status from the drive. */
 static void
-input_data(char         *buffer,
-           unsigned int bytesleft,
-           unsigned int nblocks,
-           unsigned int offset,
-           unsigned int skip)
+input_data(char *buffer,
+          unsigned int bytesleft,
+          unsigned int nblocks, unsigned int offset, unsigned int skip)
 {
-   int i;
-   volatile unsigned char val;
+       int i;
+       volatile unsigned char val;
 
 
 #if DEBUG
-   printk("Entering input_data\n");
+       printk("Entering input_data\n");
 #endif
-   /* If an XA disk on a CDU31A, skip the first 12 bytes of data from
-      the disk.  The real data is after that. */
-   if (sony_xa_mode)
-   {
-      for(i=0; i<CD_XA_HEAD; i++)
-      {
-         val = read_data_register();
-      }
-   }
-
-   clear_data_ready();
-
-   if (bytesleft == 2048) /* 2048 byte direct buffer transfer */
-   {
-      insb(sony_cd_read_reg, buffer, 2048);
-      readahead_dataleft = 0;
-   }
-   else
-   {
-      /* If the input read did not align with the beginning of the block,
-        skip the necessary bytes. */
-      if (skip != 0)
-      {
-         insb(sony_cd_read_reg, readahead_buffer, skip);
-      }
-
-      /* Get the data into the buffer. */
-      insb(sony_cd_read_reg, &buffer[offset], bytesleft);
-
-      /* Get the rest of the data into the readahead buffer at the
-        proper location. */
-      readahead_dataleft = (2048 - skip) - bytesleft;
-      insb(sony_cd_read_reg,
-           readahead_buffer + bytesleft,
-           readahead_dataleft);
-   }
-   sony_blocks_left -= nblocks;
-   sony_next_block += nblocks; 
-
-   /* If an XA disk, we have to clear out the rest of the unused
-      error correction data. */
-   if (sony_xa_mode)
-   {
-      for(i=0; i<CD_XA_TAIL; i++)
-      {
-         val = read_data_register();
-      }
-   }
+       /* If an XA disk on a CDU31A, skip the first 12 bytes of data from
+          the disk.  The real data is after that. */
+       if (sony_xa_mode) {
+               for (i = 0; i < CD_XA_HEAD; i++) {
+                       val = read_data_register();
+               }
+       }
+
+       clear_data_ready();
+
+       if (bytesleft == 2048) {        /* 2048 byte direct buffer transfer */
+               insb(sony_cd_read_reg, buffer, 2048);
+               readahead_dataleft = 0;
+       } else {
+               /* If the input read did not align with the beginning of the block,
+                  skip the necessary bytes. */
+               if (skip != 0) {
+                       insb(sony_cd_read_reg, readahead_buffer, skip);
+               }
+
+               /* Get the data into the buffer. */
+               insb(sony_cd_read_reg, &buffer[offset], bytesleft);
+
+               /* Get the rest of the data into the readahead buffer at the
+                  proper location. */
+               readahead_dataleft = (2048 - skip) - bytesleft;
+               insb(sony_cd_read_reg,
+                    readahead_buffer + bytesleft, readahead_dataleft);
+       }
+       sony_blocks_left -= nblocks;
+       sony_next_block += nblocks;
+
+       /* If an XA disk, we have to clear out the rest of the unused
+          error correction data. */
+       if (sony_xa_mode) {
+               for (i = 0; i < CD_XA_TAIL; i++) {
+                       val = read_data_register();
+               }
+       }
 #if DEBUG
-   printk("Leaving input_data at %d\n", __LINE__);
+       printk("Leaving input_data at %d\n", __LINE__);
 #endif
 }
 
 /* read data from the drive.  Note the nsect must be <= 4. */
 static void
-read_data_block(char          *buffer,
-                unsigned int  block,
-                unsigned int  nblocks,
-                unsigned char res_reg[],
-                int           *res_size)
+read_data_block(char *buffer,
+               unsigned int block,
+               unsigned int nblocks,
+               unsigned char res_reg[], int *res_size)
 {
-   unsigned int retry_count;
-   unsigned int bytesleft;
-   unsigned int offset;
-   unsigned int skip;
+       unsigned int retry_count;
+       unsigned int bytesleft;
+       unsigned int offset;
+       unsigned int skip;
 
 
 #if DEBUG
-   printk("Entering read_data_block\n");
+       printk("Entering read_data_block\n");
 #endif
 
-   res_reg[0] = 0;
-   res_reg[1] = 0;
-   *res_size = 0;
-   bytesleft = nblocks * 512;
-   offset = 0;
-
-   /* If the data in the read-ahead does not match the block offset,
-      then fix things up. */
-   if (((block % 4) * 512) != ((2048 - readahead_dataleft) % 2048))
-   {
-      sony_next_block += block % 4;
-      sony_blocks_left -= block % 4;
-      skip = (block % 4) * 512;
-   }
-   else
-   {
-      skip = 0;
-   }
-
-   /* We have readahead data in the buffer, get that first before we
-      decide if a read is necessary. */
-   if (readahead_dataleft != 0)
-   {
-      if (bytesleft > readahead_dataleft)
-      {
-        /* The readahead will not fill the requested buffer, but
-           get the data out of the readahead into the buffer. */
-         memcpy(buffer,
-                readahead_buffer + (2048 - readahead_dataleft),
-                readahead_dataleft);
-         readahead_dataleft = 0;
-         bytesleft -= readahead_dataleft;
-         offset += readahead_dataleft;
-      }
-      else
-      {
-        /* The readahead will fill the whole buffer, get the data
-           and return. */
-         memcpy(buffer,
-                readahead_buffer + (2048 - readahead_dataleft),
-                bytesleft);
-         readahead_dataleft -= bytesleft;
-         bytesleft = 0;
-         sony_blocks_left -= nblocks;
-         sony_next_block += nblocks;
-
-        /* If the data in the readahead is bad, return an error so the
-           driver will abort the buffer. */
-         if (readahead_bad)
-         {
-            res_reg[0] = 0x20;
-            res_reg[1] = SONY_BAD_DATA_ERR;
-            *res_size = 2;
-         }
-
-         if (readahead_dataleft == 0)
-         {
-            readahead_bad = 0;
-         }
-
-         /* Final transfer is done for read command, get final result. */
-         if (sony_blocks_left == 0)
-         {
-            get_result(res_reg, res_size);
-         }
+       res_reg[0] = 0;
+       res_reg[1] = 0;
+       *res_size = 0;
+       bytesleft = nblocks * 512;
+       offset = 0;
+
+       /* If the data in the read-ahead does not match the block offset,
+          then fix things up. */
+       if (((block % 4) * 512) != ((2048 - readahead_dataleft) % 2048)) {
+               sony_next_block += block % 4;
+               sony_blocks_left -= block % 4;
+               skip = (block % 4) * 512;
+       } else {
+               skip = 0;
+       }
+
+       /* We have readahead data in the buffer, get that first before we
+          decide if a read is necessary. */
+       if (readahead_dataleft != 0) {
+               if (bytesleft > readahead_dataleft) {
+                       /* The readahead will not fill the requested buffer, but
+                          get the data out of the readahead into the buffer. */
+                       memcpy(buffer,
+                              readahead_buffer + (2048 -
+                                                  readahead_dataleft),
+                              readahead_dataleft);
+                       readahead_dataleft = 0;
+                       bytesleft -= readahead_dataleft;
+                       offset += readahead_dataleft;
+               } else {
+                       /* The readahead will fill the whole buffer, get the data
+                          and return. */
+                       memcpy(buffer,
+                              readahead_buffer + (2048 -
+                                                  readahead_dataleft),
+                              bytesleft);
+                       readahead_dataleft -= bytesleft;
+                       bytesleft = 0;
+                       sony_blocks_left -= nblocks;
+                       sony_next_block += nblocks;
+
+                       /* If the data in the readahead is bad, return an error so the
+                          driver will abort the buffer. */
+                       if (readahead_bad) {
+                               res_reg[0] = 0x20;
+                               res_reg[1] = SONY_BAD_DATA_ERR;
+                               *res_size = 2;
+                       }
+
+                       if (readahead_dataleft == 0) {
+                               readahead_bad = 0;
+                       }
+
+                       /* Final transfer is done for read command, get final result. */
+                       if (sony_blocks_left == 0) {
+                               get_result(res_reg, res_size);
+                       }
 #if DEBUG
-         printk("Leaving read_data_block at %d\n", __LINE__);
+                       printk("Leaving read_data_block at %d\n",
+                              __LINE__);
 #endif
-         return;
-      }
-   }
-
-   /* Wait for the drive to tell us we have something */
-   retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-   while (time_before(jiffies, retry_count) && !(is_data_ready()))
-   {
-      while (handle_sony_cd_attention())
-         ;
-
-      sony_sleep();
-   }
-   if (!(is_data_ready()))
-   {
-      if (is_result_ready())
-      {
-         get_result(res_reg, res_size);
-         if ((res_reg[0] & 0xf0) != 0x20)
-         {
-            printk("CDU31A: Got result that should have been error: %d\n",
-                   res_reg[0]);
-            res_reg[0] = 0x20;
-            res_reg[1] = SONY_BAD_DATA_ERR;
-            *res_size = 2;
-         }
-         abort_read();
-      }
-      else
-      {
+                       return;
+               }
+       }
+
+       /* Wait for the drive to tell us we have something */
+       retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
+       while (time_before(jiffies, retry_count) && !(is_data_ready())) {
+               while (handle_sony_cd_attention());
+
+               sony_sleep();
+       }
+       if (!(is_data_ready())) {
+               if (is_result_ready()) {
+                       get_result(res_reg, res_size);
+                       if ((res_reg[0] & 0xf0) != 0x20) {
+                               printk
+                                   ("CDU31A: Got result that should have been error: %d\n",
+                                    res_reg[0]);
+                               res_reg[0] = 0x20;
+                               res_reg[1] = SONY_BAD_DATA_ERR;
+                               *res_size = 2;
+                       }
+                       abort_read();
+               } else {
 #if DEBUG
-         printk("CDU31A timeout out %d\n", __LINE__);
+                       printk("CDU31A timeout out %d\n", __LINE__);
 #endif
-         res_reg[0] = 0x20;
-         res_reg[1] = SONY_TIMEOUT_OP_ERR;
-         *res_size = 2;
-         abort_read();
-      }
-   }
-   else
-   {
-      input_data(buffer, bytesleft, nblocks, offset, skip);
-
-      /* Wait for the status from the drive. */
-      retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-      while (time_before(jiffies, retry_count) && !(is_result_ready()))
-      {
-         while (handle_sony_cd_attention())
-            ;
-
-         sony_sleep();
-      }
-
-      if (!is_result_ready())
-      {
+                       res_reg[0] = 0x20;
+                       res_reg[1] = SONY_TIMEOUT_OP_ERR;
+                       *res_size = 2;
+                       abort_read();
+               }
+       } else {
+               input_data(buffer, bytesleft, nblocks, offset, skip);
+
+               /* Wait for the status from the drive. */
+               retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
+               while (time_before(jiffies, retry_count)
+                      && !(is_result_ready())) {
+                       while (handle_sony_cd_attention());
+
+                       sony_sleep();
+               }
+
+               if (!is_result_ready()) {
 #if DEBUG
-         printk("CDU31A timeout out %d\n", __LINE__);
+                       printk("CDU31A timeout out %d\n", __LINE__);
 #endif
-         res_reg[0] = 0x20;
-         res_reg[1] = SONY_TIMEOUT_OP_ERR;
-         *res_size = 2;
-         abort_read();
-      }
-      else
-      {
-         get_result(res_reg, res_size);
-
-        /* If we got a buffer status, handle that. */
-         if ((res_reg[0] & 0xf0) == 0x50)
-         {
-
-            if (   (res_reg[0] == SONY_NO_CIRC_ERR_BLK_STAT)
-                || (res_reg[0] == SONY_NO_LECC_ERR_BLK_STAT)
-                || (res_reg[0] == SONY_RECOV_LECC_ERR_BLK_STAT))
-            {
-              /* The data was successful, but if data was read from
-                 the readahead  and it was bad, set the whole
-                 buffer as bad. */
-               if (readahead_bad)
-               {
-                  readahead_bad = 0;
-                  res_reg[0] = 0x20;
-                  res_reg[1] = SONY_BAD_DATA_ERR;
-                  *res_size = 2;
-               }
-            }
-            else
-            {
-               printk("CDU31A: Data block error: 0x%x\n", res_reg[0]);
-               res_reg[0] = 0x20;
-               res_reg[1] = SONY_BAD_DATA_ERR;
-               *res_size = 2;
-
-               /* Data is in the readahead buffer but an error was returned.
-                  Make sure future requests don't use the data. */
-               if (bytesleft != 2048)
-               {
-                  readahead_bad = 1;
-               }
-            }
-
-            /* Final transfer is done for read command, get final result. */
-            if (sony_blocks_left == 0)
-            {
-               get_result(res_reg, res_size);
-            }
-         }
-         else if ((res_reg[0] & 0xf0) != 0x20)
-         {
-            /* The drive gave me bad status, I don't know what to do.
-               Reset the driver and return an error. */
-            printk("CDU31A: Invalid block status: 0x%x\n", res_reg[0]);
-            restart_on_error();
-            res_reg[0] = 0x20;
-            res_reg[1] = SONY_BAD_DATA_ERR;
-            *res_size = 2;
-         }
-      }
-   }
+                       res_reg[0] = 0x20;
+                       res_reg[1] = SONY_TIMEOUT_OP_ERR;
+                       *res_size = 2;
+                       abort_read();
+               } else {
+                       get_result(res_reg, res_size);
+
+                       /* If we got a buffer status, handle that. */
+                       if ((res_reg[0] & 0xf0) == 0x50) {
+
+                               if ((res_reg[0] ==
+                                    SONY_NO_CIRC_ERR_BLK_STAT)
+                                   || (res_reg[0] ==
+                                       SONY_NO_LECC_ERR_BLK_STAT)
+                                   || (res_reg[0] ==
+                                       SONY_RECOV_LECC_ERR_BLK_STAT)) {
+                                       /* The data was successful, but if data was read from
+                                          the readahead  and it was bad, set the whole
+                                          buffer as bad. */
+                                       if (readahead_bad) {
+                                               readahead_bad = 0;
+                                               res_reg[0] = 0x20;
+                                               res_reg[1] =
+                                                   SONY_BAD_DATA_ERR;
+                                               *res_size = 2;
+                                       }
+                               } else {
+                                       printk
+                                           ("CDU31A: Data block error: 0x%x\n",
+                                            res_reg[0]);
+                                       res_reg[0] = 0x20;
+                                       res_reg[1] = SONY_BAD_DATA_ERR;
+                                       *res_size = 2;
+
+                                       /* Data is in the readahead buffer but an error was returned.
+                                          Make sure future requests don't use the data. */
+                                       if (bytesleft != 2048) {
+                                               readahead_bad = 1;
+                                       }
+                               }
+
+                               /* Final transfer is done for read command, get final result. */
+                               if (sony_blocks_left == 0) {
+                                       get_result(res_reg, res_size);
+                               }
+                       } else if ((res_reg[0] & 0xf0) != 0x20) {
+                               /* The drive gave me bad status, I don't know what to do.
+                                  Reset the driver and return an error. */
+                               printk
+                                   ("CDU31A: Invalid block status: 0x%x\n",
+                                    res_reg[0]);
+                               restart_on_error();
+                               res_reg[0] = 0x20;
+                               res_reg[1] = SONY_BAD_DATA_ERR;
+                               *res_size = 2;
+                       }
+               }
+       }
 #if DEBUG
-   printk("Leaving read_data_block at %d\n", __LINE__);
+       printk("Leaving read_data_block at %d\n", __LINE__);
 #endif
 }
 
@@ -1646,230 +1538,215 @@ read_data_block(char          *buffer,
  * uses 1024 byte blocks and the drive uses 2048 byte blocks.  Since most
  * data access on a CD is done sequentially, this saves a lot of operations.
  */
-static void
-do_cdu31a_request(request_queue_t * q)
+static void do_cdu31a_request(request_queue_t * q)
 {
-   int block;
-   int nblock;
-   unsigned char res_reg[12];
-   unsigned int res_size;
-   int num_retries;
-   unsigned long flags;
+       int block;
+       int nblock;
+       unsigned char res_reg[12];
+       unsigned int res_size;
+       int num_retries;
+       unsigned long flags;
 
 
 #if DEBUG
-         printk("Entering do_cdu31a_request\n");
+       printk("Entering do_cdu31a_request\n");
 #endif
 
-   /* 
-    * Make sure no one else is using the driver; wait for them
-    * to finish if it is so.
-    */
-   save_flags(flags);
-   cli();
-   while (sony_inuse)
-   {
-      interruptible_sleep_on(&sony_wait);
-      if (signal_pending(current))
-      {
-         restore_flags(flags);
-         if (!QUEUE_EMPTY && CURRENT->rq_status != RQ_INACTIVE)
-         {
-            end_request(0);
-         }
-         restore_flags(flags);
+       /* 
+        * Make sure no one else is using the driver; wait for them
+        * to finish if it is so.
+        */
+       save_flags(flags);
+       cli();
+       while (sony_inuse) {
+               interruptible_sleep_on(&sony_wait);
+               if (signal_pending(current)) {
+                       restore_flags(flags);
+                       if (!QUEUE_EMPTY
+                           && CURRENT->rq_status != RQ_INACTIVE) {
+                               end_request(0);
+                       }
+                       restore_flags(flags);
 #if DEBUG
-         printk("Leaving do_cdu31a_request at %d\n", __LINE__);
+                       printk("Leaving do_cdu31a_request at %d\n",
+                              __LINE__);
 #endif
-         return;
-      }
-   }
-   sony_inuse = 1;
-   has_cd_task = current;
-
-   /* Get drive status before doing anything. */
-   while (handle_sony_cd_attention())
-      ;
-
-   /* Make sure we have a valid TOC. */
-   sony_get_toc(); 
-
-   spin_unlock_irq(&io_request_lock);
-
-   /* Make sure the timer is cancelled. */
-   del_timer(&cdu31a_abort_timer);
-
-   while (1)
-   {
-cdu31a_request_startover:
-      /*
-       * The beginning here is stolen from the hard disk driver.  I hope
-       * it's right.
-       */
-      if (QUEUE_EMPTY || CURRENT->rq_status == RQ_INACTIVE)
-      {
-         goto end_do_cdu31a_request;
-      }
-
-      if (!sony_spun_up)
-      {
-         scd_spinup();
-      }
-
-      /* I don't use INIT_REQUEST because it calls return, which would
-         return without unlocking the device.  It shouldn't matter,
-         but just to be safe... */
-      if (MAJOR(CURRENT->rq_dev) != MAJOR_NR)
-      {
-        panic(DEVICE_NAME ": request list destroyed");
-      }
-      if (CURRENT->bh)
-      {
-        if (!buffer_locked(CURRENT->bh))
-         {
-           panic(DEVICE_NAME ": block not locked");
-         }
-      }
-
-      block = CURRENT->sector;
-      nblock = CURRENT->nr_sectors;
-
-      if (!sony_toc_read)
-      {
-        printk("CDU31A: TOC not read\n");
-        end_request(0);
-        goto cdu31a_request_startover;
-      }
-
-      switch(CURRENT->cmd)
-      {
-      case READ:
-         /*
-          * If the block address is invalid or the request goes beyond the end of
-          * the media, return an error.
-          */
+                       return;
+               }
+       }
+       sony_inuse = 1;
+       has_cd_task = current;
+
+       /* Get drive status before doing anything. */
+       while (handle_sony_cd_attention());
+
+       /* Make sure we have a valid TOC. */
+       sony_get_toc();
+
+       spin_unlock_irq(&io_request_lock);
+
+       /* Make sure the timer is cancelled. */
+       del_timer(&cdu31a_abort_timer);
+
+       while (1) {
+             cdu31a_request_startover:
+               /*
+                * The beginning here is stolen from the hard disk driver.  I hope
+                * it's right.
+                */
+               if (QUEUE_EMPTY || CURRENT->rq_status == RQ_INACTIVE) {
+                       goto end_do_cdu31a_request;
+               }
+
+               if (!sony_spun_up) {
+                       scd_spinup();
+               }
+
+               /* I don't use INIT_REQUEST because it calls return, which would
+                  return without unlocking the device.  It shouldn't matter,
+                  but just to be safe... */
+               if (MAJOR(CURRENT->rq_dev) != MAJOR_NR) {
+                       panic(DEVICE_NAME ": request list destroyed");
+               }
+               if (CURRENT->bh) {
+                       if (!buffer_locked(CURRENT->bh)) {
+                               panic(DEVICE_NAME ": block not locked");
+                       }
+               }
+
+               block = CURRENT->sector;
+               nblock = CURRENT->nr_sectors;
+
+               if (!sony_toc_read) {
+                       printk("CDU31A: TOC not read\n");
+                       end_request(0);
+                       goto cdu31a_request_startover;
+               }
+
+               switch (CURRENT->cmd) {
+               case READ:
+                       /*
+                        * If the block address is invalid or the request goes beyond the end of
+                        * the media, return an error.
+                        */
 #if 0
-        if ((block / 4) < sony_toc.start_track_lba)
-        {
-            printk("CDU31A: Request before beginning of media\n");
-            end_request(0);
-            goto cdu31a_request_startover;
-        }
+                       if ((block / 4) < sony_toc.start_track_lba) {
+                               printk
+                                   ("CDU31A: Request before beginning of media\n");
+                               end_request(0);
+                               goto cdu31a_request_startover;
+                       }
 #endif
-         if ((block / 4) >= sony_toc.lead_out_start_lba)
-         {
-            printk("CDU31A: Request past end of media\n");
-            end_request(0);
-            goto cdu31a_request_startover;
-         }
-         if (((block + nblock) / 4) >= sony_toc.lead_out_start_lba)
-         {
-            printk("CDU31A: Request past end of media\n");
-            end_request(0);
-            goto cdu31a_request_startover;
-         }
-
-         num_retries = 0;
-
-try_read_again:
-         while (handle_sony_cd_attention())
-            ;
-
-         if (!sony_toc_read)
-         {
-           printk("CDU31A: TOC not read\n");
-           end_request(0);
-           goto cdu31a_request_startover;
-         }
-
-        /* If no data is left to be read from the drive, start the
-           next request. */
-         if (sony_blocks_left == 0)
-         {
-            if (start_request(block / 4, CDU31A_READAHEAD / 4, 0))
-            {
-               end_request(0);
-               goto cdu31a_request_startover;
-            }
-         }
-        /* If the requested block is not the next one waiting in
-           the driver, abort the current operation and start a
-           new one. */
-         else if (block != sony_next_block)
-         {
+                       if ((block / 4) >= sony_toc.lead_out_start_lba) {
+                               printk
+                                   ("CDU31A: Request past end of media\n");
+                               end_request(0);
+                               goto cdu31a_request_startover;
+                       }
+                       if (((block + nblock) / 4) >=
+                           sony_toc.lead_out_start_lba) {
+                               printk
+                                   ("CDU31A: Request past end of media\n");
+                               end_request(0);
+                               goto cdu31a_request_startover;
+                       }
+
+                       num_retries = 0;
+
+                     try_read_again:
+                       while (handle_sony_cd_attention());
+
+                       if (!sony_toc_read) {
+                               printk("CDU31A: TOC not read\n");
+                               end_request(0);
+                               goto cdu31a_request_startover;
+                       }
+
+                       /* If no data is left to be read from the drive, start the
+                          next request. */
+                       if (sony_blocks_left == 0) {
+                               if (start_request
+                                   (block / 4, CDU31A_READAHEAD / 4, 0)) {
+                                       end_request(0);
+                                       goto cdu31a_request_startover;
+                               }
+                       }
+                       /* If the requested block is not the next one waiting in
+                          the driver, abort the current operation and start a
+                          new one. */
+                       else if (block != sony_next_block) {
 #if DEBUG
-            printk("CDU31A Warning: Read for block %d, expected %d\n",
-                   block,
-                   sony_next_block);
+                               printk
+                                   ("CDU31A Warning: Read for block %d, expected %d\n",
+                                    block, sony_next_block);
 #endif
-            abort_read();
-            if (!sony_toc_read)
-            {
-              printk("CDU31A: TOC not read\n");
-              end_request(0);
-               goto cdu31a_request_startover;
-            }
-            if (start_request(block / 4, CDU31A_READAHEAD / 4, 0))
-            {
-               printk("CDU31a: start request failed\n");
-               end_request(0);
-               goto cdu31a_request_startover;
-            }
-         }
-
-         read_data_block(CURRENT->buffer, block, nblock, res_reg, &res_size);
-         if (res_reg[0] == 0x20)
-         {
-            if (num_retries > MAX_CDU31A_RETRIES)
-            {
-               end_request(0);
-               goto cdu31a_request_startover;
-            }
-
-            num_retries++;
-            if (res_reg[1] == SONY_NOT_SPIN_ERR)
-            {
-               do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-            }
-            else
-            {
-               printk("CDU31A: %s error for block %d, nblock %d\n", translate_error(res_reg[1]), block, nblock);
-            }
-            goto try_read_again;
-         }
-         else
-         {
-            end_request(1);
-         }
-         break;
-            
-      case WRITE:
-         end_request(0);
-         break;
-            
-      default:
-         panic("CDU31A: Unknown cmd");
-      }
-   }
-
-end_do_cdu31a_request:
-   spin_lock_irq(&io_request_lock);
+                               abort_read();
+                               if (!sony_toc_read) {
+                                       printk("CDU31A: TOC not read\n");
+                                       end_request(0);
+                                       goto cdu31a_request_startover;
+                               }
+                               if (start_request
+                                   (block / 4, CDU31A_READAHEAD / 4, 0)) {
+                                       printk
+                                           ("CDU31a: start request failed\n");
+                                       end_request(0);
+                                       goto cdu31a_request_startover;
+                               }
+                       }
+
+                       read_data_block(CURRENT->buffer, block, nblock,
+                                       res_reg, &res_size);
+                       if (res_reg[0] == 0x20) {
+                               if (num_retries > MAX_CDU31A_RETRIES) {
+                                       end_request(0);
+                                       goto cdu31a_request_startover;
+                               }
+
+                               num_retries++;
+                               if (res_reg[1] == SONY_NOT_SPIN_ERR) {
+                                       do_sony_cd_cmd(SONY_SPIN_UP_CMD,
+                                                      NULL, 0, res_reg,
+                                                      &res_size);
+                               } else {
+                                       printk
+                                           ("CDU31A: %s error for block %d, nblock %d\n",
+                                            translate_error(res_reg[1]),
+                                            block, nblock);
+                               }
+                               goto try_read_again;
+                       } else {
+                               end_request(1);
+                       }
+                       break;
+
+               case WRITE:
+                       end_request(0);
+                       break;
+
+               default:
+                       panic("CDU31A: Unknown cmd");
+               }
+       }
+
+      end_do_cdu31a_request:
+       spin_lock_irq(&io_request_lock);
 #if 0
-   /* After finished, cancel any pending operations. */
-   abort_read();
+       /* After finished, cancel any pending operations. */
+       abort_read();
 #else
-   /* Start a timer to time out after a while to disable
-      the read. */
-   cdu31a_abort_timer.expires = jiffies + 2*HZ; /* Wait 2 seconds */
-   add_timer(&cdu31a_abort_timer);
+       /* Start a timer to time out after a while to disable
+          the read. */
+       cdu31a_abort_timer.expires = jiffies + 2 * HZ;  /* Wait 2 seconds */
+       add_timer(&cdu31a_abort_timer);
 #endif
 
-   has_cd_task = NULL;
-   sony_inuse = 0;
-   wake_up_interruptible(&sony_wait);
-   restore_flags(flags);
+       has_cd_task = NULL;
+       sony_inuse = 0;
+       wake_up_interruptible(&sony_wait);
+       restore_flags(flags);
 #if DEBUG
-   printk("Leaving do_cdu31a_request at %d\n", __LINE__);
+       printk("Leaving do_cdu31a_request at %d\n", __LINE__);
 #endif
 }
 
@@ -1878,356 +1755,473 @@ end_do_cdu31a_request:
  * Read the table of contents from the drive and set up TOC if
  * successful.
  */
-static void
-sony_get_toc(void)
+static void sony_get_toc(void)
 {
-   unsigned char res_reg[2];
-   unsigned int res_size;
-   unsigned char parms[1];
-   int session;
-   int num_spin_ups;
-   int totaltracks = 0;
-   int mint = 99;
-   int maxt = 0;
+       unsigned char res_reg[2];
+       unsigned int res_size;
+       unsigned char parms[1];
+       int session;
+       int num_spin_ups;
+       int totaltracks = 0;
+       int mint = 99;
+       int maxt = 0;
 
 #if DEBUG
-   printk("Entering sony_get_toc\n");
+       printk("Entering sony_get_toc\n");
 #endif
 
-   num_spin_ups = 0;
-   if (!sony_toc_read)
-   {
-respinup_on_gettoc:
-      /* Ignore the result, since it might error if spinning already. */
-      do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-
-      do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, &res_size);
-
-      /* The drive sometimes returns error 0.  I don't know why, but ignore
-         it.  It seems to mean the drive has already done the operation. */
-      if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0)))
-      {
-         /* If the drive is already playing, it's ok.  */
-         if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR) || (res_reg[1] == 0))
-         {
-            goto gettoc_drive_spinning;
-         }
-
-         /* If the drive says it is not spun up (even though we just did it!)
-            then retry the operation at least a few times. */
-         if (   (res_reg[1] == SONY_NOT_SPIN_ERR)
-             && (num_spin_ups < MAX_CDU31A_RETRIES))
-         {
-            num_spin_ups++;
-            goto respinup_on_gettoc;
-         }
-
-         printk("cdu31a: Error reading TOC: %x %s\n",
-                res_reg[0], translate_error(res_reg[1]));
-        return;
-      }
-
-gettoc_drive_spinning:
-
-      /* The idea here is we keep asking for sessions until the command
-        fails.  Then we know what the last valid session on the disk is.
-        No need to check session 0, since session 0 is the same as session
-         1; the command returns different information if you give it 0. 
-        */
+       num_spin_ups = 0;
+       if (!sony_toc_read) {
+             respinup_on_gettoc:
+               /* Ignore the result, since it might error if spinning already. */
+               do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
+                              &res_size);
+
+               do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg,
+                              &res_size);
+
+               /* The drive sometimes returns error 0.  I don't know why, but ignore
+                  it.  It seems to mean the drive has already done the operation. */
+               if ((res_size < 2)
+                   || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
+                       /* If the drive is already playing, it's ok.  */
+                       if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR)
+                           || (res_reg[1] == 0)) {
+                               goto gettoc_drive_spinning;
+                       }
+
+                       /* If the drive says it is not spun up (even though we just did it!)
+                          then retry the operation at least a few times. */
+                       if ((res_reg[1] == SONY_NOT_SPIN_ERR)
+                           && (num_spin_ups < MAX_CDU31A_RETRIES)) {
+                               num_spin_ups++;
+                               goto respinup_on_gettoc;
+                       }
+
+                       printk("cdu31a: Error reading TOC: %x %s\n",
+                              res_reg[0], translate_error(res_reg[1]));
+                       return;
+               }
+
+             gettoc_drive_spinning:
+
+               /* The idea here is we keep asking for sessions until the command
+                  fails.  Then we know what the last valid session on the disk is.
+                  No need to check session 0, since session 0 is the same as session
+                  1; the command returns different information if you give it 0. 
+                */
 #if DEBUG
-      memset(&sony_toc, 0x0e, sizeof(sony_toc));
-      memset(&single_toc, 0x0f, sizeof(single_toc));
+               memset(&sony_toc, 0x0e, sizeof(sony_toc));
+               memset(&single_toc, 0x0f, sizeof(single_toc));
 #endif
-      session = 1;
-      while (1)
-      {
+               session = 1;
+               while (1) {
 /* This seems to slow things down enough to make it work.  This
  * appears to be a problem in do_sony_cd_cmd.  This printk seems 
  * to address the symptoms...  -Erik */
 #if 1
-         printk("cdu31a: Trying session %d\n", session);
+                       printk("cdu31a: Trying session %d\n", session);
 #endif
-        parms[0] = session;
-        do_sony_cd_cmd(SONY_READ_TOC_SPEC_CMD,
-                       parms,
-                       1, 
-                       res_reg,
-                       &res_size);
+                       parms[0] = session;
+                       do_sony_cd_cmd(SONY_READ_TOC_SPEC_CMD,
+                                      parms, 1, res_reg, &res_size);
 
 #if DEBUG
-         printk("%2.2x %2.2x\n", res_reg[0], res_reg[1]);
+                       printk("%2.2x %2.2x\n", res_reg[0], res_reg[1]);
 #endif
 
-        if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
-        {
-           /* An error reading the TOC, this must be past the last session. */
-            if (session == 1)
-                   printk("Yikes! Couldn't read any sessions!");
-           break;
-         }
+                       if ((res_size < 2)
+                           || ((res_reg[0] & 0xf0) == 0x20)) {
+                               /* An error reading the TOC, this must be past the last session. */
+                               if (session == 1)
+                                       printk
+                                           ("Yikes! Couldn't read any sessions!");
+                               break;
+                       }
 #if DEBUG
-         printk("Reading session %d\n", session);
+                       printk("Reading session %d\n", session);
 #endif
 
-         parms[0] = session;
-         do_sony_cd_cmd(SONY_REQ_TOC_DATA_SPEC_CMD,
-                    parms,
-                    1, 
-                    (unsigned char *) &single_toc, 
-                    &res_size);
-         if ((res_size < 2) || ((single_toc.exec_status[0] & 0xf0) == 0x20))
-         {
-            printk("cdu31a: Error reading session %d: %x %s\n",
-                session,
-                single_toc.exec_status[0],
-                translate_error(single_toc.exec_status[1]));
-           /* An error reading the TOC.  Return without sony_toc_read
-              set. */
-           return;
-         }
+                       parms[0] = session;
+                       do_sony_cd_cmd(SONY_REQ_TOC_DATA_SPEC_CMD,
+                                      parms,
+                                      1,
+                                      (unsigned char *) &single_toc,
+                                      &res_size);
+                       if ((res_size < 2)
+                           || ((single_toc.exec_status[0] & 0xf0) ==
+                               0x20)) {
+                               printk
+                                   ("cdu31a: Error reading session %d: %x %s\n",
+                                    session, single_toc.exec_status[0],
+                                    translate_error(single_toc.
+                                                    exec_status[1]));
+                               /* An error reading the TOC.  Return without sony_toc_read
+                                  set. */
+                               return;
+                       }
 #if DEBUG
-      printk("add0 %01x, con0 %01x, poi0 %02x, 1st trk %d, dsktyp %x, dum0 %x\n",
-              single_toc.address0, single_toc.control0, single_toc.point0,
-              bcd_to_int(single_toc.first_track_num), single_toc.disk_type, single_toc.dummy0);
-      printk("add1 %01x, con1 %01x, poi1 %02x, lst trk %d, dummy1 %x, dum2 %x\n",
-              single_toc.address1, single_toc.control1, single_toc.point1,
-              bcd_to_int(single_toc.last_track_num), single_toc.dummy1, single_toc.dummy2);
-      printk("add2 %01x, con2 %01x, poi2 %02x leadout start min %d, sec %d, frame %d\n",
-              single_toc.address2, single_toc.control2, single_toc.point2,
-              bcd_to_int(single_toc.lead_out_start_msf[0]),
-              bcd_to_int(single_toc.lead_out_start_msf[1]),
-              bcd_to_int(single_toc.lead_out_start_msf[2]));
-      if (res_size > 18 && single_toc.pointb0 > 0xaf)
-      printk("addb0 %01x, conb0 %01x, poib0 %02x, nextsession min %d, sec %d, frame %d\n"
-             "#mode5_ptrs %02d, max_start_outer_leadout_msf min %d, sec %d, frame %d\n",
-              single_toc.addressb0, single_toc.controlb0, single_toc.pointb0,
-              bcd_to_int(single_toc.next_poss_prog_area_msf[0]),
-              bcd_to_int(single_toc.next_poss_prog_area_msf[1]),
-              bcd_to_int(single_toc.next_poss_prog_area_msf[2]),
-              single_toc.num_mode_5_pointers,
-              bcd_to_int(single_toc.max_start_outer_leadout_msf[0]),
-              bcd_to_int(single_toc.max_start_outer_leadout_msf[1]),
-              bcd_to_int(single_toc.max_start_outer_leadout_msf[2]));
-      if (res_size > 27 && single_toc.pointb1 > 0xaf)
-      printk("addb1 %01x, conb1 %01x, poib1 %02x, %x %x %x %x #skipint_ptrs %d, #skiptrkassign %d %x\n",
-              single_toc.addressb1, single_toc.controlb1, single_toc.pointb1,
-              single_toc.dummyb0_1[0],
-              single_toc.dummyb0_1[1],
-              single_toc.dummyb0_1[2],
-              single_toc.dummyb0_1[3],
-              single_toc.num_skip_interval_pointers,
-              single_toc.num_skip_track_assignments,
-              single_toc.dummyb0_2);
-      if (res_size > 36 && single_toc.pointb2 > 0xaf)
-      printk("addb2 %01x, conb2 %01x, poib2 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
-              single_toc.addressb2, single_toc.controlb2, single_toc.pointb2,
-              single_toc.tracksb2[0],
-              single_toc.tracksb2[1],
-              single_toc.tracksb2[2],
-              single_toc.tracksb2[3],
-              single_toc.tracksb2[4],
-              single_toc.tracksb2[5],
-              single_toc.tracksb2[6]);
-      if (res_size > 45 && single_toc.pointb3 > 0xaf)
-      printk("addb3 %01x, conb3 %01x, poib3 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
-              single_toc.addressb3, single_toc.controlb3, single_toc.pointb3,
-              single_toc.tracksb3[0],
-              single_toc.tracksb3[1],
-              single_toc.tracksb3[2],
-              single_toc.tracksb3[3],
-              single_toc.tracksb3[4],
-              single_toc.tracksb3[5],
-              single_toc.tracksb3[6]);
-      if (res_size > 54 && single_toc.pointb4 > 0xaf)
-      printk("addb4 %01x, conb4 %01x, poib4 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
-              single_toc.addressb4, single_toc.controlb4, single_toc.pointb4,
-              single_toc.tracksb4[0],
-              single_toc.tracksb4[1],
-              single_toc.tracksb4[2],
-              single_toc.tracksb4[3],
-              single_toc.tracksb4[4],
-              single_toc.tracksb4[5],
-              single_toc.tracksb4[6]);
-      if (res_size > 63 && single_toc.pointc0 > 0xaf)
-      printk("addc0 %01x, conc0 %01x, poic0 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
-              single_toc.addressc0, single_toc.controlc0, single_toc.pointc0,
-              single_toc.dummyc0[0],
-              single_toc.dummyc0[1],
-              single_toc.dummyc0[2],
-              single_toc.dummyc0[3],
-              single_toc.dummyc0[4],
-              single_toc.dummyc0[5],
-              single_toc.dummyc0[6]);
+                       printk
+                           ("add0 %01x, con0 %01x, poi0 %02x, 1st trk %d, dsktyp %x, dum0 %x\n",
+                            single_toc.address0, single_toc.control0,
+                            single_toc.point0,
+                            bcd_to_int(single_toc.first_track_num),
+                            single_toc.disk_type, single_toc.dummy0);
+                       printk
+                           ("add1 %01x, con1 %01x, poi1 %02x, lst trk %d, dummy1 %x, dum2 %x\n",
+                            single_toc.address1, single_toc.control1,
+                            single_toc.point1,
+                            bcd_to_int(single_toc.last_track_num),
+                            single_toc.dummy1, single_toc.dummy2);
+                       printk
+                           ("add2 %01x, con2 %01x, poi2 %02x leadout start min %d, sec %d, frame %d\n",
+                            single_toc.address2, single_toc.control2,
+                            single_toc.point2,
+                            bcd_to_int(single_toc.lead_out_start_msf[0]),
+                            bcd_to_int(single_toc.lead_out_start_msf[1]),
+                            bcd_to_int(single_toc.lead_out_start_msf[2]));
+                       if (res_size > 18 && single_toc.pointb0 > 0xaf)
+                               printk
+                                   ("addb0 %01x, conb0 %01x, poib0 %02x, nextsession min %d, sec %d, frame %d\n"
+                                    "#mode5_ptrs %02d, max_start_outer_leadout_msf min %d, sec %d, frame %d\n",
+                                    single_toc.addressb0,
+                                    single_toc.controlb0,
+                                    single_toc.pointb0,
+                                    bcd_to_int(single_toc.
+                                               next_poss_prog_area_msf
+                                               [0]),
+                                    bcd_to_int(single_toc.
+                                               next_poss_prog_area_msf
+                                               [1]),
+                                    bcd_to_int(single_toc.
+                                               next_poss_prog_area_msf
+                                               [2]),
+                                    single_toc.num_mode_5_pointers,
+                                    bcd_to_int(single_toc.
+                                               max_start_outer_leadout_msf
+                                               [0]),
+                                    bcd_to_int(single_toc.
+                                               max_start_outer_leadout_msf
+                                               [1]),
+                                    bcd_to_int(single_toc.
+                                               max_start_outer_leadout_msf
+                                               [2]));
+                       if (res_size > 27 && single_toc.pointb1 > 0xaf)
+                               printk
+                                   ("addb1 %01x, conb1 %01x, poib1 %02x, %x %x %x %x #skipint_ptrs %d, #skiptrkassign %d %x\n",
+                                    single_toc.addressb1,
+                                    single_toc.controlb1,
+                                    single_toc.pointb1,
+                                    single_toc.dummyb0_1[0],
+                                    single_toc.dummyb0_1[1],
+                                    single_toc.dummyb0_1[2],
+                                    single_toc.dummyb0_1[3],
+                                    single_toc.num_skip_interval_pointers,
+                                    single_toc.num_skip_track_assignments,
+                                    single_toc.dummyb0_2);
+                       if (res_size > 36 && single_toc.pointb2 > 0xaf)
+                               printk
+                                   ("addb2 %01x, conb2 %01x, poib2 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
+                                    single_toc.addressb2,
+                                    single_toc.controlb2,
+                                    single_toc.pointb2,
+                                    single_toc.tracksb2[0],
+                                    single_toc.tracksb2[1],
+                                    single_toc.tracksb2[2],
+                                    single_toc.tracksb2[3],
+                                    single_toc.tracksb2[4],
+                                    single_toc.tracksb2[5],
+                                    single_toc.tracksb2[6]);
+                       if (res_size > 45 && single_toc.pointb3 > 0xaf)
+                               printk
+                                   ("addb3 %01x, conb3 %01x, poib3 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
+                                    single_toc.addressb3,
+                                    single_toc.controlb3,
+                                    single_toc.pointb3,
+                                    single_toc.tracksb3[0],
+                                    single_toc.tracksb3[1],
+                                    single_toc.tracksb3[2],
+                                    single_toc.tracksb3[3],
+                                    single_toc.tracksb3[4],
+                                    single_toc.tracksb3[5],
+                                    single_toc.tracksb3[6]);
+                       if (res_size > 54 && single_toc.pointb4 > 0xaf)
+                               printk
+                                   ("addb4 %01x, conb4 %01x, poib4 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
+                                    single_toc.addressb4,
+                                    single_toc.controlb4,
+                                    single_toc.pointb4,
+                                    single_toc.tracksb4[0],
+                                    single_toc.tracksb4[1],
+                                    single_toc.tracksb4[2],
+                                    single_toc.tracksb4[3],
+                                    single_toc.tracksb4[4],
+                                    single_toc.tracksb4[5],
+                                    single_toc.tracksb4[6]);
+                       if (res_size > 63 && single_toc.pointc0 > 0xaf)
+                               printk
+                                   ("addc0 %01x, conc0 %01x, poic0 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
+                                    single_toc.addressc0,
+                                    single_toc.controlc0,
+                                    single_toc.pointc0,
+                                    single_toc.dummyc0[0],
+                                    single_toc.dummyc0[1],
+                                    single_toc.dummyc0[2],
+                                    single_toc.dummyc0[3],
+                                    single_toc.dummyc0[4],
+                                    single_toc.dummyc0[5],
+                                    single_toc.dummyc0[6]);
 #endif
 #undef DEBUG
 #define DEBUG 0
 
-      sony_toc.lead_out_start_msf[0] = bcd_to_int(single_toc.lead_out_start_msf[0]);
-      sony_toc.lead_out_start_msf[1] = bcd_to_int(single_toc.lead_out_start_msf[1]);
-      sony_toc.lead_out_start_msf[2] = bcd_to_int(single_toc.lead_out_start_msf[2]);
-      sony_toc.lead_out_start_lba = single_toc.lead_out_start_lba =
-                    msf_to_log(sony_toc.lead_out_start_msf);
-
-      /* For points that do not exist, move the data over them
-        to the right location. */
-      if (single_toc.pointb0 != 0xb0)
-      {
-        memmove(((char *) &single_toc) + 27,
-                ((char *) &single_toc) + 18,
-                res_size - 18);
-        res_size += 9;
-      }
-      else if (res_size > 18) {
-        sony_toc.lead_out_start_msf[0] = bcd_to_int(single_toc.max_start_outer_leadout_msf[0]);
-        sony_toc.lead_out_start_msf[1] = bcd_to_int(single_toc.max_start_outer_leadout_msf[1]);
-        sony_toc.lead_out_start_msf[2] = bcd_to_int(single_toc.max_start_outer_leadout_msf[2]);
-        sony_toc.lead_out_start_lba = msf_to_log(sony_toc.lead_out_start_msf);
-      }
-      if (single_toc.pointb1 != 0xb1)
-      {
-        memmove(((char *) &single_toc) + 36,
-               ((char *) &single_toc) + 27,
-               res_size - 27);
-        res_size += 9;
-      }
-      if (single_toc.pointb2 != 0xb2)
-      {
-        memmove(((char *) &single_toc) + 45,
-               ((char *) &single_toc) + 36,
-               res_size - 36);
-        res_size += 9;
-      }
-      if (single_toc.pointb3 != 0xb3)
-      {
-        memmove(((char *) &single_toc) + 54,
-               ((char *) &single_toc) + 45,
-               res_size - 45);
-        res_size += 9;
-      }
-      if (single_toc.pointb4 != 0xb4)
-      {
-        memmove(((char *) &single_toc) + 63,
-               ((char *) &single_toc) + 54,
-               res_size - 54);
-        res_size += 9;
-      }
-      if (single_toc.pointc0 != 0xc0)
-      {
-        memmove(((char *) &single_toc) + 72,
-               ((char *) &single_toc) + 63,
-               res_size - 63);
-        res_size += 9;
-      }
-
+                       sony_toc.lead_out_start_msf[0] =
+                           bcd_to_int(single_toc.lead_out_start_msf[0]);
+                       sony_toc.lead_out_start_msf[1] =
+                           bcd_to_int(single_toc.lead_out_start_msf[1]);
+                       sony_toc.lead_out_start_msf[2] =
+                           bcd_to_int(single_toc.lead_out_start_msf[2]);
+                       sony_toc.lead_out_start_lba =
+                           single_toc.lead_out_start_lba =
+                           msf_to_log(sony_toc.lead_out_start_msf);
+
+                       /* For points that do not exist, move the data over them
+                          to the right location. */
+                       if (single_toc.pointb0 != 0xb0) {
+                               memmove(((char *) &single_toc) + 27,
+                                       ((char *) &single_toc) + 18,
+                                       res_size - 18);
+                               res_size += 9;
+                       } else if (res_size > 18) {
+                               sony_toc.lead_out_start_msf[0] =
+                                   bcd_to_int(single_toc.
+                                              max_start_outer_leadout_msf
+                                              [0]);
+                               sony_toc.lead_out_start_msf[1] =
+                                   bcd_to_int(single_toc.
+                                              max_start_outer_leadout_msf
+                                              [1]);
+                               sony_toc.lead_out_start_msf[2] =
+                                   bcd_to_int(single_toc.
+                                              max_start_outer_leadout_msf
+                                              [2]);
+                               sony_toc.lead_out_start_lba =
+                                   msf_to_log(sony_toc.
+                                              lead_out_start_msf);
+                       }
+                       if (single_toc.pointb1 != 0xb1) {
+                               memmove(((char *) &single_toc) + 36,
+                                       ((char *) &single_toc) + 27,
+                                       res_size - 27);
+                               res_size += 9;
+                       }
+                       if (single_toc.pointb2 != 0xb2) {
+                               memmove(((char *) &single_toc) + 45,
+                                       ((char *) &single_toc) + 36,
+                                       res_size - 36);
+                               res_size += 9;
+                       }
+                       if (single_toc.pointb3 != 0xb3) {
+                               memmove(((char *) &single_toc) + 54,
+                                       ((char *) &single_toc) + 45,
+                                       res_size - 45);
+                               res_size += 9;
+                       }
+                       if (single_toc.pointb4 != 0xb4) {
+                               memmove(((char *) &single_toc) + 63,
+                                       ((char *) &single_toc) + 54,
+                                       res_size - 54);
+                               res_size += 9;
+                       }
+                       if (single_toc.pointc0 != 0xc0) {
+                               memmove(((char *) &single_toc) + 72,
+                                       ((char *) &single_toc) + 63,
+                                       res_size - 63);
+                               res_size += 9;
+                       }
 #if DEBUG
-      printk("start track lba %u,  leadout start lba %u\n",
-              single_toc.start_track_lba, single_toc.lead_out_start_lba);
-      { int i;
-        for (i = 0; i < 1 + bcd_to_int(single_toc.last_track_num)
-                          - bcd_to_int(single_toc.first_track_num); i++) {
-          printk("trk %02d: add 0x%01x, con 0x%01x,  track %02d, start min %02d, sec %02d, frame %02d\n",
-                 i, single_toc.tracks[i].address, single_toc.tracks[i].control,
-                 bcd_to_int(single_toc.tracks[i].track),
-                 bcd_to_int(single_toc.tracks[i].track_start_msf[0]),
-                 bcd_to_int(single_toc.tracks[i].track_start_msf[1]),
-                 bcd_to_int(single_toc.tracks[i].track_start_msf[2]));
-          if (mint > bcd_to_int(single_toc.tracks[i].track))
-            mint = bcd_to_int(single_toc.tracks[i].track);
-          if (maxt < bcd_to_int(single_toc.tracks[i].track))
-            maxt = bcd_to_int(single_toc.tracks[i].track);
-        }
-        printk("min track number %d,   max track number %d\n", mint, maxt);
-      }
+                       printk
+                           ("start track lba %u,  leadout start lba %u\n",
+                            single_toc.start_track_lba,
+                            single_toc.lead_out_start_lba);
+                       {
+                               int i;
+                               for (i = 0;
+                                    i <
+                                    1 +
+                                    bcd_to_int(single_toc.last_track_num)
+                                    -
+                                    bcd_to_int(single_toc.
+                                               first_track_num); i++) {
+                                       printk
+                                           ("trk %02d: add 0x%01x, con 0x%01x,  track %02d, start min %02d, sec %02d, frame %02d\n",
+                                            i,
+                                            single_toc.tracks[i].address,
+                                            single_toc.tracks[i].control,
+                                            bcd_to_int(single_toc.
+                                                       tracks[i].track),
+                                            bcd_to_int(single_toc.
+                                                       tracks[i].
+                                                       track_start_msf
+                                                       [0]),
+                                            bcd_to_int(single_toc.
+                                                       tracks[i].
+                                                       track_start_msf
+                                                       [1]),
+                                            bcd_to_int(single_toc.
+                                                       tracks[i].
+                                                       track_start_msf
+                                                       [2]));
+                                       if (mint >
+                                           bcd_to_int(single_toc.
+                                                      tracks[i].track))
+                                               mint =
+                                                   bcd_to_int(single_toc.
+                                                              tracks[i].
+                                                              track);
+                                       if (maxt <
+                                           bcd_to_int(single_toc.
+                                                      tracks[i].track))
+                                               maxt =
+                                                   bcd_to_int(single_toc.
+                                                              tracks[i].
+                                                              track);
+                               }
+                               printk
+                                   ("min track number %d,   max track number %d\n",
+                                    mint, maxt);
+                       }
 #endif
 
-         /* prepare a special table of contents for a CD-I disc. They don't have one. */
-         if (single_toc.disk_type == 0x10 &&
-             single_toc.first_track_num == 2 &&
-             single_toc.last_track_num == 2 /* CD-I */)
-         {
-            sony_toc.tracks[totaltracks].address = 1;
-           sony_toc.tracks[totaltracks].control = 4; /* force data tracks */
-            sony_toc.tracks[totaltracks].track = 1;
-            sony_toc.tracks[totaltracks].track_start_msf[0] = 0;
-            sony_toc.tracks[totaltracks].track_start_msf[1] = 2;
-            sony_toc.tracks[totaltracks].track_start_msf[2] = 0;
-            mint = maxt = 1;
-            totaltracks++;
-         } else
-         /* gather track entries from this session */
-         { int i;
-          for (i = 0; i < 1 + bcd_to_int(single_toc.last_track_num)
-                          - bcd_to_int(single_toc.first_track_num); i++, totaltracks++) {
-             sony_toc.tracks[totaltracks].address = single_toc.tracks[i].address;
-             sony_toc.tracks[totaltracks].control = single_toc.tracks[i].control;
-             sony_toc.tracks[totaltracks].track = bcd_to_int(single_toc.tracks[i].track);
-             sony_toc.tracks[totaltracks].track_start_msf[0] = 
-                  bcd_to_int(single_toc.tracks[i].track_start_msf[0]);
-             sony_toc.tracks[totaltracks].track_start_msf[1] = 
-                  bcd_to_int(single_toc.tracks[i].track_start_msf[1]);
-             sony_toc.tracks[totaltracks].track_start_msf[2] = 
-                  bcd_to_int(single_toc.tracks[i].track_start_msf[2]);
-             if (i == 0)
-               single_toc.start_track_lba = msf_to_log(sony_toc.tracks[totaltracks].track_start_msf);
-             if (mint > sony_toc.tracks[totaltracks].track)
-               mint = sony_toc.tracks[totaltracks].track;
-             if (maxt < sony_toc.tracks[totaltracks].track)
-               maxt = sony_toc.tracks[totaltracks].track;
-           }
-         }
-         sony_toc.first_track_num = mint;
-         sony_toc.last_track_num = maxt;
-         /* Disk type of last session wins. For example:
-            CD-Extra has disk type 0 for the first session, so
-            a dumb HiFi CD player thinks it is a plain audio CD.
-           We are interested in the disk type of the last session,
-            which is 0x20 (XA) for CD-Extra, so we can access the
-            data track ... */
-         sony_toc.disk_type = single_toc.disk_type;
-         sony_toc.sessions = session;
-
-         /* don't believe everything :-) */
-         if (session == 1)
-            single_toc.start_track_lba = 0;
-         sony_toc.start_track_lba = single_toc.start_track_lba;
-
-         if (session > 1 && single_toc.pointb0 == 0xb0 &&
-             sony_toc.lead_out_start_lba == single_toc.lead_out_start_lba)
-        {
-            break;
-         }
-
-         /* Let's not get carried away... */
-         if (session > 40)
-         {
-            printk("cdu31a: too many sessions: %d\n", session);
-            break;
-         }
-         session++;
-      }
-      sony_toc.track_entries = totaltracks;
-      /* add one entry for the LAST track with track number CDROM_LEADOUT */ 
-      sony_toc.tracks[totaltracks].address = single_toc.address2;
-      sony_toc.tracks[totaltracks].control = single_toc.control2;
-      sony_toc.tracks[totaltracks].track = CDROM_LEADOUT;
-      sony_toc.tracks[totaltracks].track_start_msf[0] = 
-             sony_toc.lead_out_start_msf[0];
-      sony_toc.tracks[totaltracks].track_start_msf[1] = 
-             sony_toc.lead_out_start_msf[1];
-      sony_toc.tracks[totaltracks].track_start_msf[2] = 
-             sony_toc.lead_out_start_msf[2];
-
-      sony_toc_read = 1;
+                       /* prepare a special table of contents for a CD-I disc. They don't have one. */
+                       if (single_toc.disk_type == 0x10 &&
+                           single_toc.first_track_num == 2 &&
+                           single_toc.last_track_num == 2 /* CD-I */ ) {
+                               sony_toc.tracks[totaltracks].address = 1;
+                               sony_toc.tracks[totaltracks].control = 4;       /* force data tracks */
+                               sony_toc.tracks[totaltracks].track = 1;
+                               sony_toc.tracks[totaltracks].
+                                   track_start_msf[0] = 0;
+                               sony_toc.tracks[totaltracks].
+                                   track_start_msf[1] = 2;
+                               sony_toc.tracks[totaltracks].
+                                   track_start_msf[2] = 0;
+                               mint = maxt = 1;
+                               totaltracks++;
+                       } else
+                               /* gather track entries from this session */
+                       {
+                               int i;
+                               for (i = 0;
+                                    i <
+                                    1 +
+                                    bcd_to_int(single_toc.last_track_num)
+                                    -
+                                    bcd_to_int(single_toc.
+                                               first_track_num);
+                                    i++, totaltracks++) {
+                                       sony_toc.tracks[totaltracks].
+                                           address =
+                                           single_toc.tracks[i].address;
+                                       sony_toc.tracks[totaltracks].
+                                           control =
+                                           single_toc.tracks[i].control;
+                                       sony_toc.tracks[totaltracks].
+                                           track =
+                                           bcd_to_int(single_toc.
+                                                      tracks[i].track);
+                                       sony_toc.tracks[totaltracks].
+                                           track_start_msf[0] =
+                                           bcd_to_int(single_toc.
+                                                      tracks[i].
+                                                      track_start_msf[0]);
+                                       sony_toc.tracks[totaltracks].
+                                           track_start_msf[1] =
+                                           bcd_to_int(single_toc.
+                                                      tracks[i].
+                                                      track_start_msf[1]);
+                                       sony_toc.tracks[totaltracks].
+                                           track_start_msf[2] =
+                                           bcd_to_int(single_toc.
+                                                      tracks[i].
+                                                      track_start_msf[2]);
+                                       if (i == 0)
+                                               single_toc.
+                                                   start_track_lba =
+                                                   msf_to_log(sony_toc.
+                                                              tracks
+                                                              [totaltracks].
+                                                              track_start_msf);
+                                       if (mint >
+                                           sony_toc.tracks[totaltracks].
+                                           track)
+                                               mint =
+                                                   sony_toc.
+                                                   tracks[totaltracks].
+                                                   track;
+                                       if (maxt <
+                                           sony_toc.tracks[totaltracks].
+                                           track)
+                                               maxt =
+                                                   sony_toc.
+                                                   tracks[totaltracks].
+                                                   track;
+                               }
+                       }
+                       sony_toc.first_track_num = mint;
+                       sony_toc.last_track_num = maxt;
+                       /* Disk type of last session wins. For example:
+                          CD-Extra has disk type 0 for the first session, so
+                          a dumb HiFi CD player thinks it is a plain audio CD.
+                          We are interested in the disk type of the last session,
+                          which is 0x20 (XA) for CD-Extra, so we can access the
+                          data track ... */
+                       sony_toc.disk_type = single_toc.disk_type;
+                       sony_toc.sessions = session;
+
+                       /* don't believe everything :-) */
+                       if (session == 1)
+                               single_toc.start_track_lba = 0;
+                       sony_toc.start_track_lba =
+                           single_toc.start_track_lba;
+
+                       if (session > 1 && single_toc.pointb0 == 0xb0 &&
+                           sony_toc.lead_out_start_lba ==
+                           single_toc.lead_out_start_lba) {
+                               break;
+                       }
+
+                       /* Let's not get carried away... */
+                       if (session > 40) {
+                               printk("cdu31a: too many sessions: %d\n",
+                                      session);
+                               break;
+                       }
+                       session++;
+               }
+               sony_toc.track_entries = totaltracks;
+               /* add one entry for the LAST track with track number CDROM_LEADOUT */
+               sony_toc.tracks[totaltracks].address = single_toc.address2;
+               sony_toc.tracks[totaltracks].control = single_toc.control2;
+               sony_toc.tracks[totaltracks].track = CDROM_LEADOUT;
+               sony_toc.tracks[totaltracks].track_start_msf[0] =
+                   sony_toc.lead_out_start_msf[0];
+               sony_toc.tracks[totaltracks].track_start_msf[1] =
+                   sony_toc.lead_out_start_msf[1];
+               sony_toc.tracks[totaltracks].track_start_msf[2] =
+                   sony_toc.lead_out_start_msf[2];
+
+               sony_toc_read = 1;
 #undef DEBUG
 #if DEBUG
-   printk("Disk session %d, start track: %d, stop track: %d\n",
-         session,
-         single_toc.start_track_lba,
-         single_toc.lead_out_start_lba);
+               printk
+                   ("Disk session %d, start track: %d, stop track: %d\n",
+                    session, single_toc.start_track_lba,
+                    single_toc.lead_out_start_lba);
 #endif
-   }
+       }
 #if DEBUG
-   printk("Leaving sony_get_toc\n");
+       printk("Leaving sony_get_toc\n");
 #endif
 }
 
@@ -2236,74 +2230,76 @@ gettoc_drive_spinning:
  * Uniform cdrom interface function
  * return multisession offset and sector information
  */
-static int scd_get_last_session(struct cdrom_device_info *cdi, 
-                                struct cdrom_multisession *ms_info)
+static int scd_get_last_session(struct cdrom_device_info *cdi,
+                               struct cdrom_multisession *ms_info)
 {
-   if (ms_info == NULL)
-      return 1;
+       if (ms_info == NULL)
+               return 1;
 
-   if (!sony_toc_read)
-      sony_get_toc();
+       if (!sony_toc_read)
+               sony_get_toc();
 
-   ms_info->addr_format = CDROM_LBA;
-   ms_info->addr.lba    = sony_toc.start_track_lba;
-   ms_info->xa_flag     = sony_toc.disk_type == SONY_XA_DISK_TYPE ||
-                          sony_toc.disk_type == 0x10 /* CDI */;
+       ms_info->addr_format = CDROM_LBA;
+       ms_info->addr.lba = sony_toc.start_track_lba;
+       ms_info->xa_flag = sony_toc.disk_type == SONY_XA_DISK_TYPE ||
+           sony_toc.disk_type == 0x10 /* CDI */ ;
 
-   return 0;
+       return 0;
 }
 
 /*
  * Search for a specific track in the table of contents.
  */
-static int
-find_track(int track)
+static int find_track(int track)
 {
-   int i;
+       int i;
 
-   for (i = 0; i <= sony_toc.track_entries; i++)
-   {
-      if (sony_toc.tracks[i].track == track)
-      {
-         return i;
-      }
-   }
+       for (i = 0; i <= sony_toc.track_entries; i++) {
+               if (sony_toc.tracks[i].track == track) {
+                       return i;
+               }
+       }
 
-   return -1;
+       return -1;
 }
 
 
 /*
  * Read the subcode and put it in last_sony_subcode for future use.
  */
-static int
-read_subcode(void)
-{
-   unsigned int res_size;
-
-
-   do_sony_cd_cmd(SONY_REQ_SUBCODE_ADDRESS_CMD,
-                  NULL,
-                  0, 
-                  (unsigned char *) &last_sony_subcode, 
-                  &res_size);
-   if ((res_size < 2) || ((last_sony_subcode.exec_status[0] & 0xf0) == 0x20))
-   {
-      printk("Sony CDROM error %s (read_subcode)\n",
-             translate_error(last_sony_subcode.exec_status[1]));
-      return -EIO;
-   }
-
-   last_sony_subcode.track_num = bcd_to_int(last_sony_subcode.track_num);
-   last_sony_subcode.index_num = bcd_to_int(last_sony_subcode.index_num);
-   last_sony_subcode.abs_msf[0] = bcd_to_int(last_sony_subcode.abs_msf[0]);
-   last_sony_subcode.abs_msf[1] = bcd_to_int(last_sony_subcode.abs_msf[1]);
-   last_sony_subcode.abs_msf[2] = bcd_to_int(last_sony_subcode.abs_msf[2]);
-
-   last_sony_subcode.rel_msf[0] = bcd_to_int(last_sony_subcode.rel_msf[0]);
-   last_sony_subcode.rel_msf[1] = bcd_to_int(last_sony_subcode.rel_msf[1]);
-   last_sony_subcode.rel_msf[2] = bcd_to_int(last_sony_subcode.rel_msf[2]);
-   return 0;
+static int read_subcode(void)
+{
+       unsigned int res_size;
+
+
+       do_sony_cd_cmd(SONY_REQ_SUBCODE_ADDRESS_CMD,
+                      NULL,
+                      0, (unsigned char *) &last_sony_subcode, &res_size);
+       if ((res_size < 2)
+           || ((last_sony_subcode.exec_status[0] & 0xf0) == 0x20)) {
+               printk("Sony CDROM error %s (read_subcode)\n",
+                      translate_error(last_sony_subcode.exec_status[1]));
+               return -EIO;
+       }
+
+       last_sony_subcode.track_num =
+           bcd_to_int(last_sony_subcode.track_num);
+       last_sony_subcode.index_num =
+           bcd_to_int(last_sony_subcode.index_num);
+       last_sony_subcode.abs_msf[0] =
+           bcd_to_int(last_sony_subcode.abs_msf[0]);
+       last_sony_subcode.abs_msf[1] =
+           bcd_to_int(last_sony_subcode.abs_msf[1]);
+       last_sony_subcode.abs_msf[2] =
+           bcd_to_int(last_sony_subcode.abs_msf[2]);
+
+       last_sony_subcode.rel_msf[0] =
+           bcd_to_int(last_sony_subcode.rel_msf[0]);
+       last_sony_subcode.rel_msf[1] =
+           bcd_to_int(last_sony_subcode.rel_msf[1]);
+       last_sony_subcode.rel_msf[2] =
+           bcd_to_int(last_sony_subcode.rel_msf[2]);
+       return 0;
 }
 
 /*
@@ -2313,37 +2309,33 @@ read_subcode(void)
 static int
 scd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
 {
-   unsigned char resbuffer[2 + 14];
-   unsigned char *mcnp = mcn->medium_catalog_number;
-   unsigned char *resp = resbuffer + 3;
-   unsigned int res_size;
-
-   memset(mcn->medium_catalog_number, 0, 14);
-   do_sony_cd_cmd(SONY_REQ_UPC_EAN_CMD,
-                  NULL,
-                  0, 
-                  resbuffer,
-                  &res_size);
-   if ((res_size < 2) || ((resbuffer[0] & 0xf0) == 0x20))
-     ;
-   else {
-     /* packed bcd to single ASCII digits */
-     *mcnp++ = (*resp >> 4)     + '0'; 
-     *mcnp++ = (*resp++ & 0x0f) + '0'; 
-     *mcnp++ = (*resp >> 4)     + '0'; 
-     *mcnp++ = (*resp++ & 0x0f) + '0'; 
-     *mcnp++ = (*resp >> 4)     + '0'; 
-     *mcnp++ = (*resp++ & 0x0f) + '0'; 
-     *mcnp++ = (*resp >> 4)     + '0'; 
-     *mcnp++ = (*resp++ & 0x0f) + '0'; 
-     *mcnp++ = (*resp >> 4)     + '0'; 
-     *mcnp++ = (*resp++ & 0x0f) + '0'; 
-     *mcnp++ = (*resp >> 4)     + '0'; 
-     *mcnp++ = (*resp++ & 0x0f) + '0'; 
-     *mcnp++ = (*resp >> 4)     + '0'; 
-   }
-   *mcnp = '\0';
-   return 0;
+       unsigned char resbuffer[2 + 14];
+       unsigned char *mcnp = mcn->medium_catalog_number;
+       unsigned char *resp = resbuffer + 3;
+       unsigned int res_size;
+
+       memset(mcn->medium_catalog_number, 0, 14);
+       do_sony_cd_cmd(SONY_REQ_UPC_EAN_CMD,
+                      NULL, 0, resbuffer, &res_size);
+       if ((res_size < 2) || ((resbuffer[0] & 0xf0) == 0x20));
+       else {
+               /* packed bcd to single ASCII digits */
+               *mcnp++ = (*resp >> 4) + '0';
+               *mcnp++ = (*resp++ & 0x0f) + '0';
+               *mcnp++ = (*resp >> 4) + '0';
+               *mcnp++ = (*resp++ & 0x0f) + '0';
+               *mcnp++ = (*resp >> 4) + '0';
+               *mcnp++ = (*resp++ & 0x0f) + '0';
+               *mcnp++ = (*resp >> 4) + '0';
+               *mcnp++ = (*resp++ & 0x0f) + '0';
+               *mcnp++ = (*resp >> 4) + '0';
+               *mcnp++ = (*resp++ & 0x0f) + '0';
+               *mcnp++ = (*resp >> 4) + '0';
+               *mcnp++ = (*resp++ & 0x0f) + '0';
+               *mcnp++ = (*resp >> 4) + '0';
+       }
+       *mcnp = '\0';
+       return 0;
 }
 
 
@@ -2354,67 +2346,67 @@ scd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
  * already been stored, just use that.  The ioctl call wants things in decimal
  * (not BCD), so all the conversions are done.
  */
-static int
-sony_get_subchnl_info(struct cdrom_subchnl *schi)
-{
-   /* Get attention stuff */
-   while (handle_sony_cd_attention())
-      ;
-
-   sony_get_toc();
-   if (!sony_toc_read)
-   {
-      return -EIO;
-   }
-
-   switch (sony_audio_status)
-   {
-   case CDROM_AUDIO_NO_STATUS:
-   case CDROM_AUDIO_PLAY:
-      if (read_subcode() < 0)
-      {
-         return -EIO;
-      }
-      break;
-
-   case CDROM_AUDIO_PAUSED:
-   case CDROM_AUDIO_COMPLETED:
-      break;
+static int sony_get_subchnl_info(struct cdrom_subchnl *schi)
+{
+       /* Get attention stuff */
+       while (handle_sony_cd_attention());
+
+       sony_get_toc();
+       if (!sony_toc_read) {
+               return -EIO;
+       }
+
+       switch (sony_audio_status) {
+       case CDROM_AUDIO_NO_STATUS:
+       case CDROM_AUDIO_PLAY:
+               if (read_subcode() < 0) {
+                       return -EIO;
+               }
+               break;
+
+       case CDROM_AUDIO_PAUSED:
+       case CDROM_AUDIO_COMPLETED:
+               break;
 
 #if 0
-   case CDROM_AUDIO_NO_STATUS:
-      schi->cdsc_audiostatus = sony_audio_status;
-      return 0;
-      break;
+       case CDROM_AUDIO_NO_STATUS:
+               schi->cdsc_audiostatus = sony_audio_status;
+               return 0;
+               break;
 #endif
-   case CDROM_AUDIO_INVALID:
-   case CDROM_AUDIO_ERROR:
-   default:
-      return -EIO;
-   }
-
-   schi->cdsc_audiostatus = sony_audio_status;
-   schi->cdsc_adr = last_sony_subcode.address;
-   schi->cdsc_ctrl = last_sony_subcode.control;
-   schi->cdsc_trk = last_sony_subcode.track_num;
-   schi->cdsc_ind = last_sony_subcode.index_num;
-   if (schi->cdsc_format == CDROM_MSF)
-   {
-      schi->cdsc_absaddr.msf.minute = last_sony_subcode.abs_msf[0];
-      schi->cdsc_absaddr.msf.second = last_sony_subcode.abs_msf[1];
-      schi->cdsc_absaddr.msf.frame = last_sony_subcode.abs_msf[2];
-
-      schi->cdsc_reladdr.msf.minute = last_sony_subcode.rel_msf[0];
-      schi->cdsc_reladdr.msf.second = last_sony_subcode.rel_msf[1];
-      schi->cdsc_reladdr.msf.frame = last_sony_subcode.rel_msf[2];
-   }
-   else if (schi->cdsc_format == CDROM_LBA)
-   {
-      schi->cdsc_absaddr.lba = msf_to_log(last_sony_subcode.abs_msf);
-      schi->cdsc_reladdr.lba = msf_to_log(last_sony_subcode.rel_msf);
-   }
-   
-   return 0;
+       case CDROM_AUDIO_INVALID:
+       case CDROM_AUDIO_ERROR:
+       default:
+               return -EIO;
+       }
+
+       schi->cdsc_audiostatus = sony_audio_status;
+       schi->cdsc_adr = last_sony_subcode.address;
+       schi->cdsc_ctrl = last_sony_subcode.control;
+       schi->cdsc_trk = last_sony_subcode.track_num;
+       schi->cdsc_ind = last_sony_subcode.index_num;
+       if (schi->cdsc_format == CDROM_MSF) {
+               schi->cdsc_absaddr.msf.minute =
+                   last_sony_subcode.abs_msf[0];
+               schi->cdsc_absaddr.msf.second =
+                   last_sony_subcode.abs_msf[1];
+               schi->cdsc_absaddr.msf.frame =
+                   last_sony_subcode.abs_msf[2];
+
+               schi->cdsc_reladdr.msf.minute =
+                   last_sony_subcode.rel_msf[0];
+               schi->cdsc_reladdr.msf.second =
+                   last_sony_subcode.rel_msf[1];
+               schi->cdsc_reladdr.msf.frame =
+                   last_sony_subcode.rel_msf[2];
+       } else if (schi->cdsc_format == CDROM_LBA) {
+               schi->cdsc_absaddr.lba =
+                   msf_to_log(last_sony_subcode.abs_msf);
+               schi->cdsc_reladdr.lba =
+                   msf_to_log(last_sony_subcode.rel_msf);
+       }
+
+       return 0;
 }
 
 /* Get audio data from the drive.  This is fairly complex because I
@@ -2422,782 +2414,756 @@ sony_get_subchnl_info(struct cdrom_subchnl *schi)
    then I just look for data.  I need to get the status immediately so
    the switch from audio to data tracks will happen quickly. */
 static void
-read_audio_data(char          *buffer,
-                unsigned char res_reg[],
-                int           *res_size)
-{
-   unsigned int retry_count;
-   int result_read;
-
-
-   res_reg[0] = 0;
-   res_reg[1] = 0;
-   *res_size = 0;
-   result_read = 0;
-
-   /* Wait for the drive to tell us we have something */
-   retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-continue_read_audio_wait:
-   while (time_before(jiffies, retry_count) && !(is_data_ready())
-          && !(is_result_ready() || result_read))
-   {
-      while (handle_sony_cd_attention())
-         ;
-
-      sony_sleep();
-   }
-   if (!(is_data_ready()))
-   {
-      if (is_result_ready() && !result_read)
-      {
-         get_result(res_reg, res_size);
-
-         /* Read block status and continue waiting for data. */
-         if ((res_reg[0] & 0xf0) == 0x50)
-         {
-            result_read = 1;
-            goto continue_read_audio_wait;
-         }
-         /* Invalid data from the drive.  Shut down the operation. */
-         else if ((res_reg[0] & 0xf0) != 0x20)
-         {
-            printk("CDU31A: Got result that should have been error: %d\n",
-                   res_reg[0]);
-            res_reg[0] = 0x20;
-            res_reg[1] = SONY_BAD_DATA_ERR;
-            *res_size = 2;
-         }
-         abort_read();
-      }
-      else
-      {
+read_audio_data(char *buffer, unsigned char res_reg[], int *res_size)
+{
+       unsigned int retry_count;
+       int result_read;
+
+
+       res_reg[0] = 0;
+       res_reg[1] = 0;
+       *res_size = 0;
+       result_read = 0;
+
+       /* Wait for the drive to tell us we have something */
+       retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
+      continue_read_audio_wait:
+       while (time_before(jiffies, retry_count) && !(is_data_ready())
+              && !(is_result_ready() || result_read)) {
+               while (handle_sony_cd_attention());
+
+               sony_sleep();
+       }
+       if (!(is_data_ready())) {
+               if (is_result_ready() && !result_read) {
+                       get_result(res_reg, res_size);
+
+                       /* Read block status and continue waiting for data. */
+                       if ((res_reg[0] & 0xf0) == 0x50) {
+                               result_read = 1;
+                               goto continue_read_audio_wait;
+                       }
+                       /* Invalid data from the drive.  Shut down the operation. */
+                       else if ((res_reg[0] & 0xf0) != 0x20) {
+                               printk
+                                   ("CDU31A: Got result that should have been error: %d\n",
+                                    res_reg[0]);
+                               res_reg[0] = 0x20;
+                               res_reg[1] = SONY_BAD_DATA_ERR;
+                               *res_size = 2;
+                       }
+                       abort_read();
+               } else {
 #if DEBUG
-         printk("CDU31A timeout out %d\n", __LINE__);
+                       printk("CDU31A timeout out %d\n", __LINE__);
 #endif
-         res_reg[0] = 0x20;
-         res_reg[1] = SONY_TIMEOUT_OP_ERR;
-         *res_size = 2;
-         abort_read();
-      }
-   }
-   else
-   {
-      clear_data_ready();
-
-      /* If data block, then get 2340 bytes offset by 12. */
-      if (sony_raw_data_mode)
-      {
-         insb(sony_cd_read_reg, buffer + CD_XA_HEAD, CD_FRAMESIZE_RAW1);
-      }
-      else
-      {
-         /* Audio gets the whole 2352 bytes. */
-         insb(sony_cd_read_reg, buffer, CD_FRAMESIZE_RAW);
-      }
-
-      /* If I haven't already gotten the result, get it now. */
-      if (!result_read)
-      {
-         /* Wait for the drive to tell us we have something */
-         retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-         while (time_before(jiffies, retry_count) && !(is_result_ready()))
-         {
-            while (handle_sony_cd_attention())
-               ;
-
-            sony_sleep();
-         }
-
-         if (!is_result_ready())
-         {
+                       res_reg[0] = 0x20;
+                       res_reg[1] = SONY_TIMEOUT_OP_ERR;
+                       *res_size = 2;
+                       abort_read();
+               }
+       } else {
+               clear_data_ready();
+
+               /* If data block, then get 2340 bytes offset by 12. */
+               if (sony_raw_data_mode) {
+                       insb(sony_cd_read_reg, buffer + CD_XA_HEAD,
+                            CD_FRAMESIZE_RAW1);
+               } else {
+                       /* Audio gets the whole 2352 bytes. */
+                       insb(sony_cd_read_reg, buffer, CD_FRAMESIZE_RAW);
+               }
+
+               /* If I haven't already gotten the result, get it now. */
+               if (!result_read) {
+                       /* Wait for the drive to tell us we have something */
+                       retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
+                       while (time_before(jiffies, retry_count)
+                              && !(is_result_ready())) {
+                               while (handle_sony_cd_attention());
+
+                               sony_sleep();
+                       }
+
+                       if (!is_result_ready()) {
 #if DEBUG
-            printk("CDU31A timeout out %d\n", __LINE__);
+                               printk("CDU31A timeout out %d\n",
+                                      __LINE__);
 #endif
-            res_reg[0] = 0x20;
-            res_reg[1] = SONY_TIMEOUT_OP_ERR;
-            *res_size = 2;
-            abort_read();
-            return;
-         }
-         else
-         {
-            get_result(res_reg, res_size);
-         }
-      }
-
-      if ((res_reg[0] & 0xf0) == 0x50)
-      {
-         if (   (res_reg[0] == SONY_NO_CIRC_ERR_BLK_STAT)
-             || (res_reg[0] == SONY_NO_LECC_ERR_BLK_STAT)
-             || (res_reg[0] == SONY_RECOV_LECC_ERR_BLK_STAT)
-             || (res_reg[0] == SONY_NO_ERR_DETECTION_STAT))
-         {
-            /* Ok, nothing to do. */
-         }
-         else
-         {
-            printk("CDU31A: Data block error: 0x%x\n", res_reg[0]);
-            res_reg[0] = 0x20;
-            res_reg[1] = SONY_BAD_DATA_ERR;
-            *res_size = 2;
-         }
-      }
-      else if ((res_reg[0] & 0xf0) != 0x20)
-      {
-         /* The drive gave me bad status, I don't know what to do.
-            Reset the driver and return an error. */
-         printk("CDU31A: Invalid block status: 0x%x\n", res_reg[0]);
-         restart_on_error();
-         res_reg[0] = 0x20;
-         res_reg[1] = SONY_BAD_DATA_ERR;
-         *res_size = 2;
-      }
-   }
+                               res_reg[0] = 0x20;
+                               res_reg[1] = SONY_TIMEOUT_OP_ERR;
+                               *res_size = 2;
+                               abort_read();
+                               return;
+                       } else {
+                               get_result(res_reg, res_size);
+                       }
+               }
+
+               if ((res_reg[0] & 0xf0) == 0x50) {
+                       if ((res_reg[0] == SONY_NO_CIRC_ERR_BLK_STAT)
+                           || (res_reg[0] == SONY_NO_LECC_ERR_BLK_STAT)
+                           || (res_reg[0] == SONY_RECOV_LECC_ERR_BLK_STAT)
+                           || (res_reg[0] == SONY_NO_ERR_DETECTION_STAT)) {
+                               /* Ok, nothing to do. */
+                       } else {
+                               printk("CDU31A: Data block error: 0x%x\n",
+                                      res_reg[0]);
+                               res_reg[0] = 0x20;
+                               res_reg[1] = SONY_BAD_DATA_ERR;
+                               *res_size = 2;
+                       }
+               } else if ((res_reg[0] & 0xf0) != 0x20) {
+                       /* The drive gave me bad status, I don't know what to do.
+                          Reset the driver and return an error. */
+                       printk("CDU31A: Invalid block status: 0x%x\n",
+                              res_reg[0]);
+                       restart_on_error();
+                       res_reg[0] = 0x20;
+                       res_reg[1] = SONY_BAD_DATA_ERR;
+                       *res_size = 2;
+               }
+       }
 }
 
 /* Perform a raw data read.  This will automatically detect the
    track type and read the proper data (audio or data). */
-static int
-read_audio(struct cdrom_read_audio *ra)
-{
-   int retval;
-   unsigned char params[2];
-   unsigned char res_reg[12];
-   unsigned int res_size;
-   unsigned int cframe;
-   unsigned long flags;
-
-   /* 
-    * Make sure no one else is using the driver; wait for them
-    * to finish if it is so.
-    */
-   save_flags(flags);
-   cli();
-   while (sony_inuse)
-   {
-      interruptible_sleep_on(&sony_wait);
-      if (signal_pending(current))
-      {
-         restore_flags(flags);
-         return -EAGAIN;
-      }
-   }
-   sony_inuse = 1;
-   has_cd_task = current;
-   restore_flags(flags);
-
-   if (!sony_spun_up)
-   {
-     scd_spinup();
-   }
-
-   /* Set the drive to do raw operations. */
-   params[0] = SONY_SD_DECODE_PARAM;
-   params[1] = 0x06 | sony_raw_data_mode;
-   do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                  params,
-                  2,
-                  res_reg,
-                  &res_size);
-   if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
-   {
-      printk("CDU31A: Unable to set decode params: 0x%2.2x\n", res_reg[1]);
-      return -EIO;
-   }
-
-   /* From here down, we have to goto exit_read_audio instead of returning
-      because the drive parameters have to be set back to data before
-      return. */
-
-   retval = 0;
-   /* start_request clears out any readahead data, so it should be safe. */
-   if (start_request(ra->addr.lba, ra->nframes, 1))
-   {
-      retval = -EIO;
-      goto exit_read_audio;
-   }
-
-   /* For every requested frame. */
-   cframe = 0;
-   while (cframe < ra->nframes)
-   {
-      read_audio_data(readahead_buffer, res_reg, &res_size);
-      if ((res_reg[0] & 0xf0) == 0x20)
-      {
-         if (res_reg[1] == SONY_BAD_DATA_ERR)
-         {
-            printk("CDU31A: Data error on audio sector %d\n",
-                   ra->addr.lba + cframe);
-         }
-         else if (res_reg[1] == SONY_ILL_TRACK_R_ERR)
-         {
-            /* Illegal track type, change track types and start over. */
-            sony_raw_data_mode = (sony_raw_data_mode) ? 0 : 1;
-
-            /* Set the drive mode. */
-            params[0] = SONY_SD_DECODE_PARAM;
-            params[1] = 0x06 | sony_raw_data_mode;
-            do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                           params,
-                           2,
-                           res_reg,
-                           &res_size);
-            if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
-            {
-               printk("CDU31A: Unable to set decode params: 0x%2.2x\n", res_reg[1]);
-               retval = -EIO;
-               goto exit_read_audio;
-            }
-
-            /* Restart the request on the current frame. */
-            if (start_request(ra->addr.lba + cframe, ra->nframes - cframe, 1))
-            {
-               retval = -EIO;
-               goto exit_read_audio;
-            }
-
-            /* Don't go back to the top because don't want to get into
-               and infinite loop.  A lot of code gets duplicated, but
-               that's no big deal, I don't guess. */
-            read_audio_data(readahead_buffer, res_reg, &res_size);
-            if ((res_reg[0] & 0xf0) == 0x20)
-            {
-               if (res_reg[1] == SONY_BAD_DATA_ERR)
-               {
-                  printk("CDU31A: Data error on audio sector %d\n",
-                         ra->addr.lba + cframe);
-               }
-               else
-               {
-                  printk("CDU31A: Error reading audio data on sector %d: %s\n",
-                         ra->addr.lba + cframe,
-                         translate_error(res_reg[1]));
-                  retval = -EIO;
-                  goto exit_read_audio;
-               }
-            }
-            else
-            {
-               copy_to_user((char *) (ra->buf + (CD_FRAMESIZE_RAW * cframe)),
-                           (char *) readahead_buffer,
-                           CD_FRAMESIZE_RAW);
-            }
-         }
-         else
-         {
-            printk("CDU31A: Error reading audio data on sector %d: %s\n",
-                   ra->addr.lba + cframe,
-                   translate_error(res_reg[1]));
-            retval = -EIO;
-            goto exit_read_audio;
-         }
-      }
-      else
-      {
-         copy_to_user((char *) (ra->buf + (CD_FRAMESIZE_RAW * cframe)),
-                     (char *) readahead_buffer,
-                     CD_FRAMESIZE_RAW);
-      }
-
-      cframe++;
-   }
-
-   get_result(res_reg, &res_size);
-   if ((res_reg[0] & 0xf0) == 0x20)
-   {
-      printk("CDU31A: Error return from audio read: %s\n",
-             translate_error(res_reg[1]));
-      retval = -EIO;
-      goto exit_read_audio;
-   }
-
-exit_read_audio:
-
-   /* Set the drive mode back to the proper one for the disk. */
-   params[0] = SONY_SD_DECODE_PARAM;
-   if (!sony_xa_mode)
-   {
-      params[1] = 0x0f;
-   }
-   else
-   {
-      params[1] = 0x07;
-   }
-   do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                  params,
-                  2,
-                  res_reg,
-                  &res_size);
-   if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
-   {
-      printk("CDU31A: Unable to reset decode params: 0x%2.2x\n", res_reg[1]);
-      return -EIO;
-   }
-
-   has_cd_task = NULL;
-   sony_inuse = 0;
-   wake_up_interruptible(&sony_wait);
-
-   return(retval);
+static int read_audio(struct cdrom_read_audio *ra)
+{
+       int retval;
+       unsigned char params[2];
+       unsigned char res_reg[12];
+       unsigned int res_size;
+       unsigned int cframe;
+       unsigned long flags;
+
+       /* 
+        * Make sure no one else is using the driver; wait for them
+        * to finish if it is so.
+        */
+       save_flags(flags);
+       cli();
+       while (sony_inuse) {
+               interruptible_sleep_on(&sony_wait);
+               if (signal_pending(current)) {
+                       restore_flags(flags);
+                       return -EAGAIN;
+               }
+       }
+       sony_inuse = 1;
+       has_cd_task = current;
+       restore_flags(flags);
+
+       if (!sony_spun_up) {
+               scd_spinup();
+       }
+
+       /* Set the drive to do raw operations. */
+       params[0] = SONY_SD_DECODE_PARAM;
+       params[1] = 0x06 | sony_raw_data_mode;
+       do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
+                      params, 2, res_reg, &res_size);
+       if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
+               printk("CDU31A: Unable to set decode params: 0x%2.2x\n",
+                      res_reg[1]);
+               return -EIO;
+       }
+
+       /* From here down, we have to goto exit_read_audio instead of returning
+          because the drive parameters have to be set back to data before
+          return. */
+
+       retval = 0;
+       /* start_request clears out any readahead data, so it should be safe. */
+       if (start_request(ra->addr.lba, ra->nframes, 1)) {
+               retval = -EIO;
+               goto exit_read_audio;
+       }
+
+       /* For every requested frame. */
+       cframe = 0;
+       while (cframe < ra->nframes) {
+               read_audio_data(readahead_buffer, res_reg, &res_size);
+               if ((res_reg[0] & 0xf0) == 0x20) {
+                       if (res_reg[1] == SONY_BAD_DATA_ERR) {
+                               printk
+                                   ("CDU31A: Data error on audio sector %d\n",
+                                    ra->addr.lba + cframe);
+                       } else if (res_reg[1] == SONY_ILL_TRACK_R_ERR) {
+                               /* Illegal track type, change track types and start over. */
+                               sony_raw_data_mode =
+                                   (sony_raw_data_mode) ? 0 : 1;
+
+                               /* Set the drive mode. */
+                               params[0] = SONY_SD_DECODE_PARAM;
+                               params[1] = 0x06 | sony_raw_data_mode;
+                               do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
+                                              params,
+                                              2, res_reg, &res_size);
+                               if ((res_size < 2)
+                                   || ((res_reg[0] & 0xf0) == 0x20)) {
+                                       printk
+                                           ("CDU31A: Unable to set decode params: 0x%2.2x\n",
+                                            res_reg[1]);
+                                       retval = -EIO;
+                                       goto exit_read_audio;
+                               }
+
+                               /* Restart the request on the current frame. */
+                               if (start_request
+                                   (ra->addr.lba + cframe,
+                                    ra->nframes - cframe, 1)) {
+                                       retval = -EIO;
+                                       goto exit_read_audio;
+                               }
+
+                               /* Don't go back to the top because don't want to get into
+                                  and infinite loop.  A lot of code gets duplicated, but
+                                  that's no big deal, I don't guess. */
+                               read_audio_data(readahead_buffer, res_reg,
+                                               &res_size);
+                               if ((res_reg[0] & 0xf0) == 0x20) {
+                                       if (res_reg[1] ==
+                                           SONY_BAD_DATA_ERR) {
+                                               printk
+                                                   ("CDU31A: Data error on audio sector %d\n",
+                                                    ra->addr.lba +
+                                                    cframe);
+                                       } else {
+                                               printk
+                                                   ("CDU31A: Error reading audio data on sector %d: %s\n",
+                                                    ra->addr.lba + cframe,
+                                                    translate_error
+                                                    (res_reg[1]));
+                                               retval = -EIO;
+                                               goto exit_read_audio;
+                                       }
+                               } else {
+                                       copy_to_user((char *) (ra->buf +
+                                                              (CD_FRAMESIZE_RAW
+                                                               * cframe)),
+                                                    (char *)
+                                                    readahead_buffer,
+                                                    CD_FRAMESIZE_RAW);
+                               }
+                       } else {
+                               printk
+                                   ("CDU31A: Error reading audio data on sector %d: %s\n",
+                                    ra->addr.lba + cframe,
+                                    translate_error(res_reg[1]));
+                               retval = -EIO;
+                               goto exit_read_audio;
+                       }
+               } else {
+                       copy_to_user((char *) (ra->buf +
+                                              (CD_FRAMESIZE_RAW *
+                                               cframe)),
+                                    (char *) readahead_buffer,
+                                    CD_FRAMESIZE_RAW);
+               }
+
+               cframe++;
+       }
+
+       get_result(res_reg, &res_size);
+       if ((res_reg[0] & 0xf0) == 0x20) {
+               printk("CDU31A: Error return from audio read: %s\n",
+                      translate_error(res_reg[1]));
+               retval = -EIO;
+               goto exit_read_audio;
+       }
+
+      exit_read_audio:
+
+       /* Set the drive mode back to the proper one for the disk. */
+       params[0] = SONY_SD_DECODE_PARAM;
+       if (!sony_xa_mode) {
+               params[1] = 0x0f;
+       } else {
+               params[1] = 0x07;
+       }
+       do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
+                      params, 2, res_reg, &res_size);
+       if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
+               printk("CDU31A: Unable to reset decode params: 0x%2.2x\n",
+                      res_reg[1]);
+               return -EIO;
+       }
+
+       has_cd_task = NULL;
+       sony_inuse = 0;
+       wake_up_interruptible(&sony_wait);
+
+       return (retval);
 }
 
 static int
 do_sony_cd_cmd_chk(const char *name,
-                   unsigned char cmd,
-                   unsigned char *params,
-                   unsigned int num_params,
-                  unsigned char *result_buffer,
-                   unsigned int *result_size)
-{      
-      do_sony_cd_cmd(cmd, params, num_params, result_buffer, result_size);
-      if ((*result_size < 2) || ((result_buffer[0] & 0xf0) == 0x20))
-      {
-         printk("Sony CDROM error %s (CDROM%s)\n", translate_error(result_buffer[1]), name);
-         return -EIO;
-      }
-      return 0;
+                  unsigned char cmd,
+                  unsigned char *params,
+                  unsigned int num_params,
+                  unsigned char *result_buffer, unsigned int *result_size)
+{
+       do_sony_cd_cmd(cmd, params, num_params, result_buffer,
+                      result_size);
+       if ((*result_size < 2) || ((result_buffer[0] & 0xf0) == 0x20)) {
+               printk("Sony CDROM error %s (CDROM%s)\n",
+                      translate_error(result_buffer[1]), name);
+               return -EIO;
+       }
+       return 0;
 }
+
 /*
  * Uniform cdrom interface function
  * open the tray
  */
 static int scd_tray_move(struct cdrom_device_info *cdi, int position)
 {
-  if (position == 1 /* open tray */)
-  {
-    unsigned char res_reg[12];
-    unsigned int res_size;
-
-    do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg, &res_size);
-    do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
-
-    sony_audio_status = CDROM_AUDIO_INVALID;
-    return do_sony_cd_cmd_chk("EJECT",SONY_EJECT_CMD, NULL, 0, res_reg, &res_size);
-  } else {
-    if (0 == scd_spinup())
-      sony_spun_up = 1;
-    return 0;
-  }
+       if (position == 1 /* open tray */ ) {
+               unsigned char res_reg[12];
+               unsigned int res_size;
+
+               do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
+                              &res_size);
+               do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
+                              &res_size);
+
+               sony_audio_status = CDROM_AUDIO_INVALID;
+               return do_sony_cd_cmd_chk("EJECT", SONY_EJECT_CMD, NULL, 0,
+                                         res_reg, &res_size);
+       } else {
+               if (0 == scd_spinup())
+                       sony_spun_up = 1;
+               return 0;
+       }
 }
 
 /*
  * The big ugly ioctl handler.
  */
 static int scd_audio_ioctl(struct cdrom_device_info *cdi,
-          unsigned int  cmd,
-          void * arg)
-{
-   unsigned char res_reg[12];
-   unsigned int res_size;
-   unsigned char params[7];
-   int i;
-
-
-   switch (cmd)
-   {
-   case CDROMSTART:     /* Spin up the drive */
-      return do_sony_cd_cmd_chk("START",SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-      break;
-      
-   case CDROMSTOP:      /* Spin down the drive */
-      do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg, &res_size);
-
-      /*
-       * Spin the drive down, ignoring the error if the disk was
-       * already not spinning.
-       */
-      sony_audio_status = CDROM_AUDIO_NO_STATUS;
-      return do_sony_cd_cmd_chk("STOP",SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
-
-   case CDROMPAUSE:     /* Pause the drive */
-      if(do_sony_cd_cmd_chk("PAUSE", SONY_AUDIO_STOP_CMD, NULL, 0, res_reg, &res_size))
-       return -EIO;
-      /* Get the current position and save it for resuming */
-      if (read_subcode() < 0)
-      {
-         return -EIO;
-      }
-      cur_pos_msf[0] = last_sony_subcode.abs_msf[0];
-      cur_pos_msf[1] = last_sony_subcode.abs_msf[1];
-      cur_pos_msf[2] = last_sony_subcode.abs_msf[2];
-      sony_audio_status = CDROM_AUDIO_PAUSED;
-      return 0;
-      break;
-
-   case CDROMRESUME:    /* Start the drive after being paused */
-      if (sony_audio_status != CDROM_AUDIO_PAUSED)
-      {
-         return -EINVAL;
-      }
-      
-      do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-      
-      /* Start the drive at the saved position. */
-      params[1] = int_to_bcd(cur_pos_msf[0]);
-      params[2] = int_to_bcd(cur_pos_msf[1]);
-      params[3] = int_to_bcd(cur_pos_msf[2]);
-      params[4] = int_to_bcd(final_pos_msf[0]);
-      params[5] = int_to_bcd(final_pos_msf[1]);
-      params[6] = int_to_bcd(final_pos_msf[2]);
-      params[0] = 0x03;
-      if(do_sony_cd_cmd_chk("RESUME",SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg, &res_size)<0)
-       return -EIO;
-      sony_audio_status = CDROM_AUDIO_PLAY;
-      return 0;
-
-   case CDROMPLAYMSF:   /* Play starting at the given MSF address. */
-      do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-      
-      /* The parameters are given in int, must be converted */
-      for (i=1; i<7; i++)
-      {
-         params[i] = int_to_bcd(((unsigned char *)arg)[i-1]);
-      }
-      params[0] = 0x03;
-      if(do_sony_cd_cmd_chk("PLAYMSF",SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg, &res_size)<0)
-       return -EIO;
-      
-      /* Save the final position for pauses and resumes */
-      final_pos_msf[0] = bcd_to_int(params[4]);
-      final_pos_msf[1] = bcd_to_int(params[5]);
-      final_pos_msf[2] = bcd_to_int(params[6]);
-      sony_audio_status = CDROM_AUDIO_PLAY;
-      return 0;
-
-   case CDROMREADTOCHDR:        /* Read the table of contents header */
-      {
-         struct cdrom_tochdr *hdr;
-         
-         sony_get_toc();
-         if (!sony_toc_read)
-         {
-            return -EIO;
-         }
-         
-         hdr = (struct cdrom_tochdr *) arg;
-         hdr->cdth_trk0 = sony_toc.first_track_num;
-         hdr->cdth_trk1 = sony_toc.last_track_num;
-      }
-      return 0;
-
-   case CDROMREADTOCENTRY:      /* Read a given table of contents entry */
-      {
-         struct cdrom_tocentry *entry;
-         int track_idx;
-         unsigned char *msf_val = NULL;
-         
-         sony_get_toc();
-         if (!sony_toc_read)
-         {
-            return -EIO;
-         }
-         
-         entry = (struct cdrom_tocentry *) arg;
-         
-         track_idx = find_track(entry->cdte_track);
-         if (track_idx < 0)
-         {
-            return -EINVAL;
-         }
-            
-         entry->cdte_adr = sony_toc.tracks[track_idx].address;
-         entry->cdte_ctrl = sony_toc.tracks[track_idx].control;
-         msf_val = sony_toc.tracks[track_idx].track_start_msf;
-         
-         /* Logical buffer address or MSF format requested? */
-         if (entry->cdte_format == CDROM_LBA)
-         {
-            entry->cdte_addr.lba = msf_to_log(msf_val);
-         }
-         else if (entry->cdte_format == CDROM_MSF)
-         {
-            entry->cdte_addr.msf.minute = *msf_val;
-            entry->cdte_addr.msf.second = *(msf_val+1);
-            entry->cdte_addr.msf.frame = *(msf_val+2);
-         }
-      }
-      return 0;
-      break;
-
-   case CDROMPLAYTRKIND:     /* Play a track.  This currently ignores index. */
-      {
-         struct cdrom_ti *ti = (struct cdrom_ti *) arg;
-         int track_idx;
-         
-         sony_get_toc();
-         if (!sony_toc_read)
-         {
-            return -EIO;
-         }
-         
-         if (   (ti->cdti_trk0 < sony_toc.first_track_num)
-             || (ti->cdti_trk0 > sony_toc.last_track_num)
-             || (ti->cdti_trk1 < ti->cdti_trk0))
-         {
-            return -EINVAL;
-         }
-         
-         track_idx = find_track(ti->cdti_trk0);
-         if (track_idx < 0)
-         {
-            return -EINVAL;
-         }
-         params[1] = int_to_bcd(sony_toc.tracks[track_idx].track_start_msf[0]);
-         params[2] = int_to_bcd(sony_toc.tracks[track_idx].track_start_msf[1]);
-         params[3] = int_to_bcd(sony_toc.tracks[track_idx].track_start_msf[2]);
-         
-         /*
-          * If we want to stop after the last track, use the lead-out
-          * MSF to do that.
-          */
-         if (ti->cdti_trk1 >= sony_toc.last_track_num)
-         {
-            track_idx = find_track(CDROM_LEADOUT);
-         }
-         else
-         {
-            track_idx = find_track(ti->cdti_trk1+1);
-         }
-         if (track_idx < 0)
-         {
-            return -EINVAL;
-         }
-         params[4] = int_to_bcd(sony_toc.tracks[track_idx].track_start_msf[0]);
-         params[5] = int_to_bcd(sony_toc.tracks[track_idx].track_start_msf[1]);
-         params[6] = int_to_bcd(sony_toc.tracks[track_idx].track_start_msf[2]);
-         params[0] = 0x03;
-         
-         do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-         
-         do_sony_cd_cmd(SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg, &res_size);
-         
-         if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
-         {
-            printk("Params: %x %x %x %x %x %x %x\n", params[0], params[1],
-                   params[2], params[3], params[4], params[5], params[6]);
-            printk("Sony CDROM error %s (CDROMPLAYTRKIND)\n", translate_error(res_reg[1]));
-            return -EIO;
-         }
-         
-         /* Save the final position for pauses and resumes */
-         final_pos_msf[0] = bcd_to_int(params[4]);
-         final_pos_msf[1] = bcd_to_int(params[5]);
-         final_pos_msf[2] = bcd_to_int(params[6]);
-         sony_audio_status = CDROM_AUDIO_PLAY;
-         return 0;
-      }
-     
-   case CDROMVOLCTRL:   /* Volume control.  What volume does this change, anyway? */
-      {
-         struct cdrom_volctrl *volctrl = (struct cdrom_volctrl *) arg;
-         
-         params[0] = SONY_SD_AUDIO_VOLUME;
-         params[1] = volctrl->channel0;
-         params[2] = volctrl->channel1;
-         return do_sony_cd_cmd_chk("VOLCTRL",SONY_SET_DRIVE_PARAM_CMD, params, 3, res_reg, &res_size);
-      }
-   case CDROMSUBCHNL:   /* Get subchannel info */
-      return sony_get_subchnl_info((struct cdrom_subchnl *)arg);
-
-   default:
-      return -EINVAL;
-   }
+                          unsigned int cmd, void *arg)
+{
+       unsigned char res_reg[12];
+       unsigned int res_size;
+       unsigned char params[7];
+       int i;
+
+
+       switch (cmd) {
+       case CDROMSTART:        /* Spin up the drive */
+               return do_sony_cd_cmd_chk("START", SONY_SPIN_UP_CMD, NULL,
+                                         0, res_reg, &res_size);
+               break;
+
+       case CDROMSTOP: /* Spin down the drive */
+               do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
+                              &res_size);
+
+               /*
+                * Spin the drive down, ignoring the error if the disk was
+                * already not spinning.
+                */
+               sony_audio_status = CDROM_AUDIO_NO_STATUS;
+               return do_sony_cd_cmd_chk("STOP", SONY_SPIN_DOWN_CMD, NULL,
+                                         0, res_reg, &res_size);
+
+       case CDROMPAUSE:        /* Pause the drive */
+               if (do_sony_cd_cmd_chk
+                   ("PAUSE", SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
+                    &res_size))
+                       return -EIO;
+               /* Get the current position and save it for resuming */
+               if (read_subcode() < 0) {
+                       return -EIO;
+               }
+               cur_pos_msf[0] = last_sony_subcode.abs_msf[0];
+               cur_pos_msf[1] = last_sony_subcode.abs_msf[1];
+               cur_pos_msf[2] = last_sony_subcode.abs_msf[2];
+               sony_audio_status = CDROM_AUDIO_PAUSED;
+               return 0;
+               break;
+
+       case CDROMRESUME:       /* Start the drive after being paused */
+               if (sony_audio_status != CDROM_AUDIO_PAUSED) {
+                       return -EINVAL;
+               }
+
+               do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
+                              &res_size);
+
+               /* Start the drive at the saved position. */
+               params[1] = int_to_bcd(cur_pos_msf[0]);
+               params[2] = int_to_bcd(cur_pos_msf[1]);
+               params[3] = int_to_bcd(cur_pos_msf[2]);
+               params[4] = int_to_bcd(final_pos_msf[0]);
+               params[5] = int_to_bcd(final_pos_msf[1]);
+               params[6] = int_to_bcd(final_pos_msf[2]);
+               params[0] = 0x03;
+               if (do_sony_cd_cmd_chk
+                   ("RESUME", SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg,
+                    &res_size) < 0)
+                       return -EIO;
+               sony_audio_status = CDROM_AUDIO_PLAY;
+               return 0;
+
+       case CDROMPLAYMSF:      /* Play starting at the given MSF address. */
+               do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
+                              &res_size);
+
+               /* The parameters are given in int, must be converted */
+               for (i = 1; i < 7; i++) {
+                       params[i] =
+                           int_to_bcd(((unsigned char *) arg)[i - 1]);
+               }
+               params[0] = 0x03;
+               if (do_sony_cd_cmd_chk
+                   ("PLAYMSF", SONY_AUDIO_PLAYBACK_CMD, params, 7,
+                    res_reg, &res_size) < 0)
+                       return -EIO;
+
+               /* Save the final position for pauses and resumes */
+               final_pos_msf[0] = bcd_to_int(params[4]);
+               final_pos_msf[1] = bcd_to_int(params[5]);
+               final_pos_msf[2] = bcd_to_int(params[6]);
+               sony_audio_status = CDROM_AUDIO_PLAY;
+               return 0;
+
+       case CDROMREADTOCHDR:   /* Read the table of contents header */
+               {
+                       struct cdrom_tochdr *hdr;
+
+                       sony_get_toc();
+                       if (!sony_toc_read) {
+                               return -EIO;
+                       }
+
+                       hdr = (struct cdrom_tochdr *) arg;
+                       hdr->cdth_trk0 = sony_toc.first_track_num;
+                       hdr->cdth_trk1 = sony_toc.last_track_num;
+               }
+               return 0;
+
+       case CDROMREADTOCENTRY: /* Read a given table of contents entry */
+               {
+                       struct cdrom_tocentry *entry;
+                       int track_idx;
+                       unsigned char *msf_val = NULL;
+
+                       sony_get_toc();
+                       if (!sony_toc_read) {
+                               return -EIO;
+                       }
+
+                       entry = (struct cdrom_tocentry *) arg;
+
+                       track_idx = find_track(entry->cdte_track);
+                       if (track_idx < 0) {
+                               return -EINVAL;
+                       }
+
+                       entry->cdte_adr =
+                           sony_toc.tracks[track_idx].address;
+                       entry->cdte_ctrl =
+                           sony_toc.tracks[track_idx].control;
+                       msf_val =
+                           sony_toc.tracks[track_idx].track_start_msf;
+
+                       /* Logical buffer address or MSF format requested? */
+                       if (entry->cdte_format == CDROM_LBA) {
+                               entry->cdte_addr.lba = msf_to_log(msf_val);
+                       } else if (entry->cdte_format == CDROM_MSF) {
+                               entry->cdte_addr.msf.minute = *msf_val;
+                               entry->cdte_addr.msf.second =
+                                   *(msf_val + 1);
+                               entry->cdte_addr.msf.frame =
+                                   *(msf_val + 2);
+                       }
+               }
+               return 0;
+               break;
+
+       case CDROMPLAYTRKIND:   /* Play a track.  This currently ignores index. */
+               {
+                       struct cdrom_ti *ti = (struct cdrom_ti *) arg;
+                       int track_idx;
+
+                       sony_get_toc();
+                       if (!sony_toc_read) {
+                               return -EIO;
+                       }
+
+                       if ((ti->cdti_trk0 < sony_toc.first_track_num)
+                           || (ti->cdti_trk0 > sony_toc.last_track_num)
+                           || (ti->cdti_trk1 < ti->cdti_trk0)) {
+                               return -EINVAL;
+                       }
+
+                       track_idx = find_track(ti->cdti_trk0);
+                       if (track_idx < 0) {
+                               return -EINVAL;
+                       }
+                       params[1] =
+                           int_to_bcd(sony_toc.tracks[track_idx].
+                                      track_start_msf[0]);
+                       params[2] =
+                           int_to_bcd(sony_toc.tracks[track_idx].
+                                      track_start_msf[1]);
+                       params[3] =
+                           int_to_bcd(sony_toc.tracks[track_idx].
+                                      track_start_msf[2]);
+
+                       /*
+                        * If we want to stop after the last track, use the lead-out
+                        * MSF to do that.
+                        */
+                       if (ti->cdti_trk1 >= sony_toc.last_track_num) {
+                               track_idx = find_track(CDROM_LEADOUT);
+                       } else {
+                               track_idx = find_track(ti->cdti_trk1 + 1);
+                       }
+                       if (track_idx < 0) {
+                               return -EINVAL;
+                       }
+                       params[4] =
+                           int_to_bcd(sony_toc.tracks[track_idx].
+                                      track_start_msf[0]);
+                       params[5] =
+                           int_to_bcd(sony_toc.tracks[track_idx].
+                                      track_start_msf[1]);
+                       params[6] =
+                           int_to_bcd(sony_toc.tracks[track_idx].
+                                      track_start_msf[2]);
+                       params[0] = 0x03;
+
+                       do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
+                                      &res_size);
+
+                       do_sony_cd_cmd(SONY_AUDIO_PLAYBACK_CMD, params, 7,
+                                      res_reg, &res_size);
+
+                       if ((res_size < 2)
+                           || ((res_reg[0] & 0xf0) == 0x20)) {
+                               printk("Params: %x %x %x %x %x %x %x\n",
+                                      params[0], params[1], params[2],
+                                      params[3], params[4], params[5],
+                                      params[6]);
+                               printk
+                                   ("Sony CDROM error %s (CDROMPLAYTRKIND)\n",
+                                    translate_error(res_reg[1]));
+                               return -EIO;
+                       }
+
+                       /* Save the final position for pauses and resumes */
+                       final_pos_msf[0] = bcd_to_int(params[4]);
+                       final_pos_msf[1] = bcd_to_int(params[5]);
+                       final_pos_msf[2] = bcd_to_int(params[6]);
+                       sony_audio_status = CDROM_AUDIO_PLAY;
+                       return 0;
+               }
+
+       case CDROMVOLCTRL:      /* Volume control.  What volume does this change, anyway? */
+               {
+                       struct cdrom_volctrl *volctrl =
+                           (struct cdrom_volctrl *) arg;
+
+                       params[0] = SONY_SD_AUDIO_VOLUME;
+                       params[1] = volctrl->channel0;
+                       params[2] = volctrl->channel1;
+                       return do_sony_cd_cmd_chk("VOLCTRL",
+                                                 SONY_SET_DRIVE_PARAM_CMD,
+                                                 params, 3, res_reg,
+                                                 &res_size);
+               }
+       case CDROMSUBCHNL:      /* Get subchannel info */
+               return sony_get_subchnl_info((struct cdrom_subchnl *) arg);
+
+       default:
+               return -EINVAL;
+       }
 }
 
 static int scd_dev_ioctl(struct cdrom_device_info *cdi,
-          unsigned int  cmd,
-          unsigned long arg)
-{
-   int i;
-
-   switch (cmd)
-   {
-   case CDROMREADAUDIO:      /* Read 2352 byte audio tracks and 2340 byte
-                                raw data tracks. */
-      {
-         struct cdrom_read_audio ra;
-
-
-         sony_get_toc();
-         if (!sony_toc_read)
-         {
-               return -EIO;
-         }
-
-        if(copy_from_user(&ra, (char *) arg, sizeof(ra)))
-               return -EFAULT;
-
-         if (ra.nframes == 0)
-         {
-               return 0;
-         }
-
-         i=verify_area(VERIFY_WRITE, ra.buf, CD_FRAMESIZE_RAW * ra.nframes);
-         if(i<0)
-               return i;
-
-         if (ra.addr_format == CDROM_LBA)
-         {
-            if (   (ra.addr.lba >= sony_toc.lead_out_start_lba)
-                || (ra.addr.lba + ra.nframes >= sony_toc.lead_out_start_lba))
-            {
-               return -EINVAL;
-            }
-         }
-         else if (ra.addr_format == CDROM_MSF)
-         {
-            if (   (ra.addr.msf.minute >= 75)
-                || (ra.addr.msf.second >= 60)
-                || (ra.addr.msf.frame >= 75))
-            {
-               return -EINVAL;
-            }
-
-            ra.addr.lba = (  (ra.addr.msf.minute * 4500)
-                           + (ra.addr.msf.second * 75)
-                           + ra.addr.msf.frame);
-            if (   (ra.addr.lba >= sony_toc.lead_out_start_lba)
-                || (ra.addr.lba + ra.nframes >= sony_toc.lead_out_start_lba))
-            {
-               return -EINVAL;
-            }
-
-            /* I know, this can go negative on an unsigned.  However,
-               the first thing done to the data is to add this value,
-               so this should compensate and allow direct msf access. */
-            ra.addr.lba -= LOG_START_OFFSET;
-         }
-         else
-         {
-            return -EINVAL;
-         }
-
-         return(read_audio(&ra));
-      }
-      return 0;
-      break;
-
-   default:
-      return -EINVAL;
-   }
+                        unsigned int cmd, unsigned long arg)
+{
+       int i;
+
+       switch (cmd) {
+       case CDROMREADAUDIO:    /* Read 2352 byte audio tracks and 2340 byte
+                                  raw data tracks. */
+               {
+                       struct cdrom_read_audio ra;
+
+
+                       sony_get_toc();
+                       if (!sony_toc_read) {
+                               return -EIO;
+                       }
+
+                       if (copy_from_user(&ra, (char *) arg, sizeof(ra)))
+                               return -EFAULT;
+
+                       if (ra.nframes == 0) {
+                               return 0;
+                       }
+
+                       i = verify_area(VERIFY_WRITE, ra.buf,
+                                       CD_FRAMESIZE_RAW * ra.nframes);
+                       if (i < 0)
+                               return i;
+
+                       if (ra.addr_format == CDROM_LBA) {
+                               if ((ra.addr.lba >=
+                                    sony_toc.lead_out_start_lba)
+                                   || (ra.addr.lba + ra.nframes >=
+                                       sony_toc.lead_out_start_lba)) {
+                                       return -EINVAL;
+                               }
+                       } else if (ra.addr_format == CDROM_MSF) {
+                               if ((ra.addr.msf.minute >= 75)
+                                   || (ra.addr.msf.second >= 60)
+                                   || (ra.addr.msf.frame >= 75)) {
+                                       return -EINVAL;
+                               }
+
+                               ra.addr.lba = ((ra.addr.msf.minute * 4500)
+                                              + (ra.addr.msf.second * 75)
+                                              + ra.addr.msf.frame);
+                               if ((ra.addr.lba >=
+                                    sony_toc.lead_out_start_lba)
+                                   || (ra.addr.lba + ra.nframes >=
+                                       sony_toc.lead_out_start_lba)) {
+                                       return -EINVAL;
+                               }
+
+                               /* I know, this can go negative on an unsigned.  However,
+                                  the first thing done to the data is to add this value,
+                                  so this should compensate and allow direct msf access. */
+                               ra.addr.lba -= LOG_START_OFFSET;
+                       } else {
+                               return -EINVAL;
+                       }
+
+                       return (read_audio(&ra));
+               }
+               return 0;
+               break;
+
+       default:
+               return -EINVAL;
+       }
 }
 
 static int scd_spinup(void)
 {
-   unsigned char res_reg[12];
-   unsigned int res_size;
-   int num_spin_ups;
-
-   num_spin_ups = 0;
-
-respinup_on_open:
-   do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-
-   /* The drive sometimes returns error 0.  I don't know why, but ignore
-      it.  It seems to mean the drive has already done the operation. */
-   if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0)))
-   {
-      printk("Sony CDROM %s error (scd_open, spin up)\n", translate_error(res_reg[1]));
-      return 1;
-   }
-      
-   do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, &res_size);
-
-   /* The drive sometimes returns error 0.  I don't know why, but ignore
-      it.  It seems to mean the drive has already done the operation. */
-   if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0)))
-   {
-      /* If the drive is already playing, it's ok.  */
-      if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR) || (res_reg[1] == 0))
-      {
-         return 0;
-      }
-
-      /* If the drive says it is not spun up (even though we just did it!)
-         then retry the operation at least a few times. */
-      if (   (res_reg[1] == SONY_NOT_SPIN_ERR)
-          && (num_spin_ups < MAX_CDU31A_RETRIES))
-      {
-         num_spin_ups++;
-         goto respinup_on_open;
-      }
-
-      printk("Sony CDROM error %s (scd_open, read toc)\n", translate_error(res_reg[1]));
-      do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
-      return 1;  
-   }
-   return 0;
+       unsigned char res_reg[12];
+       unsigned int res_size;
+       int num_spin_ups;
+
+       num_spin_ups = 0;
+
+      respinup_on_open:
+       do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
+
+       /* The drive sometimes returns error 0.  I don't know why, but ignore
+          it.  It seems to mean the drive has already done the operation. */
+       if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
+               printk("Sony CDROM %s error (scd_open, spin up)\n",
+                      translate_error(res_reg[1]));
+               return 1;
+       }
+
+       do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, &res_size);
+
+       /* The drive sometimes returns error 0.  I don't know why, but ignore
+          it.  It seems to mean the drive has already done the operation. */
+       if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
+               /* If the drive is already playing, it's ok.  */
+               if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR)
+                   || (res_reg[1] == 0)) {
+                       return 0;
+               }
+
+               /* If the drive says it is not spun up (even though we just did it!)
+                  then retry the operation at least a few times. */
+               if ((res_reg[1] == SONY_NOT_SPIN_ERR)
+                   && (num_spin_ups < MAX_CDU31A_RETRIES)) {
+                       num_spin_ups++;
+                       goto respinup_on_open;
+               }
+
+               printk("Sony CDROM error %s (scd_open, read toc)\n",
+                      translate_error(res_reg[1]));
+               do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
+                              &res_size);
+               return 1;
+       }
+       return 0;
 }
 
 /*
  * Open the drive for operations.  Spin the drive up and read the table of
  * contents if these have not already been done.
  */
-static int
-scd_open(struct cdrom_device_info *cdi, int openmode)
-{
-   unsigned char res_reg[12];
-   unsigned int res_size;
-   unsigned char params[2];
-
-   MOD_INC_USE_COUNT;
-   if (sony_usage == 0)
-   {
-      if (scd_spinup() != 0) {
-         MOD_DEC_USE_COUNT;
-         return -EIO;
-      }
-      sony_get_toc();
-      if (!sony_toc_read)
-      {
-         do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
-         MOD_DEC_USE_COUNT;
-         return -EIO;
-      }
-
-      /* For XA on the CDU31A only, we have to do special reads.
-         The CDU33A handles XA automagically. */
-      /* if (   (sony_toc.disk_type == SONY_XA_DISK_TYPE) */
-      if (   (sony_toc.disk_type != 0x00)
-          && (!is_double_speed))
-      {
-         params[0] = SONY_SD_DECODE_PARAM;
-         params[1] = 0x07;
-         do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                        params,
-                        2,
-                        res_reg,
-                        &res_size);
-         if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
-         {
-            printk("CDU31A: Unable to set XA params: 0x%2.2x\n", res_reg[1]);
-         }
-         sony_xa_mode = 1;
-      }
-      /* A non-XA disk.  Set the parms back if necessary. */
-      else if (sony_xa_mode)
-      {
-         params[0] = SONY_SD_DECODE_PARAM;
-         params[1] = 0x0f;
-         do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
-                        params,
-                        2,
-                        res_reg,
-                        &res_size);
-         if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
-         {
-            printk("CDU31A: Unable to reset XA params: 0x%2.2x\n", res_reg[1]);
-         }
-         sony_xa_mode = 0;
-      }
-
-      sony_spun_up = 1;
-   }
-
-   sony_usage++;
-
-   return 0;
+static int scd_open(struct cdrom_device_info *cdi, int openmode)
+{
+       unsigned char res_reg[12];
+       unsigned int res_size;
+       unsigned char params[2];
+
+       MOD_INC_USE_COUNT;
+       if (sony_usage == 0) {
+               if (scd_spinup() != 0) {
+                       MOD_DEC_USE_COUNT;
+                       return -EIO;
+               }
+               sony_get_toc();
+               if (!sony_toc_read) {
+                       do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0,
+                                      res_reg, &res_size);
+                       MOD_DEC_USE_COUNT;
+                       return -EIO;
+               }
+
+               /* For XA on the CDU31A only, we have to do special reads.
+                  The CDU33A handles XA automagically. */
+               /* if (   (sony_toc.disk_type == SONY_XA_DISK_TYPE) */
+               if ((sony_toc.disk_type != 0x00)
+                   && (!is_double_speed)) {
+                       params[0] = SONY_SD_DECODE_PARAM;
+                       params[1] = 0x07;
+                       do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
+                                      params, 2, res_reg, &res_size);
+                       if ((res_size < 2)
+                           || ((res_reg[0] & 0xf0) == 0x20)) {
+                               printk
+                                   ("CDU31A: Unable to set XA params: 0x%2.2x\n",
+                                    res_reg[1]);
+                       }
+                       sony_xa_mode = 1;
+               }
+               /* A non-XA disk.  Set the parms back if necessary. */
+               else if (sony_xa_mode) {
+                       params[0] = SONY_SD_DECODE_PARAM;
+                       params[1] = 0x0f;
+                       do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
+                                      params, 2, res_reg, &res_size);
+                       if ((res_size < 2)
+                           || ((res_reg[0] & 0xf0) == 0x20)) {
+                               printk
+                                   ("CDU31A: Unable to reset XA params: 0x%2.2x\n",
+                                    res_reg[1]);
+                       }
+                       sony_xa_mode = 0;
+               }
+
+               sony_spun_up = 1;
+       }
+
+       sony_usage++;
+
+       return 0;
 }
 
 
@@ -3205,114 +3171,109 @@ scd_open(struct cdrom_device_info *cdi, int openmode)
  * Close the drive.  Spin it down if no task is using it.  The spin
  * down will fail if playing audio, so audio play is OK.
  */
-static void
-scd_release(struct cdrom_device_info *cdi)
+static void scd_release(struct cdrom_device_info *cdi)
 {
-   if (sony_usage == 1)
-   {
-      unsigned char res_reg[12];
-      unsigned int  res_size;
+       if (sony_usage == 1) {
+               unsigned char res_reg[12];
+               unsigned int res_size;
 
-      do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
+               do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
+                              &res_size);
 
-      sony_spun_up = 0;
-   }
-   sony_usage--;
-   MOD_DEC_USE_COUNT;
+               sony_spun_up = 0;
+       }
+       sony_usage--;
+       MOD_DEC_USE_COUNT;
 }
 
 static struct cdrom_device_ops scd_dops = {
-       open:                   scd_open,
-       release:                scd_release,
-       drive_status:           scd_drive_status,
-       media_changed:          scd_media_changed,
-       tray_move:              scd_tray_move,
-       lock_door:              scd_lock_door,
-       select_speed:           scd_select_speed,
-       get_last_session:       scd_get_last_session,
-       get_mcn:                scd_get_mcn,
-       reset:                  scd_reset,
-       audio_ioctl:            scd_audio_ioctl,
-       dev_ioctl:              scd_dev_ioctl,
-       capability:             CDC_OPEN_TRAY | CDC_CLOSE_TRAY | CDC_LOCK |
-                               CDC_SELECT_SPEED | CDC_MULTI_SESSION | 
-                               CDC_MULTI_SESSION | CDC_MCN |
-                               CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO |
-                               CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS,
-       n_minors:               1,
+       open:scd_open,
+       release:scd_release,
+       drive_status:scd_drive_status,
+       media_changed:scd_media_changed,
+       tray_move:scd_tray_move,
+       lock_door:scd_lock_door,
+       select_speed:scd_select_speed,
+       get_last_session:scd_get_last_session,
+       get_mcn:scd_get_mcn,
+       reset:scd_reset,
+       audio_ioctl:scd_audio_ioctl,
+       dev_ioctl:scd_dev_ioctl,
+       capability:CDC_OPEN_TRAY | CDC_CLOSE_TRAY | CDC_LOCK |
+           CDC_SELECT_SPEED | CDC_MULTI_SESSION |
+           CDC_MULTI_SESSION | CDC_MCN |
+           CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO |
+           CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS,
+       n_minors:1,
 };
 
 static struct cdrom_device_info scd_info = {
-       ops:            &scd_dops,
-       speed:          2,
-       capacity:       1,
-       name:           "cdu31a"
+       ops:&scd_dops,
+       speed:2,
+       capacity:1,
+       name:"cdu31a"
 };
 
 /* The different types of disc loading mechanisms supported */
-static const char *load_mech[] __initdata = { "caddy", "tray", "pop-up", "unknown" };
+static char *load_mech[] __initdata =
+    { "caddy", "tray", "pop-up", "unknown" };
 
-static void __init 
+static void __init
 get_drive_configuration(unsigned short base_io,
-                        unsigned char res_reg[],
-                        unsigned int *res_size)
-{
-   int retry_count;
-
-
-   /* Set the base address */
-   cdu31a_port = base_io;
-
-   /* Set up all the register locations */
-   sony_cd_cmd_reg = cdu31a_port + SONY_CMD_REG_OFFSET;
-   sony_cd_param_reg = cdu31a_port + SONY_PARAM_REG_OFFSET;
-   sony_cd_write_reg = cdu31a_port + SONY_WRITE_REG_OFFSET;
-   sony_cd_control_reg = cdu31a_port + SONY_CONTROL_REG_OFFSET;
-   sony_cd_status_reg = cdu31a_port + SONY_STATUS_REG_OFFSET;
-   sony_cd_result_reg = cdu31a_port + SONY_RESULT_REG_OFFSET;
-   sony_cd_read_reg = cdu31a_port + SONY_READ_REG_OFFSET;
-   sony_cd_fifost_reg = cdu31a_port + SONY_FIFOST_REG_OFFSET;
-
-   /*
-    * Check to see if anything exists at the status register location.
-    * I don't know if this is a good way to check, but it seems to work
-    * ok for me.
-    */
-   if (read_status_register() != 0xff)
-   {
-      /*
-       * Reset the drive and wait for attention from it (to say it's reset).
-       * If you don't wait, the next operation will probably fail.
-       */
-      reset_drive();
-      retry_count = jiffies + SONY_RESET_TIMEOUT;
-      while (time_before(jiffies, retry_count) && (!is_attention()))
-      {
-         sony_sleep();
-      }
+                       unsigned char res_reg[], unsigned int *res_size)
+{
+       int retry_count;
+
+
+       /* Set the base address */
+       cdu31a_port = base_io;
+
+       /* Set up all the register locations */
+       sony_cd_cmd_reg = cdu31a_port + SONY_CMD_REG_OFFSET;
+       sony_cd_param_reg = cdu31a_port + SONY_PARAM_REG_OFFSET;
+       sony_cd_write_reg = cdu31a_port + SONY_WRITE_REG_OFFSET;
+       sony_cd_control_reg = cdu31a_port + SONY_CONTROL_REG_OFFSET;
+       sony_cd_status_reg = cdu31a_port + SONY_STATUS_REG_OFFSET;
+       sony_cd_result_reg = cdu31a_port + SONY_RESULT_REG_OFFSET;
+       sony_cd_read_reg = cdu31a_port + SONY_READ_REG_OFFSET;
+       sony_cd_fifost_reg = cdu31a_port + SONY_FIFOST_REG_OFFSET;
+
+       /*
+        * Check to see if anything exists at the status register location.
+        * I don't know if this is a good way to check, but it seems to work
+        * ok for me.
+        */
+       if (read_status_register() != 0xff) {
+               /*
+                * Reset the drive and wait for attention from it (to say it's reset).
+                * If you don't wait, the next operation will probably fail.
+                */
+               reset_drive();
+               retry_count = jiffies + SONY_RESET_TIMEOUT;
+               while (time_before(jiffies, retry_count)
+                      && (!is_attention())) {
+                       sony_sleep();
+               }
 
 #if 0
-      /* If attention is never seen probably not a CDU31a present */
-      if (!is_attention())
-      {
-         res_reg[0] = 0x20;
-         return;
-      }
+               /* If attention is never seen probably not a CDU31a present */
+               if (!is_attention()) {
+                       res_reg[0] = 0x20;
+                       return;
+               }
 #endif
 
-      /*
-       * Get the drive configuration.
-       */
-      do_sony_cd_cmd(SONY_REQ_DRIVE_CONFIG_CMD,
-                     NULL,
-                     0,
-                     (unsigned char *) res_reg,
-                     res_size);
-      return;
-   }
-
-   /* Return an error */
-   res_reg[0] = 0x20;
+               /*
+                * Get the drive configuration.
+                */
+               do_sony_cd_cmd(SONY_REQ_DRIVE_CONFIG_CMD,
+                              NULL,
+                              0, (unsigned char *) res_reg, res_size);
+               return;
+       }
+
+       /* Return an error */
+       res_reg[0] = 0x20;
 }
 
 #ifndef MODULE
@@ -3321,33 +3282,28 @@ get_drive_configuration(unsigned short base_io,
  
  */
 
-static int __init cdu31a_setup(char *strings)       
-{
-    int ints[4];
-    
-    (void)get_options(strings, ARRAY_SIZE(ints), ints);
-
-   if (ints[0] > 0)
-   {
-      cdu31a_port = ints[1];
-   }
-   if (ints[0] > 1)
-   {
-      cdu31a_irq = ints[2];
-   }
-   if ((strings != NULL) && (*strings != '\0'))
-   {
-      if (strcmp(strings, "PAS") == 0)
-      {
-        sony_pas_init = 1;
-      }
-      else
-      {
-        printk("CDU31A: Unknown interface type: %s\n", strings);
-      }
-   }
-   
-   return 1;
+static int __init cdu31a_setup(char *strings)
+{
+       int ints[4];
+
+       (void) get_options(strings, ARRAY_SIZE(ints), ints);
+
+       if (ints[0] > 0) {
+               cdu31a_port = ints[1];
+       }
+       if (ints[0] > 1) {
+               cdu31a_irq = ints[2];
+       }
+       if ((strings != NULL) && (*strings != '\0')) {
+               if (strcmp(strings, "PAS") == 0) {
+                       sony_pas_init = 1;
+               } else {
+                       printk("CDU31A: Unknown interface type: %s\n",
+                              strings);
+               }
+       }
+
+       return 1;
 }
 
 __setup("cdu31a=", cdu31a_setup);
@@ -3359,223 +3315,204 @@ static int cdu31a_block_size;
 /*
  * Initialize the driver.
  */
-int __init 
-cdu31a_init(void)
-{
-   struct s_sony_drive_config drive_config;
-   unsigned int res_size;
-   char msg[255];
-   char buf[40];
-   int i;
-   int drive_found;
-   int tmp_irq;
-
-
-   /*
-    * According to Alex Freed (freed@europa.orion.adobe.com), this is
-    * required for the Fusion CD-16 package.  If the sound driver is
-    * loaded, it should work fine, but just in case...
-    *
-    * The following turn on the CD-ROM interface for a Fusion CD-16.
-    */
-   if (sony_pas_init)
-   {
-      outb(0xbc, 0x9a01);
-      outb(0xe2, 0x9a01);
-   }
-
-   drive_found = 0;
-
-   /* Setting the base I/O address to 0xffff will disable it. */
-   if (cdu31a_port == 0xffff)
-   {
-   }
-   else if (cdu31a_port != 0)
-   {
-      tmp_irq = cdu31a_irq; /* Need IRQ 0 because we can't sleep here. */
-      cdu31a_irq = 0;
-
-      get_drive_configuration(cdu31a_port,
-                             drive_config.exec_status,
-                             &res_size);
-      if ((res_size > 2) && ((drive_config.exec_status[0] & 0xf0) == 0x00))
-      {
-        drive_found = 1;
-      }
-
-      cdu31a_irq = tmp_irq;
-   }
-   else
-   {
-      cdu31a_irq = 0;
-      i = 0;
-      while (   (cdu31a_addresses[i].base != 0)
-            && (!drive_found))
-      {
-        if (check_region(cdu31a_addresses[i].base, 4)) {
-           i++;
-           continue;
-        }
-        get_drive_configuration(cdu31a_addresses[i].base,
-                                drive_config.exec_status,
-                                &res_size);
-        if ((res_size > 2) && ((drive_config.exec_status[0] & 0xf0) == 0x00))
-        {
-           drive_found = 1;
-           cdu31a_irq = cdu31a_addresses[i].int_num;
-        }
-        else
-        {
-           i++;
-        }
-      }
-   }
-
-   if (drive_found)
-   {
-      int deficiency=0;
-
-      request_region(cdu31a_port, 4,"cdu31a");
-      
-      if (devfs_register_blkdev(MAJOR_NR,"cdu31a",&cdrom_fops))
-      {
-        printk("Unable to get major %d for CDU-31a\n", MAJOR_NR);
-         goto errout2;
-      }
-
-      if (SONY_HWC_DOUBLE_SPEED(drive_config))
-      {
-        is_double_speed = 1;
-      }
-
-      tmp_irq = cdu31a_irq; /* Need IRQ 0 because we can't sleep here. */
-      cdu31a_irq = 0;
-
-      set_drive_params(sony_speed);
-
-      cdu31a_irq = tmp_irq;
-      
-      if (cdu31a_irq > 0)
-      {
-        if (request_irq(cdu31a_irq, cdu31a_interrupt, SA_INTERRUPT, "cdu31a", NULL))
-        {
-           printk("Unable to grab IRQ%d for the CDU31A driver\n", cdu31a_irq);
-           cdu31a_irq = 0;
-        }
-      }
-      
-      sprintf(msg, "Sony I/F CDROM : %8.8s %16.16s %8.8s\n",
-            drive_config.vendor_id,
-            drive_config.product_id,
-            drive_config.product_rev_level);
-      sprintf(buf, "  Capabilities: %s",
-            load_mech[SONY_HWC_GET_LOAD_MECH(drive_config)]);
-      strcat(msg, buf);
-      if (SONY_HWC_AUDIO_PLAYBACK(drive_config))
-      {
-         strcat(msg, ", audio");
-      } else
-        deficiency |= CDC_PLAY_AUDIO;
-      if (SONY_HWC_EJECT(drive_config))
-      {
-         strcat(msg, ", eject");
-      } else
-        deficiency |= CDC_OPEN_TRAY;
-      if (SONY_HWC_LED_SUPPORT(drive_config))
-      {
-         strcat(msg, ", LED");
-      }
-      if (SONY_HWC_ELECTRIC_VOLUME(drive_config))
-      {
-         strcat(msg, ", elec. Vol");
-      }
-      if (SONY_HWC_ELECTRIC_VOLUME_CTL(drive_config))
-      {
-         strcat(msg, ", sep. Vol");
-      }
-      if (is_double_speed)
-      {
-         strcat(msg, ", double speed");
-      } else
-        deficiency |= CDC_SELECT_SPEED;
-      if (cdu31a_irq > 0)
-      {
-        sprintf(buf, ", irq %d", cdu31a_irq);
-         strcat(msg, buf);
-      }
-      strcat(msg, "\n");
-
-      is_a_cdu31a = strcmp("CD-ROM CDU31A", drive_config.product_id) == 0;
-
-      blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
-      read_ahead[MAJOR_NR] = CDU31A_READAHEAD;
-      cdu31a_block_size = 1024; /* 1kB default block size */
-      /* use 'mount -o block=2048' */
-      blksize_size[MAJOR_NR] = &cdu31a_block_size;
-      
-      init_timer(&cdu31a_abort_timer);
-      cdu31a_abort_timer.function = handle_abort_timeout;
-
-      scd_info.dev = MKDEV(MAJOR_NR,0);
-      scd_info.mask = deficiency;
-      strncpy(scd_info.name, "cdu31a", sizeof(scd_info.name));
-
-      if (register_cdrom(&scd_info))
-      {
-         goto errout0;
-      }
-   }
-
-
-   disk_changed = 1;
-   
-   if (drive_found)
-   {
-      return(0);
-   }
-   else
-   {
-      goto errout3;
-   }
-errout0:
-   printk("Unable to register CDU-31a with Uniform cdrom driver\n");
-   blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-   if (devfs_unregister_blkdev(MAJOR_NR, "cdu31a"))    
-   {
-      printk("Can't unregister block device for cdu31a\n");
-   }
-errout2:
-   release_region(cdu31a_port,4);
-errout3:
-   return -EIO;
-}
-
-
-void __exit
-cdu31a_exit(void)
-{
-   if (unregister_cdrom(&scd_info))    
-   {
-      printk("Can't unregister cdu31a from Uniform cdrom driver\n");
-      return;
-   }
-   if ((devfs_unregister_blkdev(MAJOR_NR, "cdu31a") == -EINVAL))    
-   {
-      printk("Can't unregister cdu31a\n");
-      return;
-   }
-
-   blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-
-   if (cdu31a_irq > 0)
-      free_irq(cdu31a_irq, NULL);
-
-   release_region(cdu31a_port,4);
-   printk(KERN_INFO "cdu31a module released.\n");
-}   
+int __init cdu31a_init(void)
+{
+       struct s_sony_drive_config drive_config;
+       unsigned int res_size;
+       char msg[255];
+       char buf[40];
+       int i;
+       int drive_found;
+       int tmp_irq;
+
+
+       /*
+        * According to Alex Freed (freed@europa.orion.adobe.com), this is
+        * required for the Fusion CD-16 package.  If the sound driver is
+        * loaded, it should work fine, but just in case...
+        *
+        * The following turn on the CD-ROM interface for a Fusion CD-16.
+        */
+       if (sony_pas_init) {
+               outb(0xbc, 0x9a01);
+               outb(0xe2, 0x9a01);
+       }
+
+       drive_found = 0;
+
+       /* Setting the base I/O address to 0xffff will disable it. */
+       if (cdu31a_port == 0xffff) {
+       } else if (cdu31a_port != 0) {
+               tmp_irq = cdu31a_irq;   /* Need IRQ 0 because we can't sleep here. */
+               cdu31a_irq = 0;
+
+               get_drive_configuration(cdu31a_port,
+                                       drive_config.exec_status,
+                                       &res_size);
+               if ((res_size > 2)
+                   && ((drive_config.exec_status[0] & 0xf0) == 0x00)) {
+                       drive_found = 1;
+               }
+
+               cdu31a_irq = tmp_irq;
+       } else {
+               cdu31a_irq = 0;
+               i = 0;
+               while ((cdu31a_addresses[i].base != 0)
+                      && (!drive_found)) {
+                       if (check_region(cdu31a_addresses[i].base, 4)) {
+                               i++;
+                               continue;
+                       }
+                       get_drive_configuration(cdu31a_addresses[i].base,
+                                               drive_config.exec_status,
+                                               &res_size);
+                       if ((res_size > 2)
+                           && ((drive_config.exec_status[0] & 0xf0) ==
+                               0x00)) {
+                               drive_found = 1;
+                               cdu31a_irq = cdu31a_addresses[i].int_num;
+                       } else {
+                               i++;
+                       }
+               }
+       }
+
+       if (drive_found) {
+               int deficiency = 0;
+
+               request_region(cdu31a_port, 4, "cdu31a");
+
+               if (devfs_register_blkdev(MAJOR_NR, "cdu31a", &cdrom_fops)) {
+                       printk("Unable to get major %d for CDU-31a\n",
+                              MAJOR_NR);
+                       goto errout2;
+               }
+
+               if (SONY_HWC_DOUBLE_SPEED(drive_config)) {
+                       is_double_speed = 1;
+               }
+
+               tmp_irq = cdu31a_irq;   /* Need IRQ 0 because we can't sleep here. */
+               cdu31a_irq = 0;
+
+               set_drive_params(sony_speed);
+
+               cdu31a_irq = tmp_irq;
+
+               if (cdu31a_irq > 0) {
+                       if (request_irq
+                           (cdu31a_irq, cdu31a_interrupt, SA_INTERRUPT,
+                            "cdu31a", NULL)) {
+                               printk
+                                   ("Unable to grab IRQ%d for the CDU31A driver\n",
+                                    cdu31a_irq);
+                               cdu31a_irq = 0;
+                       }
+               }
+
+               sprintf(msg, "Sony I/F CDROM : %8.8s %16.16s %8.8s\n",
+                       drive_config.vendor_id,
+                       drive_config.product_id,
+                       drive_config.product_rev_level);
+               sprintf(buf, "  Capabilities: %s",
+                       load_mech[SONY_HWC_GET_LOAD_MECH(drive_config)]);
+               strcat(msg, buf);
+               if (SONY_HWC_AUDIO_PLAYBACK(drive_config)) {
+                       strcat(msg, ", audio");
+               } else
+                       deficiency |= CDC_PLAY_AUDIO;
+               if (SONY_HWC_EJECT(drive_config)) {
+                       strcat(msg, ", eject");
+               } else
+                       deficiency |= CDC_OPEN_TRAY;
+               if (SONY_HWC_LED_SUPPORT(drive_config)) {
+                       strcat(msg, ", LED");
+               }
+               if (SONY_HWC_ELECTRIC_VOLUME(drive_config)) {
+                       strcat(msg, ", elec. Vol");
+               }
+               if (SONY_HWC_ELECTRIC_VOLUME_CTL(drive_config)) {
+                       strcat(msg, ", sep. Vol");
+               }
+               if (is_double_speed) {
+                       strcat(msg, ", double speed");
+               } else
+                       deficiency |= CDC_SELECT_SPEED;
+               if (cdu31a_irq > 0) {
+                       sprintf(buf, ", irq %d", cdu31a_irq);
+                       strcat(msg, buf);
+               }
+               strcat(msg, "\n");
+
+               is_a_cdu31a =
+                   strcmp("CD-ROM CDU31A", drive_config.product_id) == 0;
+
+               blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR),
+                              DEVICE_REQUEST);
+               read_ahead[MAJOR_NR] = CDU31A_READAHEAD;
+               cdu31a_block_size = 1024;       /* 1kB default block size */
+               /* use 'mount -o block=2048' */
+               blksize_size[MAJOR_NR] = &cdu31a_block_size;
+
+               init_timer(&cdu31a_abort_timer);
+               cdu31a_abort_timer.function = handle_abort_timeout;
+
+               scd_info.dev = MKDEV(MAJOR_NR, 0);
+               scd_info.mask = deficiency;
+               strncpy(scd_info.name, "cdu31a", sizeof(scd_info.name));
+
+               if (register_cdrom(&scd_info)) {
+                       goto errout0;
+               }
+       }
+
+
+       disk_changed = 1;
+
+       if (drive_found) {
+               return (0);
+       } else {
+               goto errout3;
+       }
+      errout0:
+       printk("Unable to register CDU-31a with Uniform cdrom driver\n");
+       blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+       if (devfs_unregister_blkdev(MAJOR_NR, "cdu31a")) {
+               printk("Can't unregister block device for cdu31a\n");
+       }
+      errout2:
+       release_region(cdu31a_port, 4);
+      errout3:
+       return -EIO;
+}
+
+
+void __exit cdu31a_exit(void)
+{
+       if (unregister_cdrom(&scd_info)) {
+               printk
+                   ("Can't unregister cdu31a from Uniform cdrom driver\n");
+               return;
+       }
+       if ((devfs_unregister_blkdev(MAJOR_NR, "cdu31a") == -EINVAL)) {
+               printk("Can't unregister cdu31a\n");
+               return;
+       }
+
+       blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+
+       if (cdu31a_irq > 0)
+               free_irq(cdu31a_irq, NULL);
+
+       release_region(cdu31a_port, 4);
+       printk(KERN_INFO "cdu31a module released.\n");
+}
 
 #ifdef MODULE
 module_init(cdu31a_init);
 #endif
 module_exit(cdu31a_exit);
 
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
index ab8963fbb332cba64d0d18e89b3be250b10926b2..da12f4727816bb098515cca459db0a5778b41a4f 100644 (file)
@@ -178,7 +178,7 @@ History:
  * David van Leeuwen, david@tm.tno.nl.  */
 #define REVISION "$Revision: 1.5 $"
 
-#include <linux/module.h>      
+#include <linux/module.h>
 
 #include <linux/errno.h>       /* These include what we really need */
 #include <linux/delay.h>
@@ -211,16 +211,19 @@ History:
    address and interrupt request. It can be overridden by the boot 
    parameter `auto'.
 */
-static int auto_probe=1;       /* Yes, why not? */
+static int auto_probe = 1;     /* Yes, why not? */
 
 static int cm206_base = CM206_BASE;
-static int cm206_irq = CM206_IRQ; 
-static int cm206[2] = {0,0};   /* for compatible `insmod' parameter passing */
+static int cm206_irq = CM206_IRQ;
+#ifdef MODULE
+static int cm206[2] = { 0, 0 };        /* for compatible `insmod' parameter passing */
+#endif
 
 MODULE_PARM(cm206_base, "i");  /* base */
 MODULE_PARM(cm206_irq, "i");   /* irq */
 MODULE_PARM(cm206, "1-2i");    /* base,irq or irq,base */
 MODULE_PARM(auto_probe, "i");  /* auto probe base and irq */
+MODULE_LICENSE("GPL");
 
 #define POLLOOP 100            /* milliseconds */
 #define READ_AHEAD 1           /* defines private buffer, waste! */
@@ -233,7 +236,7 @@ MODULE_PARM(auto_probe, "i");       /* auto probe base and irq */
 #define LINUX_BLOCK_SIZE 512   /* WHERE is this defined? */
 #define RAW_SECTOR_SIZE 2352   /* ok, is also defined in cdrom.h */
 #define ISO_SECTOR_SIZE 2048
-#define BLOCKS_ISO (ISO_SECTOR_SIZE/LINUX_BLOCK_SIZE) /* 4 */
+#define BLOCKS_ISO (ISO_SECTOR_SIZE/LINUX_BLOCK_SIZE)  /* 4 */
 #define CD_SYNC_HEAD 16                /* CD_SYNC + CD_HEAD */
 
 #ifdef STATISTICS              /* keep track of errors in counters */
@@ -254,88 +257,91 @@ MODULE_PARM(auto_probe, "i");     /* auto probe base and irq */
 typedef unsigned char uch;     /* 8-bits */
 typedef unsigned short ush;    /* 16-bits */
 
-struct toc_struct            /* private copy of Table of Contents */
-  uch track, fsm[3], q0;
+struct toc_struct {            /* private copy of Table of Contents */
+       uch track, fsm[3], q0;
 };
 
 static int cm206_blocksizes[1] = { 2048 };
 
 struct cm206_struct {
-  volatile ush intr_ds;                /* data status read on last interrupt */
-  volatile ush intr_ls;                /* uart line status read on last interrupt*/
-  volatile uch ur[UR_SIZE];    /* uart receive buffer fifo */
-  volatile uch ur_w, ur_r;     /* write/read buffer index */
-  volatile uch dsb, cc;         /* drive status byte and condition (error) code */
-  int command;                 /* command to be written to the uart */
-  int openfiles;
-  ush sector[READ_AHEAD*RAW_SECTOR_SIZE/2]; /* buffered cd-sector */
-  int sector_first, sector_last; /* range of these sectors */
-  wait_queue_head_t uart;      /* wait queues for interrupt */
-  wait_queue_head_t data;
-  struct timer_list timer;     /* time-out */
-  char timed_out;
-  signed char max_sectors;     /* number of sectors that fit in adapter mem */
-  char wait_back;              /* we're waiting for a background-read */
-  char background;             /* is a read going on in the background? */
-  int adapter_first;           /* if so, that's the starting sector */
-  int adapter_last;
-  char fifo_overflowed;
-  uch disc_status[7];          /* result of get_disc_status command */
+       volatile ush intr_ds;   /* data status read on last interrupt */
+       volatile ush intr_ls;   /* uart line status read on last interrupt */
+       volatile uch ur[UR_SIZE];       /* uart receive buffer fifo */
+       volatile uch ur_w, ur_r;        /* write/read buffer index */
+       volatile uch dsb, cc;   /* drive status byte and condition (error) code */
+       int command;            /* command to be written to the uart */
+       int openfiles;
+       ush sector[READ_AHEAD * RAW_SECTOR_SIZE / 2];   /* buffered cd-sector */
+       int sector_first, sector_last;  /* range of these sectors */
+       wait_queue_head_t uart; /* wait queues for interrupt */
+       wait_queue_head_t data;
+       struct timer_list timer;        /* time-out */
+       char timed_out;
+       signed char max_sectors;        /* number of sectors that fit in adapter mem */
+       char wait_back;         /* we're waiting for a background-read */
+       char background;        /* is a read going on in the background? */
+       int adapter_first;      /* if so, that's the starting sector */
+       int adapter_last;
+       char fifo_overflowed;
+       uch disc_status[7];     /* result of get_disc_status command */
 #ifdef STATISTICS
-  int stats[NR_STATS];
-  int last_stat[NR_STATS];     /* `time' at which stat was stat */
-  int stat_counter;
-#endif  
-  struct toc_struct toc[101];  /* The whole table of contents + lead-out */
-  uch q[10];                   /* Last read q-channel info */
-  uch audio_status[5];         /* last read position on pause */
-  uch media_changed;           /* record if media changed */
+       int stats[NR_STATS];
+       int last_stat[NR_STATS];        /* `time' at which stat was stat */
+       int stat_counter;
+#endif
+       struct toc_struct toc[101];     /* The whole table of contents + lead-out */
+       uch q[10];              /* Last read q-channel info */
+       uch audio_status[5];    /* last read position on pause */
+       uch media_changed;      /* record if media changed */
 };
 
 #define DISC_STATUS cd->disc_status[0]
 #define FIRST_TRACK cd->disc_status[1]
 #define LAST_TRACK cd->disc_status[2]
-#define PAUSED cd->audio_status[0] /* misuse this memory byte! */
+#define PAUSED cd->audio_status[0]     /* misuse this memory byte! */
 #define PLAY_TO cd->toc[0]     /* toc[0] records end-time in play */
 
-static struct cm206_struct * cd; /* the main memory structure */
+static struct cm206_struct *cd;        /* the main memory structure */
 
 /* First, we define some polling functions. These are actually
    only being used in the initialization. */
 
 void send_command_polled(int command)
 {
-  int loop=POLLOOP;
-  while (!(inw(r_line_status) & ls_transmitter_buffer_empty) && loop>0) {
-    mdelay(1);         /* one millisec delay */
-    --loop;
-  }
-  outw(command, r_uart_transmit);
+       int loop = POLLOOP;
+       while (!(inw(r_line_status) & ls_transmitter_buffer_empty)
+              && loop > 0) {
+               mdelay(1);      /* one millisec delay */
+               --loop;
+       }
+       outw(command, r_uart_transmit);
 }
 
 uch receive_echo_polled(void)
 {
-  int loop=POLLOOP;
-  while (!(inw(r_line_status) & ls_receive_buffer_full) && loop>0) {
-    mdelay(1);
-    --loop;
-  }
-  return ((uch) inw(r_uart_receive));
+       int loop = POLLOOP;
+       while (!(inw(r_line_status) & ls_receive_buffer_full) && loop > 0) {
+               mdelay(1);
+               --loop;
+       }
+       return ((uch) inw(r_uart_receive));
 }
 
 uch send_receive_polled(int command)
 {
-  send_command_polled(command);
-  return receive_echo_polled();
+       send_command_polled(command);
+       return receive_echo_polled();
 }
 
-inline void clear_ur(void) {
-  if (cd->ur_r != cd->ur_w) {
-    debug(("Deleting bytes from fifo:"));
-    for(;cd->ur_r != cd->ur_w; cd->ur_r++, cd->ur_r %= UR_SIZE)
-      debug((" 0x%x", cd->ur[cd->ur_r]));
-    debug(("\n"));
-  }
+inline void clear_ur(void)
+{
+       if (cd->ur_r != cd->ur_w) {
+               debug(("Deleting bytes from fifo:"));
+               for (; cd->ur_r != cd->ur_w;
+                    cd->ur_r++, cd->ur_r %= UR_SIZE)
+                       debug((" 0x%x", cd->ur[cd->ur_r]));
+               debug(("\n"));
+       }
 }
 
 /* The interrupt handler. When the cm260 generates an interrupt, very
@@ -351,252 +357,269 @@ inline void clear_ur(void) {
    as there seems so reason for this to happen.
 */
 
-static void cm206_interrupt(int sig, void *dev_id, struct pt_regs * regs) 
+static void cm206_interrupt(int sig, void *dev_id, struct pt_regs *regs)
 /* you rang? */
 {
-  volatile ush fool;
-  cd->intr_ds = inw(r_data_status); /* resets data_ready, data_error,
-                                      crc_error, sync_error, toc_ready 
-                                      interrupts */
-  cd->intr_ls = inw(r_line_status); /* resets overrun bit */
-  debug(("Intr, 0x%x 0x%x, %d\n", cd->intr_ds, cd->intr_ls, cd->background));
-  if (cd->intr_ls & ls_attention) stats(attention);
-  /* receive buffer full? */
-  if (cd->intr_ls & ls_receive_buffer_full) {  
-    cd->ur[cd->ur_w] = inb(r_uart_receive); /* get order right! */
-    cd->intr_ls = inw(r_line_status); /* resets rbf interrupt */
-    debug(("receiving #%d: 0x%x\n", cd->ur_w, cd->ur[cd->ur_w]));
-    cd->ur_w++; cd->ur_w %= UR_SIZE;
-    if (cd->ur_w == cd->ur_r) debug(("cd->ur overflow!\n"));
-    if (waitqueue_active(&cd->uart) && cd->background < 2) { 
-      del_timer(&cd->timer);
-      wake_up_interruptible(&cd->uart);
-    }
-  }
-  /* data ready in fifo? */
-  else if (cd->intr_ds & ds_data_ready) { 
-    if (cd->background) ++cd->adapter_last;
-    if (waitqueue_active(&cd->data) && (cd->wait_back || !cd->background)) {
-      del_timer(&cd->timer);
-      wake_up_interruptible(&cd->data);
-    }
-    stats(data_ready);
-  }
-  /* ready to issue a write command? */
-  else if (cd->command && cd->intr_ls & ls_transmitter_buffer_empty) {
-    outw(dc_normal | (inw(r_data_status) & 0x7f), r_data_control);
-    outw(cd->command, r_uart_transmit);
-    cd->command=0;
-    if (!cd->background) wake_up_interruptible(&cd->uart);
-  }
-  /* now treat errors (at least, identify them for debugging) */
-  else if (cd->intr_ds & ds_fifo_overflow) {
-    debug(("Fifo overflow at sectors 0x%x\n", cd->sector_first));
-    fool = inw(r_fifo_output_buffer);  /* de-assert the interrupt */
-    cd->fifo_overflowed=1;     /* signal one word less should be read */
-    stats(fifo_overflow);
-  }
-  else if (cd->intr_ds & ds_data_error) {
-    debug(("Data error at sector 0x%x\n", cd->sector_first));
-    stats(data_error);
-  }
-  else if (cd->intr_ds & ds_crc_error) {
-    debug(("CRC error at sector 0x%x\n", cd->sector_first));
-    stats(crc_error);
-  }
-  else if (cd->intr_ds & ds_sync_error) {
-    debug(("Sync at sector 0x%x\n", cd->sector_first));
-    stats(sync_error);
-  }
-  else if (cd->intr_ds & ds_toc_ready) {
-    /* do something appropriate */
-  }
-  /* couldn't see why this interrupt, maybe due to init */
-  else {                       
-    outw(dc_normal | READ_AHEAD, r_data_control);
-    stats(lost_intr);
-  }
-  if (cd->background && (cd->adapter_last-cd->adapter_first == cd->max_sectors
-                        || cd->fifo_overflowed))
-    mark_bh(CM206_BH); /* issue a stop read command */
-  stats(interrupt);
+       volatile ush fool;
+       cd->intr_ds = inw(r_data_status);       /* resets data_ready, data_error,
+                                                  crc_error, sync_error, toc_ready 
+                                                  interrupts */
+       cd->intr_ls = inw(r_line_status);       /* resets overrun bit */
+       debug(("Intr, 0x%x 0x%x, %d\n", cd->intr_ds, cd->intr_ls,
+              cd->background));
+       if (cd->intr_ls & ls_attention)
+               stats(attention);
+       /* receive buffer full? */
+       if (cd->intr_ls & ls_receive_buffer_full) {
+               cd->ur[cd->ur_w] = inb(r_uart_receive); /* get order right! */
+               cd->intr_ls = inw(r_line_status);       /* resets rbf interrupt */
+               debug(("receiving #%d: 0x%x\n", cd->ur_w,
+                      cd->ur[cd->ur_w]));
+               cd->ur_w++;
+               cd->ur_w %= UR_SIZE;
+               if (cd->ur_w == cd->ur_r)
+                       debug(("cd->ur overflow!\n"));
+               if (waitqueue_active(&cd->uart) && cd->background < 2) {
+                       del_timer(&cd->timer);
+                       wake_up_interruptible(&cd->uart);
+               }
+       }
+       /* data ready in fifo? */
+       else if (cd->intr_ds & ds_data_ready) {
+               if (cd->background)
+                       ++cd->adapter_last;
+               if (waitqueue_active(&cd->data)
+                   && (cd->wait_back || !cd->background)) {
+                       del_timer(&cd->timer);
+                       wake_up_interruptible(&cd->data);
+               }
+               stats(data_ready);
+       }
+       /* ready to issue a write command? */
+       else if (cd->command && cd->intr_ls & ls_transmitter_buffer_empty) {
+               outw(dc_normal | (inw(r_data_status) & 0x7f),
+                    r_data_control);
+               outw(cd->command, r_uart_transmit);
+               cd->command = 0;
+               if (!cd->background)
+                       wake_up_interruptible(&cd->uart);
+       }
+       /* now treat errors (at least, identify them for debugging) */
+       else if (cd->intr_ds & ds_fifo_overflow) {
+               debug(("Fifo overflow at sectors 0x%x\n",
+                      cd->sector_first));
+               fool = inw(r_fifo_output_buffer);       /* de-assert the interrupt */
+               cd->fifo_overflowed = 1;        /* signal one word less should be read */
+               stats(fifo_overflow);
+       } else if (cd->intr_ds & ds_data_error) {
+               debug(("Data error at sector 0x%x\n", cd->sector_first));
+               stats(data_error);
+       } else if (cd->intr_ds & ds_crc_error) {
+               debug(("CRC error at sector 0x%x\n", cd->sector_first));
+               stats(crc_error);
+       } else if (cd->intr_ds & ds_sync_error) {
+               debug(("Sync at sector 0x%x\n", cd->sector_first));
+               stats(sync_error);
+       } else if (cd->intr_ds & ds_toc_ready) {
+               /* do something appropriate */
+       }
+       /* couldn't see why this interrupt, maybe due to init */
+       else {
+               outw(dc_normal | READ_AHEAD, r_data_control);
+               stats(lost_intr);
+       }
+       if (cd->background
+           && (cd->adapter_last - cd->adapter_first == cd->max_sectors
+               || cd->fifo_overflowed))
+               mark_bh(CM206_BH);      /* issue a stop read command */
+       stats(interrupt);
 }
 
 /* we have put the address of the wait queue in who */
 void cm206_timeout(unsigned long who)
 {
-  cd->timed_out = 1;
-  debug(("Timing out\n"));
-  wake_up_interruptible((wait_queue_head_t *)who);
+       cd->timed_out = 1;
+       debug(("Timing out\n"));
+       wake_up_interruptible((wait_queue_head_t *) who);
 }
 
 /* This function returns 1 if a timeout occurred, 0 if an interrupt
    happened */
-int sleep_or_timeout(wait_queue_head_t *wait, int timeout)
+int sleep_or_timeout(wait_queue_head_t * wait, int timeout)
 {
-  cd->timed_out=0;
-  cd->timer.data=(unsigned long) wait;
-  cd->timer.expires = jiffies + timeout;
-  add_timer(&cd->timer);
-  debug(("going to sleep\n"));
-  interruptible_sleep_on(wait);
-  del_timer(&cd->timer);
-  if (cd->timed_out) {
-    cd->timed_out = 0;
-    return 1;
-  }
-  else return 0;
+       cd->timed_out = 0;
+       cd->timer.data = (unsigned long) wait;
+       cd->timer.expires = jiffies + timeout;
+       add_timer(&cd->timer);
+       debug(("going to sleep\n"));
+       interruptible_sleep_on(wait);
+       del_timer(&cd->timer);
+       if (cd->timed_out) {
+               cd->timed_out = 0;
+               return 1;
+       } else
+               return 0;
 }
 
-void cm206_delay(int nr_jiffies) 
+void cm206_delay(int nr_jiffies)
 {
-  DECLARE_WAIT_QUEUE_HEAD(wait);
-  sleep_or_timeout(&wait, nr_jiffies);
+       DECLARE_WAIT_QUEUE_HEAD(wait);
+       sleep_or_timeout(&wait, nr_jiffies);
 }
 
 void send_command(int command)
 {
-  debug(("Sending 0x%x\n", command));
-  if (!(inw(r_line_status) & ls_transmitter_buffer_empty)) {
-    cd->command = command;
-    cli();                     /* don't interrupt before sleep */
-    outw(dc_mask_sync_error | dc_no_stop_on_error | 
-        (inw(r_data_status) & 0x7f), r_data_control);
-    /* interrupt routine sends command */
-    if (sleep_or_timeout(&cd->uart, UART_TIMEOUT)) {
-      debug(("Time out on write-buffer\n"));
-      stats(write_timeout);
-      outw(command, r_uart_transmit);
-    }
-    debug(("Write commmand delayed\n"));
-  }
-  else outw(command, r_uart_transmit);
+       debug(("Sending 0x%x\n", command));
+       if (!(inw(r_line_status) & ls_transmitter_buffer_empty)) {
+               cd->command = command;
+               cli();          /* don't interrupt before sleep */
+               outw(dc_mask_sync_error | dc_no_stop_on_error |
+                    (inw(r_data_status) & 0x7f), r_data_control);
+               /* interrupt routine sends command */
+               if (sleep_or_timeout(&cd->uart, UART_TIMEOUT)) {
+                       debug(("Time out on write-buffer\n"));
+                       stats(write_timeout);
+                       outw(command, r_uart_transmit);
+               }
+               debug(("Write commmand delayed\n"));
+       } else
+               outw(command, r_uart_transmit);
 }
 
 uch receive_byte(int timeout)
 {
-  uch ret;
-  cli();
-  debug(("cli\n"));
-  ret = cd->ur[cd->ur_r];
-  if (cd->ur_r != cd->ur_w) {
-    sti();
-    debug(("returning #%d: 0x%x\n", cd->ur_r, cd->ur[cd->ur_r]));
-    cd->ur_r++; cd->ur_r %= UR_SIZE;
-    return ret;
-  } 
-  else if (sleep_or_timeout(&cd->uart, timeout)) { /* does sti() */
-    debug(("Time out on receive-buffer\n"));
+       uch ret;
+       cli();
+       debug(("cli\n"));
+       ret = cd->ur[cd->ur_r];
+       if (cd->ur_r != cd->ur_w) {
+               sti();
+               debug(("returning #%d: 0x%x\n", cd->ur_r,
+                      cd->ur[cd->ur_r]));
+               cd->ur_r++;
+               cd->ur_r %= UR_SIZE;
+               return ret;
+       } else if (sleep_or_timeout(&cd->uart, timeout)) {      /* does sti() */
+               debug(("Time out on receive-buffer\n"));
 #ifdef STATISTICS
-    if (timeout==UART_TIMEOUT) stats(receive_timeout) /* no `;'! */
-    else stats(dsb_timeout);
+               if (timeout == UART_TIMEOUT)
+                       stats(receive_timeout)  /* no `;'! */
+                           else
+                       stats(dsb_timeout);
 #endif
-    return 0xda;
-  }
-  ret = cd->ur[cd->ur_r];  
-  debug(("slept; returning #%d: 0x%x\n", cd->ur_r, cd->ur[cd->ur_r]));
-  cd->ur_r++; cd->ur_r %= UR_SIZE;
-  return ret;
+               return 0xda;
+       }
+       ret = cd->ur[cd->ur_r];
+       debug(("slept; returning #%d: 0x%x\n", cd->ur_r,
+              cd->ur[cd->ur_r]));
+       cd->ur_r++;
+       cd->ur_r %= UR_SIZE;
+       return ret;
 }
 
 inline uch receive_echo(void)
 {
-  return receive_byte(UART_TIMEOUT);
+       return receive_byte(UART_TIMEOUT);
 }
 
 inline uch send_receive(int command)
 {
-  send_command(command);
-  return receive_echo();
+       send_command(command);
+       return receive_echo();
 }
 
 inline uch wait_dsb(void)
 {
-  return receive_byte(DSB_TIMEOUT);
+       return receive_byte(DSB_TIMEOUT);
 }
 
 int type_0_command(int command, int expect_dsb)
 {
-  int e;
-  clear_ur();
-  if (command != (e=send_receive(command))) {
-    debug(("command 0x%x echoed as 0x%x\n", command, e));
-    stats(echo);
-    return -1;
-  }
-  if (expect_dsb) {
-    cd->dsb = wait_dsb();      /* wait for command to finish */
-  }
-  return 0;
+       int e;
+       clear_ur();
+       if (command != (e = send_receive(command))) {
+               debug(("command 0x%x echoed as 0x%x\n", command, e));
+               stats(echo);
+               return -1;
+       }
+       if (expect_dsb) {
+               cd->dsb = wait_dsb();   /* wait for command to finish */
+       }
+       return 0;
 }
 
-int type_1_command(int command, int bytes, uch * status) /* returns info */
-{
-  int i;
-  if (type_0_command(command,0)) return -1;
-  for(i=0; i<bytes; i++) 
-    status[i] = send_receive(c_gimme);
-  return 0;
-}  
+int type_1_command(int command, int bytes, uch * status)
+{                              /* returns info */
+       int i;
+       if (type_0_command(command, 0))
+               return -1;
+       for (i = 0; i < bytes; i++)
+               status[i] = send_receive(c_gimme);
+       return 0;
+}
 
 /* This function resets the adapter card. We'd better not do this too
  * often, because it tends to generate `lost interrupts.' */
 void reset_cm260(void)
 {
-  outw(dc_normal | dc_initialize | READ_AHEAD, r_data_control);
-  udelay(10);                  /* 3.3 mu sec minimum */
-  outw(dc_normal | READ_AHEAD, r_data_control);
+       outw(dc_normal | dc_initialize | READ_AHEAD, r_data_control);
+       udelay(10);             /* 3.3 mu sec minimum */
+       outw(dc_normal | READ_AHEAD, r_data_control);
 }
 
 /* fsm: frame-sec-min from linear address; one of many */
-void fsm(int lba, uch * fsm) 
+void fsm(int lba, uch * fsm)
 {
-  fsm[0] = lba % 75;
-  lba /= 75; lba += 2;
-  fsm[1] = lba % 60; fsm[2] = lba / 60;
+       fsm[0] = lba % 75;
+       lba /= 75;
+       lba += 2;
+       fsm[1] = lba % 60;
+       fsm[2] = lba / 60;
 }
 
-inline int fsm2lba(uch * fsm) 
+inline int fsm2lba(uch * fsm)
 {
-  return fsm[0] + 75*(fsm[1]-2 + 60*fsm[2]);
+       return fsm[0] + 75 * (fsm[1] - 2 + 60 * fsm[2]);
 }
 
 inline int f_s_m2lba(uch f, uch s, uch m)
 {
-  return f + 75*(s-2 + 60*m);
+       return f + 75 * (s - 2 + 60 * m);
 }
 
-int start_read(int start) 
+int start_read(int start)
 {
-  uch read_sector[4] = {c_read_data, };
-  int i, e;
-
-  fsm(start, &read_sector[1]);
-  clear_ur();
-  for (i=0; i<4; i++) 
-    if (read_sector[i] != (e=send_receive(read_sector[i]))) {
-      debug(("read_sector: %x echoes %x\n", read_sector[i], e));
-      stats(echo);
-      if (e==0xff) {           /* this seems to happen often */
-       e = receive_echo();
-       debug(("Second try %x\n", e));
-       if (e!=read_sector[i]) return -1;
-      }
-    }
-  return 0;
+       uch read_sector[4] = { c_read_data, };
+       int i, e;
+
+       fsm(start, &read_sector[1]);
+       clear_ur();
+       for (i = 0; i < 4; i++)
+               if (read_sector[i] != (e = send_receive(read_sector[i]))) {
+                       debug(("read_sector: %x echoes %x\n",
+                              read_sector[i], e));
+                       stats(echo);
+                       if (e == 0xff) {        /* this seems to happen often */
+                               e = receive_echo();
+                               debug(("Second try %x\n", e));
+                               if (e != read_sector[i])
+                                       return -1;
+                       }
+               }
+       return 0;
 }
 
 int stop_read(void)
 {
-  int e;
-  type_0_command(c_stop,0);
-  if((e=receive_echo()) != 0xff) {
-    debug(("c_stop didn't send 0xff, but 0x%x\n", e));
-    stats(stop_0xff);
-    return -1;
-  }
-  return 0;
-}  
+       int e;
+       type_0_command(c_stop, 0);
+       if ((e = receive_echo()) != 0xff) {
+               debug(("c_stop didn't send 0xff, but 0x%x\n", e));
+               stats(stop_0xff);
+               return -1;
+       }
+       return 0;
+}
 
 /* This function starts to read sectors in adapter memory, the
    interrupt routine should stop the read. In fact, the bottom_half
@@ -605,12 +628,14 @@ int stop_read(void)
 
 int read_background(int start, int reading)
 {
-  if (cd->background) return -1; /* can't do twice */
-  outw(dc_normal | BACK_AHEAD, r_data_control);
-  if (!reading && start_read(start)) return -2;
-  cd->adapter_first = cd->adapter_last = start; 
-  cd->background = 1;          /* flag a read is going on */
-  return 0;
+       if (cd->background)
+               return -1;      /* can't do twice */
+       outw(dc_normal | BACK_AHEAD, r_data_control);
+       if (!reading && start_read(start))
+               return -2;
+       cd->adapter_first = cd->adapter_last = start;
+       cd->background = 1;     /* flag a read is going on */
+       return 0;
 }
 
 #ifdef USE_INSW
@@ -618,12 +643,12 @@ int read_background(int start, int reading)
 #else
 /* this routine implements insw(,,). There was a time i had the
    impression that there would be any difference in error-behaviour. */
-void transport_data(int port, ush * dest, int count) 
+void transport_data(int port, ush * dest, int count)
 {
-  int i;
-  ush * d;
-  for (i=0, d=dest; i<count; i++, d++) 
-    *d = inw(port);
+       int i;
+       ush *d;
+       for (i = 0, d = dest; i < count; i++, d++)
+               *d = inw(port);
 }
 #endif
 
@@ -631,33 +656,38 @@ void transport_data(int port, ush * dest, int count)
 #define MAX_TRIES 100
 int read_sector(int start)
 {
-  int tries=0;
-  if (cd->background) {
-    cd->background=0;
-    cd->adapter_last = -1;     /* invalidate adapter memory */
-    stop_read();
-  }
-  cd->fifo_overflowed=0;
-  reset_cm260();               /* empty fifo etc. */
-  if (start_read(start)) return -1;
-  do {
-    if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
-      debug(("Read timed out sector 0x%x\n", start));
-      stats(read_timeout);
-      stop_read();
-      return -3;               
-    } 
-    tries++;
-  } while (cd->intr_ds & ds_fifo_empty && tries < MAX_TRIES);
-  if (tries>1) debug(("Took me some tries\n"))
-  else if (tries == MAX_TRIES) 
-    debug(("MAX_TRIES tries for read sector\n"));
-  transport_data(r_fifo_output_buffer, cd->sector, 
-                READ_AHEAD*RAW_SECTOR_SIZE/2);
-  if (read_background(start+READ_AHEAD,1)) stats(read_background);
-  cd->sector_first = start; cd->sector_last = start+READ_AHEAD;
-  stats(read_restarted);
-  return 0;
+       int tries = 0;
+       if (cd->background) {
+               cd->background = 0;
+               cd->adapter_last = -1;  /* invalidate adapter memory */
+               stop_read();
+       }
+       cd->fifo_overflowed = 0;
+       reset_cm260();          /* empty fifo etc. */
+       if (start_read(start))
+               return -1;
+       do {
+               if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
+                       debug(("Read timed out sector 0x%x\n", start));
+                       stats(read_timeout);
+                       stop_read();
+                       return -3;
+               }
+               tries++;
+       } while (cd->intr_ds & ds_fifo_empty && tries < MAX_TRIES);
+       if (tries > 1)
+               debug(("Took me some tries\n"))
+                   else
+       if (tries == MAX_TRIES)
+               debug(("MAX_TRIES tries for read sector\n"));
+       transport_data(r_fifo_output_buffer, cd->sector,
+                      READ_AHEAD * RAW_SECTOR_SIZE / 2);
+       if (read_background(start + READ_AHEAD, 1))
+               stats(read_background);
+       cd->sector_first = start;
+       cd->sector_last = start + READ_AHEAD;
+       stats(read_restarted);
+       return 0;
 }
 
 /* The function of bottom-half is to send a stop command to the drive
@@ -672,43 +702,46 @@ int read_sector(int start)
 
 void cm206_bh(void)
 {
-  debug(("bh: %d\n", cd->background));
-  switch (cd->background) {
-  case 1:
-    stats(bh);
-    if (!(cd->intr_ls & ls_transmitter_buffer_empty)) {
-      cd->command = c_stop;
-      outw(dc_mask_sync_error | dc_no_stop_on_error | 
-          (inw(r_data_status) & 0x7f), r_data_control);
-      cd->background=2;
-      break;                   /* we'd better not time-out here! */
-    }
-    else outw(c_stop, r_uart_transmit);
-    /* fall into case 2: */
-  case 2:                      
-    /* the write has been satisfied by interrupt routine */
-    cd->background=3;
-    break;
-  case 3:
-    if (cd->ur_r != cd->ur_w) {
-      if (cd->ur[cd->ur_r] != c_stop) {
-       debug(("cm206_bh: c_stop echoed 0x%x\n", cd->ur[cd->ur_r]));
-       stats(echo);
-      }
-      cd->ur_r++; cd->ur_r %= UR_SIZE;
-    }
-    cd->background++;
-    break;
-  case 4:
-    if (cd->ur_r != cd->ur_w) {
-      if (cd->ur[cd->ur_r] != 0xff) {
-       debug(("cm206_bh: c_stop reacted with 0x%x\n", cd->ur[cd->ur_r]));
-       stats(stop_0xff);
-      }
-      cd->ur_r++; cd->ur_r %= UR_SIZE;
-    }
-    cd->background=0;
-  }
+       debug(("bh: %d\n", cd->background));
+       switch (cd->background) {
+       case 1:
+               stats(bh);
+               if (!(cd->intr_ls & ls_transmitter_buffer_empty)) {
+                       cd->command = c_stop;
+                       outw(dc_mask_sync_error | dc_no_stop_on_error |
+                            (inw(r_data_status) & 0x7f), r_data_control);
+                       cd->background = 2;
+                       break;  /* we'd better not time-out here! */
+               } else
+                       outw(c_stop, r_uart_transmit);
+               /* fall into case 2: */
+       case 2:
+               /* the write has been satisfied by interrupt routine */
+               cd->background = 3;
+               break;
+       case 3:
+               if (cd->ur_r != cd->ur_w) {
+                       if (cd->ur[cd->ur_r] != c_stop) {
+                               debug(("cm206_bh: c_stop echoed 0x%x\n",
+                                      cd->ur[cd->ur_r]));
+                               stats(echo);
+                       }
+                       cd->ur_r++;
+                       cd->ur_r %= UR_SIZE;
+               }
+               cd->background++;
+               break;
+       case 4:
+               if (cd->ur_r != cd->ur_w) {
+                       if (cd->ur[cd->ur_r] != 0xff) {
+                               debug(("cm206_bh: c_stop reacted with 0x%x\n", cd->ur[cd->ur_r]));
+                               stats(stop_0xff);
+                       }
+                       cd->ur_r++;
+                       cd->ur_r %= UR_SIZE;
+               }
+               cd->background = 0;
+       }
 }
 
 /* This command clears the dsb_possible_media_change flag, so we must 
@@ -716,66 +749,67 @@ void cm206_bh(void)
  */
 void get_drive_status(void)
 {
-  uch status[2];
-  type_1_command(c_drive_status, 2, status); /* this might be done faster */
-  cd->dsb=status[0];
-  cd->cc=status[1];
-  cd->media_changed |= 
-    !!(cd->dsb & (dsb_possible_media_change | 
-                 dsb_drive_not_ready | dsb_tray_not_closed));
+       uch status[2];
+       type_1_command(c_drive_status, 2, status);      /* this might be done faster */
+       cd->dsb = status[0];
+       cd->cc = status[1];
+       cd->media_changed |=
+           !!(cd->dsb & (dsb_possible_media_change |
+                         dsb_drive_not_ready | dsb_tray_not_closed));
 }
 
 void get_disc_status(void)
 {
-  if (type_1_command(c_disc_status, 7, cd->disc_status)) {
-    debug(("get_disc_status: error\n"));
-  }
+       if (type_1_command(c_disc_status, 7, cd->disc_status)) {
+               debug(("get_disc_status: error\n"));
+       }
 }
 
 /* The new open. The real opening strategy is defined in cdrom.c. */
 
-static int cm206_open(struct cdrom_device_info * cdi, int purpose) 
+static int cm206_open(struct cdrom_device_info *cdi, int purpose)
 {
-  MOD_INC_USE_COUNT;
-  if (!cd->openfiles) {                /* reset only first time */
-    cd->background=0;
-    reset_cm260();
-    cd->adapter_last = -1;     /* invalidate adapter memory */
-    cd->sector_last = -1;
-  }
-  ++cd->openfiles;
-  stats(open);
-  return 0;
+       MOD_INC_USE_COUNT;
+       if (!cd->openfiles) {   /* reset only first time */
+               cd->background = 0;
+               reset_cm260();
+               cd->adapter_last = -1;  /* invalidate adapter memory */
+               cd->sector_last = -1;
+       }
+       ++cd->openfiles;
+       stats(open);
+       return 0;
 }
 
-static void cm206_release(struct cdrom_device_info * cdi)
+static void cm206_release(struct cdrom_device_info *cdi)
 {
-  if (cd->openfiles==1) {
-    if (cd->background) {
-      cd->background=0;
-      stop_read();
-    }
-    cd->sector_last = -1;      /* Make our internal buffer invalid */
-    FIRST_TRACK = 0;           /* No valid disc status */
-  }
-  --cd->openfiles;
-  MOD_DEC_USE_COUNT;
+       if (cd->openfiles == 1) {
+               if (cd->background) {
+                       cd->background = 0;
+                       stop_read();
+               }
+               cd->sector_last = -1;   /* Make our internal buffer invalid */
+               FIRST_TRACK = 0;        /* No valid disc status */
+       }
+       --cd->openfiles;
+       MOD_DEC_USE_COUNT;
 }
 
 /* Empty buffer empties $sectors$ sectors of the adapter card buffer,
  * and then reads a sector in kernel memory.  */
-void empty_buffer(int sectors) 
+void empty_buffer(int sectors)
 {
-  while (sectors>=0) {
-    transport_data(r_fifo_output_buffer, cd->sector + cd->fifo_overflowed, 
-        RAW_SECTOR_SIZE/2 - cd->fifo_overflowed);
-    --sectors;
-    ++cd->adapter_first;       /* update the current adapter sector */
-    cd->fifo_overflowed=0;     /* reset overflow bit */
-    stats(sector_transferred);
-  } 
-  cd->sector_first=cd->adapter_first-1;
-  cd->sector_last=cd->adapter_first; /* update the buffer sector */
+       while (sectors >= 0) {
+               transport_data(r_fifo_output_buffer,
+                              cd->sector + cd->fifo_overflowed,
+                              RAW_SECTOR_SIZE / 2 - cd->fifo_overflowed);
+               --sectors;
+               ++cd->adapter_first;    /* update the current adapter sector */
+               cd->fifo_overflowed = 0;        /* reset overflow bit */
+               stats(sector_transferred);
+       }
+       cd->sector_first = cd->adapter_first - 1;
+       cd->sector_last = cd->adapter_first;    /* update the buffer sector */
 }
 
 /* try_adapter. This function determines if the requested sector is
@@ -783,29 +817,27 @@ void empty_buffer(int sectors)
    success */
 int try_adapter(int sector)
 {
-  if (cd->adapter_first <= sector && sector < cd->adapter_last) { 
-    /* sector is in adapter memory */
-    empty_buffer(sector - cd->adapter_first);
-    return 0;
-  }
-  else if (cd->background==1 && cd->adapter_first <= sector
-          && sector < cd->adapter_first+cd->max_sectors) {
-    /* a read is going on, we can wait for it */
-    cd->wait_back=1;
-    while (sector >= cd->adapter_last) {
-      if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
-       debug(("Timed out during background wait: %d %d %d %d\n", sector, 
-              cd->adapter_last, cd->adapter_first, cd->background));
-       stats(back_read_timeout);
-       cd->wait_back=0;
-       return -1;
-      }
-    }
-    cd->wait_back=0;
-    empty_buffer(sector - cd->adapter_first);
-    return 0;
-  }
-  else return -2;
+       if (cd->adapter_first <= sector && sector < cd->adapter_last) {
+               /* sector is in adapter memory */
+               empty_buffer(sector - cd->adapter_first);
+               return 0;
+       } else if (cd->background == 1 && cd->adapter_first <= sector
+                  && sector < cd->adapter_first + cd->max_sectors) {
+               /* a read is going on, we can wait for it */
+               cd->wait_back = 1;
+               while (sector >= cd->adapter_last) {
+                       if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
+                               debug(("Timed out during background wait: %d %d %d %d\n", sector, cd->adapter_last, cd->adapter_first, cd->background));
+                               stats(back_read_timeout);
+                               cd->wait_back = 0;
+                               return -1;
+                       }
+               }
+               cd->wait_back = 0;
+               empty_buffer(sector - cd->adapter_first);
+               return 0;
+       } else
+               return -2;
 }
 
 /* This is not a very smart implementation. We could optimize for 
@@ -813,45 +845,50 @@ int try_adapter(int sector)
    bring down the processor load. */
 static void do_cm206_request(request_queue_t * q)
 {
-  long int i, cd_sec_no;
-  int quarter, error; 
-  uch * source, * dest;
-  
-  while(1) {    /* repeat until all requests have been satisfied */
-    INIT_REQUEST;
-    if (QUEUE_EMPTY || CURRENT->rq_status == RQ_INACTIVE)
-      return;
-    if (CURRENT->cmd != READ) {
-      debug(("Non-read command %d on cdrom\n", CURRENT->cmd));
-      end_request(0);
-      continue;
-    }
-    spin_unlock_irq(&io_request_lock);
-    error=0;
-    for (i=0; i<CURRENT->nr_sectors; i++) {
-      int e1, e2;
-      cd_sec_no = (CURRENT->sector+i)/BLOCKS_ISO; /* 4 times 512 bytes */
-      quarter = (CURRENT->sector+i) % BLOCKS_ISO; 
-      dest = CURRENT->buffer + i*LINUX_BLOCK_SIZE;
-      /* is already in buffer memory? */
-      if (cd->sector_first <= cd_sec_no && cd_sec_no < cd->sector_last) {
-       source = ((uch *) cd->sector) + 16 + quarter*LINUX_BLOCK_SIZE 
-         + (cd_sec_no-cd->sector_first)*RAW_SECTOR_SIZE;
-       memcpy(dest, source, LINUX_BLOCK_SIZE); 
-      }
-      else if (!(e1=try_adapter(cd_sec_no)) || 
-              !(e2=read_sector(cd_sec_no))) {
-       source =  ((uch *) cd->sector)+16+quarter*LINUX_BLOCK_SIZE;
-       memcpy(dest, source, LINUX_BLOCK_SIZE); 
-      }
-      else {
-       error=1;
-       debug(("cm206_request: %d %d\n", e1, e2));
-      }
-    }
-    spin_lock_irq(&io_request_lock);
-    end_request(!error);
-  }
+       long int i, cd_sec_no;
+       int quarter, error;
+       uch *source, *dest;
+
+       while (1) {             /* repeat until all requests have been satisfied */
+               INIT_REQUEST;
+               if (QUEUE_EMPTY || CURRENT->rq_status == RQ_INACTIVE)
+                       return;
+               if (CURRENT->cmd != READ) {
+                       debug(("Non-read command %d on cdrom\n",
+                              CURRENT->cmd));
+                       end_request(0);
+                       continue;
+               }
+               spin_unlock_irq(&io_request_lock);
+               error = 0;
+               for (i = 0; i < CURRENT->nr_sectors; i++) {
+                       int e1, e2;
+                       cd_sec_no = (CURRENT->sector + i) / BLOCKS_ISO; /* 4 times 512 bytes */
+                       quarter = (CURRENT->sector + i) % BLOCKS_ISO;
+                       dest = CURRENT->buffer + i * LINUX_BLOCK_SIZE;
+                       /* is already in buffer memory? */
+                       if (cd->sector_first <= cd_sec_no
+                           && cd_sec_no < cd->sector_last) {
+                               source =
+                                   ((uch *) cd->sector) + 16 +
+                                   quarter * LINUX_BLOCK_SIZE +
+                                   (cd_sec_no -
+                                    cd->sector_first) * RAW_SECTOR_SIZE;
+                               memcpy(dest, source, LINUX_BLOCK_SIZE);
+                       } else if (!(e1 = try_adapter(cd_sec_no)) ||
+                                  !(e2 = read_sector(cd_sec_no))) {
+                               source =
+                                   ((uch *) cd->sector) + 16 +
+                                   quarter * LINUX_BLOCK_SIZE;
+                               memcpy(dest, source, LINUX_BLOCK_SIZE);
+                       } else {
+                               error = 1;
+                               debug(("cm206_request: %d %d\n", e1, e2));
+                       }
+               }
+               spin_lock_irq(&io_request_lock);
+               end_request(!error);
+       }
 }
 
 /* Audio support. I've tried very hard, but the cm206 drive doesn't 
@@ -870,24 +907,27 @@ static void do_cm206_request(request_queue_t * q)
 /* seek seeks to address lba. It does wait to arrive there. */
 void seek(int lba)
 {
-  int i;
-  uch seek_command[4]={c_seek, };
-  
-  fsm(lba, &seek_command[1]);
-  for (i=0; i<4; i++) type_0_command(seek_command[i], 0);
-  cd->dsb = wait_dsb();
+       int i;
+       uch seek_command[4] = { c_seek, };
+
+       fsm(lba, &seek_command[1]);
+       for (i = 0; i < 4; i++)
+               type_0_command(seek_command[i], 0);
+       cd->dsb = wait_dsb();
 }
 
-uch bcdbin(unsigned char bcd)  /* stolen from mcd.c! */
-{
-  return (bcd >> 4)*10 + (bcd & 0xf);
-} 
+uch bcdbin(unsigned char bcd)
+{                              /* stolen from mcd.c! */
+       return (bcd >> 4) * 10 + (bcd & 0xf);
+}
 
-inline uch normalize_track(uch track) 
+inline uch normalize_track(uch track)
 {
-  if (track<1) return 1;
-  if (track>LAST_TRACK) return LAST_TRACK+1;
-  return track;
+       if (track < 1)
+               return 1;
+       if (track > LAST_TRACK)
+               return LAST_TRACK + 1;
+       return track;
 }
 
 /* This function does a binary search for track start. It records all
@@ -896,150 +936,175 @@ inline uch normalize_track(uch track)
  */
 int get_toc_lba(uch track)
 {
-  int max=74*60*75-150, min=fsm2lba(cd->toc[1].fsm);
-  int i, lba, l, old_lba=0;
-  uch * q = cd->q;
-  uch ct;                      /* current track */
-  int binary=0;
-  const int skip = 3*60*75;            /* 3 minutes */
-
-  for (i=track; i>0; i--) if (cd->toc[i].track) {
-    min = fsm2lba(cd->toc[i].fsm);
-    break;
-  }
-  lba = min + skip;
-  do {
-    seek(lba); 
-    type_1_command(c_read_current_q, 10, q);
-    ct = normalize_track(q[1]);
-    if (!cd->toc[ct].track) {
-      l = q[9]-bcdbin(q[5]) + 75*(q[8]-bcdbin(q[4])-2 + 
-                                 60*(q[7]-bcdbin(q[3])));
-      cd->toc[ct].track=q[1];  /* lead out still 0xaa */
-      fsm(l, cd->toc[ct].fsm);
-      cd->toc[ct].q0 = q[0];   /* contains adr and ctrl info */
-      if (ct==track) return l;
-    }
-    old_lba=lba;
-    if (binary) {
-      if (ct < track) min = lba; else max = lba;
-      lba = (min+max)/2; 
-    } else {
-      if(ct < track) lba += skip;
-      else {
-       binary=1;
-       max = lba; min = lba - skip;
-       lba = (min+max)/2;
-      }
-    }
-  } while (lba!=old_lba);
-  return lba;
+       int max = 74 * 60 * 75 - 150, min = fsm2lba(cd->toc[1].fsm);
+       int i, lba, l, old_lba = 0;
+       uch *q = cd->q;
+       uch ct;                 /* current track */
+       int binary = 0;
+       const int skip = 3 * 60 * 75;   /* 3 minutes */
+
+       for (i = track; i > 0; i--)
+               if (cd->toc[i].track) {
+                       min = fsm2lba(cd->toc[i].fsm);
+                       break;
+               }
+       lba = min + skip;
+       do {
+               seek(lba);
+               type_1_command(c_read_current_q, 10, q);
+               ct = normalize_track(q[1]);
+               if (!cd->toc[ct].track) {
+                       l = q[9] - bcdbin(q[5]) + 75 * (q[8] -
+                                                       bcdbin(q[4]) - 2 +
+                                                       60 * (q[7] -
+                                                             bcdbin(q
+                                                                    [3])));
+                       cd->toc[ct].track = q[1];       /* lead out still 0xaa */
+                       fsm(l, cd->toc[ct].fsm);
+                       cd->toc[ct].q0 = q[0];  /* contains adr and ctrl info */
+                       if (ct == track)
+                               return l;
+               }
+               old_lba = lba;
+               if (binary) {
+                       if (ct < track)
+                               min = lba;
+                       else
+                               max = lba;
+                       lba = (min + max) / 2;
+               } else {
+                       if (ct < track)
+                               lba += skip;
+                       else {
+                               binary = 1;
+                               max = lba;
+                               min = lba - skip;
+                               lba = (min + max) / 2;
+                       }
+               }
+       } while (lba != old_lba);
+       return lba;
 }
 
-void update_toc_entry(uch track) 
+void update_toc_entry(uch track)
 {
-  track = normalize_track(track);
-  if (!cd->toc[track].track) get_toc_lba(track);
+       track = normalize_track(track);
+       if (!cd->toc[track].track)
+               get_toc_lba(track);
 }
 
 /* return 0 upon success */
-int read_toc_header(struct cdrom_tochdr * hp)
+int read_toc_header(struct cdrom_tochdr *hp)
 {
-  if (!FIRST_TRACK) get_disc_status();
-  if (hp) { 
-    int i;
-    hp->cdth_trk0 = FIRST_TRACK;
-    hp->cdth_trk1 = LAST_TRACK; 
-                               /* fill in first track position */
-    for (i=0; i<3; i++) cd->toc[1].fsm[i] = cd->disc_status[3+i];
-    update_toc_entry(LAST_TRACK+1);            /* find most entries */
-    return 0;
-  }
-  return -1;
-}  
-
-void play_from_to_msf(struct cdrom_msf* msfp)
+       if (!FIRST_TRACK)
+               get_disc_status();
+       if (hp) {
+               int i;
+               hp->cdth_trk0 = FIRST_TRACK;
+               hp->cdth_trk1 = LAST_TRACK;
+               /* fill in first track position */
+               for (i = 0; i < 3; i++)
+                       cd->toc[1].fsm[i] = cd->disc_status[3 + i];
+               update_toc_entry(LAST_TRACK + 1);       /* find most entries */
+               return 0;
+       }
+       return -1;
+}
+
+void play_from_to_msf(struct cdrom_msf *msfp)
 {
-  uch play_command[] = {c_play, 
-          msfp->cdmsf_frame0, msfp->cdmsf_sec0, msfp->cdmsf_min0,
-          msfp->cdmsf_frame1, msfp->cdmsf_sec1, msfp->cdmsf_min1, 2, 2};
-  int i;
-  for (i=0; i<9; i++) type_0_command(play_command[i], 0);
-  for (i=0; i<3; i++) 
-    PLAY_TO.fsm[i] = play_command[i+4];
-  PLAY_TO.track = 0;           /* say no track end */
-  cd->dsb = wait_dsb();
-}  
+       uch play_command[] = { c_play,
+               msfp->cdmsf_frame0, msfp->cdmsf_sec0, msfp->cdmsf_min0,
+               msfp->cdmsf_frame1, msfp->cdmsf_sec1, msfp->cdmsf_min1, 2,
+                   2
+       };
+       int i;
+       for (i = 0; i < 9; i++)
+               type_0_command(play_command[i], 0);
+       for (i = 0; i < 3; i++)
+               PLAY_TO.fsm[i] = play_command[i + 4];
+       PLAY_TO.track = 0;      /* say no track end */
+       cd->dsb = wait_dsb();
+}
 
 void play_from_to_track(int from, int to)
 {
-  uch play_command[8] = {c_play, };
-  int i;
-
-  if (from==0) {               /* continue paused play */
-    for (i=0; i<3; i++) { 
-      play_command[i+1] = cd->audio_status[i+2];
-      play_command[i+4] = PLAY_TO.fsm[i];
-    }
-  } else {
-    update_toc_entry(from); update_toc_entry(to+1);
-    for (i=0; i<3; i++) {
-      play_command[i+1] = cd->toc[from].fsm[i];
-      PLAY_TO.fsm[i] = play_command[i+4] = cd->toc[to+1].fsm[i];
-    }
-    PLAY_TO.track = to; 
-  }
-  for (i=0; i<7; i++) type_0_command(play_command[i],0);
-  for (i=0; i<2; i++) type_0_command(0x2, 0); /* volume */
-  cd->dsb = wait_dsb();
+       uch play_command[8] = { c_play, };
+       int i;
+
+       if (from == 0) {        /* continue paused play */
+               for (i = 0; i < 3; i++) {
+                       play_command[i + 1] = cd->audio_status[i + 2];
+                       play_command[i + 4] = PLAY_TO.fsm[i];
+               }
+       } else {
+               update_toc_entry(from);
+               update_toc_entry(to + 1);
+               for (i = 0; i < 3; i++) {
+                       play_command[i + 1] = cd->toc[from].fsm[i];
+                       PLAY_TO.fsm[i] = play_command[i + 4] =
+                           cd->toc[to + 1].fsm[i];
+               }
+               PLAY_TO.track = to;
+       }
+       for (i = 0; i < 7; i++)
+               type_0_command(play_command[i], 0);
+       for (i = 0; i < 2; i++)
+               type_0_command(0x2, 0); /* volume */
+       cd->dsb = wait_dsb();
 }
 
-int get_current_q(struct cdrom_subchnl * qp)
+int get_current_q(struct cdrom_subchnl *qp)
 {
-  int i;
-  uch * q = cd->q;
-  if (type_1_command(c_read_current_q, 10, q)) return 0;
+       int i;
+       uch *q = cd->q;
+       if (type_1_command(c_read_current_q, 10, q))
+               return 0;
 /*  q[0] = bcdbin(q[0]); Don't think so! */
-  for (i=2; i<6; i++) q[i]=bcdbin(q[i]); 
-  qp->cdsc_adr = q[0] & 0xf; qp->cdsc_ctrl = q[0] >> 4;        /* from mcd.c */
-  qp->cdsc_trk = q[1];  qp->cdsc_ind = q[2];
-  if (qp->cdsc_format == CDROM_MSF) {
-    qp->cdsc_reladdr.msf.minute = q[3];
-    qp->cdsc_reladdr.msf.second = q[4];
-    qp->cdsc_reladdr.msf.frame = q[5];
-    qp->cdsc_absaddr.msf.minute = q[7];
-    qp->cdsc_absaddr.msf.second = q[8];
-    qp->cdsc_absaddr.msf.frame = q[9];
-  } else {
-    qp->cdsc_reladdr.lba = f_s_m2lba(q[5], q[4], q[3]);
-    qp->cdsc_absaddr.lba = f_s_m2lba(q[9], q[8], q[7]);
-  }
-  get_drive_status();
-  if (cd->dsb & dsb_play_in_progress) 
-    qp->cdsc_audiostatus = CDROM_AUDIO_PLAY ;
-  else if (PAUSED) 
-    qp->cdsc_audiostatus = CDROM_AUDIO_PAUSED;
-  else qp->cdsc_audiostatus = CDROM_AUDIO_NO_STATUS;
-  return 0;
+       for (i = 2; i < 6; i++)
+               q[i] = bcdbin(q[i]);
+       qp->cdsc_adr = q[0] & 0xf;
+       qp->cdsc_ctrl = q[0] >> 4;      /* from mcd.c */
+       qp->cdsc_trk = q[1];
+       qp->cdsc_ind = q[2];
+       if (qp->cdsc_format == CDROM_MSF) {
+               qp->cdsc_reladdr.msf.minute = q[3];
+               qp->cdsc_reladdr.msf.second = q[4];
+               qp->cdsc_reladdr.msf.frame = q[5];
+               qp->cdsc_absaddr.msf.minute = q[7];
+               qp->cdsc_absaddr.msf.second = q[8];
+               qp->cdsc_absaddr.msf.frame = q[9];
+       } else {
+               qp->cdsc_reladdr.lba = f_s_m2lba(q[5], q[4], q[3]);
+               qp->cdsc_absaddr.lba = f_s_m2lba(q[9], q[8], q[7]);
+       }
+       get_drive_status();
+       if (cd->dsb & dsb_play_in_progress)
+               qp->cdsc_audiostatus = CDROM_AUDIO_PLAY;
+       else if (PAUSED)
+               qp->cdsc_audiostatus = CDROM_AUDIO_PAUSED;
+       else
+               qp->cdsc_audiostatus = CDROM_AUDIO_NO_STATUS;
+       return 0;
 }
 
 void invalidate_toc(void)
 {
-  memset(cd->toc, 0, sizeof(cd->toc));
-  memset(cd->disc_status, 0, sizeof(cd->disc_status));
+       memset(cd->toc, 0, sizeof(cd->toc));
+       memset(cd->disc_status, 0, sizeof(cd->disc_status));
 }
 
 /* cdrom.c guarantees that cdte_format == CDROM_MSF */
-void get_toc_entry(struct cdrom_tocentry * ep)
+void get_toc_entry(struct cdrom_tocentry *ep)
 {
-  uch track = normalize_track(ep->cdte_track);
-  update_toc_entry(track);
-  ep->cdte_addr.msf.frame = cd->toc[track].fsm[0];
-  ep->cdte_addr.msf.second = cd->toc[track].fsm[1];
-  ep->cdte_addr.msf.minute = cd->toc[track].fsm[2];
-  ep->cdte_adr = cd->toc[track].q0 & 0xf; 
-  ep->cdte_ctrl = cd->toc[track].q0 >> 4;
-  ep->cdte_datamode=0;
+       uch track = normalize_track(ep->cdte_track);
+       update_toc_entry(track);
+       ep->cdte_addr.msf.frame = cd->toc[track].fsm[0];
+       ep->cdte_addr.msf.second = cd->toc[track].fsm[1];
+       ep->cdte_addr.msf.minute = cd->toc[track].fsm[2];
+       ep->cdte_adr = cd->toc[track].q0 & 0xf;
+       ep->cdte_ctrl = cd->toc[track].q0 >> 4;
+       ep->cdte_datamode = 0;
 }
 
 /* Audio ioctl.  Ioctl commands connected to audio are in such an
@@ -1047,244 +1112,262 @@ void get_toc_entry(struct cdrom_tocentry * ep)
  * upon success. Memory checking has been done by cdrom_ioctl(), the
  * calling function, as well as LBA/MSF sanitization.
 */
-int cm206_audio_ioctl(struct cdrom_device_info * cdi, unsigned int cmd, 
-                     void * arg)  
+int cm206_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
+                     void *arg)
 {
-  switch (cmd) {
-  case CDROMREADTOCHDR: 
-    return read_toc_header((struct cdrom_tochdr *) arg);
-  case CDROMREADTOCENTRY:      
-    get_toc_entry((struct cdrom_tocentry *) arg);
-    return 0;
-  case CDROMPLAYMSF: 
-    play_from_to_msf((struct cdrom_msf *) arg);
-    return 0;
-  case CDROMPLAYTRKIND:                /* admittedly, not particularly beautiful */
-    play_from_to_track(((struct cdrom_ti *)arg)->cdti_trk0, 
-                      ((struct cdrom_ti *)arg)->cdti_trk1);
-    return 0;
-  case CDROMSTOP: 
-    PAUSED=0;
-    if (cd->dsb & dsb_play_in_progress) return type_0_command(c_stop, 1);
-    else return 0;
-  case CDROMPAUSE: 
-    get_drive_status();
-    if (cd->dsb & dsb_play_in_progress) {
-      type_0_command(c_stop, 1);
-      type_1_command(c_audio_status, 5, cd->audio_status);
-      PAUSED=1;        /* say we're paused */
-    }
-    return 0;
-  case CDROMRESUME:
-    if (PAUSED) play_from_to_track(0,0);
-    PAUSED=0;
-    return 0;
-  case CDROMSTART:
-  case CDROMVOLCTRL:
-    return 0;
-  case CDROMSUBCHNL: 
-    return get_current_q((struct cdrom_subchnl *)arg);
-  default:
-    return -EINVAL;
-  }
+       switch (cmd) {
+       case CDROMREADTOCHDR:
+               return read_toc_header((struct cdrom_tochdr *) arg);
+       case CDROMREADTOCENTRY:
+               get_toc_entry((struct cdrom_tocentry *) arg);
+               return 0;
+       case CDROMPLAYMSF:
+               play_from_to_msf((struct cdrom_msf *) arg);
+               return 0;
+       case CDROMPLAYTRKIND:   /* admittedly, not particularly beautiful */
+               play_from_to_track(((struct cdrom_ti *) arg)->cdti_trk0,
+                                  ((struct cdrom_ti *) arg)->cdti_trk1);
+               return 0;
+       case CDROMSTOP:
+               PAUSED = 0;
+               if (cd->dsb & dsb_play_in_progress)
+                       return type_0_command(c_stop, 1);
+               else
+                       return 0;
+       case CDROMPAUSE:
+               get_drive_status();
+               if (cd->dsb & dsb_play_in_progress) {
+                       type_0_command(c_stop, 1);
+                       type_1_command(c_audio_status, 5,
+                                      cd->audio_status);
+                       PAUSED = 1;     /* say we're paused */
+               }
+               return 0;
+       case CDROMRESUME:
+               if (PAUSED)
+                       play_from_to_track(0, 0);
+               PAUSED = 0;
+               return 0;
+       case CDROMSTART:
+       case CDROMVOLCTRL:
+               return 0;
+       case CDROMSUBCHNL:
+               return get_current_q((struct cdrom_subchnl *) arg);
+       default:
+               return -EINVAL;
+       }
 }
 
 /* Ioctl. These ioctls are specific to the cm206 driver. I have made
    some driver statistics accessible through ioctl calls.
  */
 
-static int cm206_ioctl(struct cdrom_device_info * cdi, unsigned int cmd, 
+static int cm206_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
                       unsigned long arg)
 {
-  switch (cmd) {
+       switch (cmd) {
 #ifdef STATISTICS
-  case CM206CTL_GET_STAT:
-    if (arg >= NR_STATS) return -EINVAL;
-    else return cd->stats[arg];
-  case CM206CTL_GET_LAST_STAT:
-    if (arg >= NR_STATS) return -EINVAL;
-    else return cd->last_stat[arg];
-#endif    
-  default:
-    debug(("Unknown ioctl call 0x%x\n", cmd));
-    return -EINVAL;
-  }
-}     
-
-int cm206_media_changed(struct cdrom_device_info * cdi, int disc_nr) 
+       case CM206CTL_GET_STAT:
+               if (arg >= NR_STATS)
+                       return -EINVAL;
+               else
+                       return cd->stats[arg];
+       case CM206CTL_GET_LAST_STAT:
+               if (arg >= NR_STATS)
+                       return -EINVAL;
+               else
+                       return cd->last_stat[arg];
+#endif
+       default:
+               debug(("Unknown ioctl call 0x%x\n", cmd));
+               return -EINVAL;
+       }
+}
+
+int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr)
 {
-  if (cd != NULL) {
-    int r;
-    get_drive_status();                /* ensure cd->media_changed OK */
-    r = cd->media_changed;
-    cd->media_changed = 0;     /* clear bit */
-    return r;
-  }
-  else return -EIO;
+       if (cd != NULL) {
+               int r;
+               get_drive_status();     /* ensure cd->media_changed OK */
+               r = cd->media_changed;
+               cd->media_changed = 0;  /* clear bit */
+               return r;
+       } else
+               return -EIO;
 }
 
 /* The new generic cdrom support. Routines should be concise, most of
    the logic should be in cdrom.c */
 
 /* returns number of times device is in use */
-int cm206_open_files(struct cdrom_device_info * cdi)   
+int cm206_open_files(struct cdrom_device_info *cdi)
 {
-  if (cd) return cd->openfiles;
-  return -1;
+       if (cd)
+               return cd->openfiles;
+       return -1;
 }
 
 /* controls tray movement */
-int cm206_tray_move(struct cdrom_device_info * cdi, int position) 
+int cm206_tray_move(struct cdrom_device_info *cdi, int position)
 {
-  if (position) {              /* 1: eject */
-    type_0_command(c_open_tray,1);
-    invalidate_toc();
-  } 
-  else type_0_command(c_close_tray, 1);        /* 0: close */
-  return 0;
+       if (position) {         /* 1: eject */
+               type_0_command(c_open_tray, 1);
+               invalidate_toc();
+       } else
+               type_0_command(c_close_tray, 1);        /* 0: close */
+       return 0;
 }
 
 /* gives current state of the drive */
-int cm206_drive_status(struct cdrom_device_info * cdi, int slot_nr)
+int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr)
 {
-  get_drive_status();
-  if (cd->dsb & dsb_tray_not_closed) return CDS_TRAY_OPEN;
-  if (!(cd->dsb & dsb_disc_present)) return CDS_NO_DISC; 
-  if (cd->dsb & dsb_drive_not_ready) return CDS_DRIVE_NOT_READY;
-  return CDS_DISC_OK;
+       get_drive_status();
+       if (cd->dsb & dsb_tray_not_closed)
+               return CDS_TRAY_OPEN;
+       if (!(cd->dsb & dsb_disc_present))
+               return CDS_NO_DISC;
+       if (cd->dsb & dsb_drive_not_ready)
+               return CDS_DRIVE_NOT_READY;
+       return CDS_DISC_OK;
 }
+
 /* locks or unlocks door lock==1: lock; return 0 upon success */
-int cm206_lock_door(struct cdrom_device_info * cdi, int lock)
+int cm206_lock_door(struct cdrom_device_info *cdi, int lock)
 {
-  uch command = (lock) ? c_lock_tray : c_unlock_tray;
-  type_0_command(command, 1);  /* wait and get dsb */
-  /* the logic calculates the success, 0 means successful */
-  return lock ^ ((cd->dsb & dsb_tray_locked) != 0);
+       uch command = (lock) ? c_lock_tray : c_unlock_tray;
+       type_0_command(command, 1);     /* wait and get dsb */
+       /* the logic calculates the success, 0 means successful */
+       return lock ^ ((cd->dsb & dsb_tray_locked) != 0);
 }
-  
+
 /* Although a session start should be in LBA format, we return it in 
    MSF format because it is slightly easier, and the new generic ioctl
    will take care of the necessary conversion. */
-int cm206_get_last_session(struct cdrom_device_info * cdi, 
-                          struct cdrom_multisession * mssp) 
+int cm206_get_last_session(struct cdrom_device_info *cdi,
+                          struct cdrom_multisession *mssp)
 {
-  if (!FIRST_TRACK) get_disc_status();
-  if (mssp != NULL) {
-    if (DISC_STATUS & cds_multi_session) { /* multi-session */
-      mssp->addr.msf.frame = cd->disc_status[3];
-      mssp->addr.msf.second = cd->disc_status[4];
-      mssp->addr.msf.minute = cd->disc_status[5];
-      mssp->addr_format = CDROM_MSF;
-      mssp->xa_flag = 1;
-    } else {
-      mssp->xa_flag = 0;
-    }
-    return 1;
-  }
-  return 0;
+       if (!FIRST_TRACK)
+               get_disc_status();
+       if (mssp != NULL) {
+               if (DISC_STATUS & cds_multi_session) {  /* multi-session */
+                       mssp->addr.msf.frame = cd->disc_status[3];
+                       mssp->addr.msf.second = cd->disc_status[4];
+                       mssp->addr.msf.minute = cd->disc_status[5];
+                       mssp->addr_format = CDROM_MSF;
+                       mssp->xa_flag = 1;
+               } else {
+                       mssp->xa_flag = 0;
+               }
+               return 1;
+       }
+       return 0;
 }
 
-int cm206_get_upc(struct cdrom_device_info * cdi, struct cdrom_mcn * mcn)
+int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
 {
-  uch upc[10];
-  char * ret = mcn->medium_catalog_number;
-  int i;
-  
-  if (type_1_command(c_read_upc, 10, upc)) return -EIO;
-  for (i=0; i<13; i++) {
-    int w=i/2+1, r=i%2;
-    if (r) ret[i] = 0x30 | (upc[w] & 0x0f);
-    else ret[i] = 0x30 | ((upc[w] >> 4) & 0x0f);
-  }
-  ret[13] = '\0';
-  return 0;
-} 
-
-int cm206_reset(struct cdrom_device_info * cdi)
+       uch upc[10];
+       char *ret = mcn->medium_catalog_number;
+       int i;
+
+       if (type_1_command(c_read_upc, 10, upc))
+               return -EIO;
+       for (i = 0; i < 13; i++) {
+               int w = i / 2 + 1, r = i % 2;
+               if (r)
+                       ret[i] = 0x30 | (upc[w] & 0x0f);
+               else
+                       ret[i] = 0x30 | ((upc[w] >> 4) & 0x0f);
+       }
+       ret[13] = '\0';
+       return 0;
+}
+
+int cm206_reset(struct cdrom_device_info *cdi)
 {
-  stop_read();
-  reset_cm260();
-  outw(dc_normal | dc_break | READ_AHEAD, r_data_control);
-  mdelay(1);                   /* 750 musec minimum */
-  outw(dc_normal | READ_AHEAD, r_data_control);
-  cd->sector_last = -1;                /* flag no data buffered */
-  cd->adapter_last = -1;    
-  invalidate_toc();
-  return 0;
+       stop_read();
+       reset_cm260();
+       outw(dc_normal | dc_break | READ_AHEAD, r_data_control);
+       mdelay(1);              /* 750 musec minimum */
+       outw(dc_normal | READ_AHEAD, r_data_control);
+       cd->sector_last = -1;   /* flag no data buffered */
+       cd->adapter_last = -1;
+       invalidate_toc();
+       return 0;
 }
 
-int cm206_select_speed(struct cdrom_device_info * cdi, int speed)
+int cm206_select_speed(struct cdrom_device_info *cdi, int speed)
 {
-  int r;
-  switch (speed) {
-  case 0: 
-    r = type_0_command(c_auto_mode, 1);
-    break;
-  case 1:
-    r = type_0_command(c_force_1x, 1);
-    break;
-  case 2:
-    r = type_0_command(c_force_2x, 1);
-    break;
-  default:
-    return -1;
-  }
-  if (r<0) return r;
-  else return 1;
+       int r;
+       switch (speed) {
+       case 0:
+               r = type_0_command(c_auto_mode, 1);
+               break;
+       case 1:
+               r = type_0_command(c_force_1x, 1);
+               break;
+       case 2:
+               r = type_0_command(c_force_2x, 1);
+               break;
+       default:
+               return -1;
+       }
+       if (r < 0)
+               return r;
+       else
+               return 1;
 }
 
 static struct cdrom_device_ops cm206_dops = {
-       open:                   cm206_open,
-       release:                cm206_release,
-       drive_status:           cm206_drive_status,
-       media_changed:          cm206_media_changed,
-       tray_move:              cm206_tray_move,
-       lock_door:              cm206_lock_door,
-       select_speed:           cm206_select_speed,
-       get_last_session:       cm206_get_last_session,
-       get_mcn:                cm206_get_upc,
-       reset:                  cm206_reset,
-       audio_ioctl:            cm206_audio_ioctl,
-       dev_ioctl:              cm206_ioctl,
-       capability:             CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
-                               CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
-                               CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED |
-                               CDC_IOCTLS | CDC_DRIVE_STATUS, 
-       n_minors:               1,
+       open:cm206_open,
+       release:cm206_release,
+       drive_status:cm206_drive_status,
+       media_changed:cm206_media_changed,
+       tray_move:cm206_tray_move,
+       lock_door:cm206_lock_door,
+       select_speed:cm206_select_speed,
+       get_last_session:cm206_get_last_session,
+       get_mcn:cm206_get_upc,
+       reset:cm206_reset,
+       audio_ioctl:cm206_audio_ioctl,
+       dev_ioctl:cm206_ioctl,
+       capability:CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
+           CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
+           CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED |
+           CDC_IOCTLS | CDC_DRIVE_STATUS,
+       n_minors:1,
 };
 
 
 static struct cdrom_device_info cm206_info = {
-       ops:            &cm206_dops,
-       speed:          2,
-       capacity:       1,
-       name:           "cm206",
+       ops:&cm206_dops,
+       speed:2,
+       capacity:1,
+       name:"cm206",
 };
 
 /* This routine gets called during initialization if things go wrong,
  * can be used in cleanup_module as well. */
 static void cleanup(int level)
 {
-  switch (level) {
-  case 4: 
-    if (unregister_cdrom(&cm206_info)) {
-      printk("Can't unregister cdrom cm206\n");
-      return;
-    }
-    if (devfs_unregister_blkdev(MAJOR_NR, "cm206")) {
-      printk("Can't unregister major cm206\n");
-      return;
-    }
-    blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-  case 3: 
-    free_irq(cm206_irq, NULL);
-  case 2: 
-  case 1: 
-    kfree(cd);
-    release_region(cm206_base, 16);
-  default:;
-  }
+       switch (level) {
+       case 4:
+               if (unregister_cdrom(&cm206_info)) {
+                       printk("Can't unregister cdrom cm206\n");
+                       return;
+               }
+               if (devfs_unregister_blkdev(MAJOR_NR, "cm206")) {
+                       printk("Can't unregister major cm206\n");
+                       return;
+               }
+               blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+       case 3:
+               free_irq(cm206_irq, NULL);
+       case 2:
+       case 1:
+               kfree(cd);
+               release_region(cm206_base, 16);
+       default:;
+       }
 }
 
 /* This function probes for the adapter card. It returns the base
@@ -1299,117 +1382,129 @@ static void cleanup(int level)
  */
 int __init probe_base_port(int base)
 {
-  int b=0x300, e=0x370;                /* this is the range of start addresses */
-  volatile int fool, i;
-
-  if (base) b=e=base;
-  for (base=b; base<=e; base += 0x10) {
-    if (check_region(base, 0x10)) continue;
-    for (i=0; i<3; i++) 
-      fool = inw(base+2); /* empty possibly uart_receive_buffer */
-    if((inw(base+6) & 0xffef) != 0x0001 || /* line_status */
-       (inw(base) & 0xad00) != 0) /* data status */
-      continue;
-    return(base);
-  }
-  return 0;
+       int b = 0x300, e = 0x370;       /* this is the range of start addresses */
+       volatile int fool, i;
+
+       if (base)
+               b = e = base;
+       for (base = b; base <= e; base += 0x10) {
+               if (check_region(base, 0x10))
+                       continue;
+               for (i = 0; i < 3; i++)
+                       fool = inw(base + 2);   /* empty possibly uart_receive_buffer */
+               if ((inw(base + 6) & 0xffef) != 0x0001 ||       /* line_status */
+                   (inw(base) & 0xad00) != 0)  /* data status */
+                       continue;
+               return (base);
+       }
+       return 0;
 }
 
 #if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
 /* Probe for irq# nr. If nr==0, probe for all possible irq's. */
-int __init probe_irq(int nr){
-  int irqs, irq;
-  outw(dc_normal | READ_AHEAD, r_data_control);        /* disable irq-generation */
-  sti(); 
-  irqs = probe_irq_on();
-  reset_cm260();               /* causes interrupt */
-  udelay(100);                 /* wait for it */
-  irq = probe_irq_off(irqs);
-  outw(dc_normal | READ_AHEAD, r_data_control);        /* services interrupt */
-  if (nr && irq!=nr && irq>0) return 0;        /* wrong interrupt happened */
-  else return irq;
+int __init probe_irq(int nr)
+{
+       int irqs, irq;
+       outw(dc_normal | READ_AHEAD, r_data_control);   /* disable irq-generation */
+       sti();
+       irqs = probe_irq_on();
+       reset_cm260();          /* causes interrupt */
+       udelay(100);            /* wait for it */
+       irq = probe_irq_off(irqs);
+       outw(dc_normal | READ_AHEAD, r_data_control);   /* services interrupt */
+       if (nr && irq != nr && irq > 0)
+               return 0;       /* wrong interrupt happened */
+       else
+               return irq;
 }
 #endif
 
 int __init cm206_init(void)
 {
-  uch e=0;
-  long int size=sizeof(struct cm206_struct);
-
-  printk(KERN_INFO "cm206 cdrom driver " REVISION);
-  cm206_base = probe_base_port(auto_probe ? 0 : cm206_base);
-  if (!cm206_base) {
-    printk(" can't find adapter!\n");
-    return -EIO;
-  }
-  printk(" adapter at 0x%x", cm206_base);
-  request_region(cm206_base, 16, "cm206");
-  cd = (struct cm206_struct *) kmalloc(size, GFP_KERNEL);
-  if (!cd) return -EIO;
-  /* Now we have found the adaptor card, try to reset it. As we have
-   * found out earlier, this process generates an interrupt as well,
-   * so we might just exploit that fact for irq probing! */
+       uch e = 0;
+       long int size = sizeof(struct cm206_struct);
+
+       printk(KERN_INFO "cm206 cdrom driver " REVISION);
+       cm206_base = probe_base_port(auto_probe ? 0 : cm206_base);
+       if (!cm206_base) {
+               printk(" can't find adapter!\n");
+               return -EIO;
+       }
+       printk(" adapter at 0x%x", cm206_base);
+       request_region(cm206_base, 16, "cm206");
+       cd = (struct cm206_struct *) kmalloc(size, GFP_KERNEL);
+       if (!cd)
+               return -EIO;
+       /* Now we have found the adaptor card, try to reset it. As we have
+        * found out earlier, this process generates an interrupt as well,
+        * so we might just exploit that fact for irq probing! */
 #if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
-  cm206_irq = probe_irq(auto_probe ? 0 : cm206_irq);   
-  if (cm206_irq<=0) {
-    printk("can't find IRQ!\n");
-    cleanup(1);
-    return -EIO;
-  }
-  else printk(" IRQ %d found\n", cm206_irq);
+       cm206_irq = probe_irq(auto_probe ? 0 : cm206_irq);
+       if (cm206_irq <= 0) {
+               printk("can't find IRQ!\n");
+               cleanup(1);
+               return -EIO;
+       } else
+               printk(" IRQ %d found\n", cm206_irq);
 #else
-  cli();
-  reset_cm260();
-  /* Now, the problem here is that reset_cm260 can generate an
-     interrupt. It seems that this can cause a kernel oops some time
-     later. So we wait a while and `service' this interrupt. */
-  mdelay(1);
-  outw(dc_normal | READ_AHEAD, r_data_control);
-  sti();
-  printk(" using IRQ %d\n", cm206_irq);
+       cli();
+       reset_cm260();
+       /* Now, the problem here is that reset_cm260 can generate an
+          interrupt. It seems that this can cause a kernel oops some time
+          later. So we wait a while and `service' this interrupt. */
+       mdelay(1);
+       outw(dc_normal | READ_AHEAD, r_data_control);
+       sti();
+       printk(" using IRQ %d\n", cm206_irq);
 #endif
-  if (send_receive_polled(c_drive_configuration) != c_drive_configuration) 
-    {
-      printk(KERN_INFO " drive not there\n");
-      cleanup(1);
-      return -EIO;
-    }
-  e = send_receive_polled(c_gimme);
-  printk(KERN_INFO "Firmware revision %d", e & dcf_revision_code);
-  if (e & dcf_transfer_rate) printk(" double");
-  else printk(" single");
-  printk(" speed drive");
-  if (e & dcf_motorized_tray) printk(", motorized tray");
-  if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206", NULL)) {
-    printk("\nUnable to reserve IRQ---aborted\n");
-    cleanup(2);
-    return -EIO;
-  }
-  printk(".\n");
-  if (devfs_register_blkdev(MAJOR_NR, "cm206", &cdrom_fops) != 0) {
-    printk(KERN_INFO "Cannot register for major %d!\n", MAJOR_NR);
-    cleanup(3);
-    return -EIO;
-  }
-  cm206_info.dev = MKDEV(MAJOR_NR,0);
-  if (register_cdrom(&cm206_info) != 0) {
-    printk(KERN_INFO "Cannot register for cdrom %d!\n", MAJOR_NR);
-    cleanup(3);
-    return -EIO;
-  }    
-  blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
-  blksize_size[MAJOR_NR] = cm206_blocksizes;
-  read_ahead[MAJOR_NR] = 16;   /* reads ahead what? */
-  init_bh(CM206_BH, cm206_bh);
-
-  memset(cd, 0, sizeof(*cd));  /* give'm some reasonable value */
-  cd->sector_last = -1;                /* flag no data buffered */
-  cd->adapter_last = -1;
-  cd->timer.function = cm206_timeout;
-  cd->max_sectors = (inw(r_data_status) & ds_ram_size) ? 24 : 97;
-  printk(KERN_INFO "%d kB adapter memory available, "  
-        " %ld bytes kernel memory used.\n", cd->max_sectors*2, size);
-  return 0;
+       if (send_receive_polled(c_drive_configuration) !=
+           c_drive_configuration) {
+               printk(KERN_INFO " drive not there\n");
+               cleanup(1);
+               return -EIO;
+       }
+       e = send_receive_polled(c_gimme);
+       printk(KERN_INFO "Firmware revision %d", e & dcf_revision_code);
+       if (e & dcf_transfer_rate)
+               printk(" double");
+       else
+               printk(" single");
+       printk(" speed drive");
+       if (e & dcf_motorized_tray)
+               printk(", motorized tray");
+       if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206", NULL)) {
+               printk("\nUnable to reserve IRQ---aborted\n");
+               cleanup(2);
+               return -EIO;
+       }
+       printk(".\n");
+       if (devfs_register_blkdev(MAJOR_NR, "cm206", &cdrom_fops) != 0) {
+               printk(KERN_INFO "Cannot register for major %d!\n",
+                      MAJOR_NR);
+               cleanup(3);
+               return -EIO;
+       }
+       cm206_info.dev = MKDEV(MAJOR_NR, 0);
+       if (register_cdrom(&cm206_info) != 0) {
+               printk(KERN_INFO "Cannot register for cdrom %d!\n",
+                      MAJOR_NR);
+               cleanup(3);
+               return -EIO;
+       }
+       blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
+       blksize_size[MAJOR_NR] = cm206_blocksizes;
+       read_ahead[MAJOR_NR] = 16;      /* reads ahead what? */
+       init_bh(CM206_BH, cm206_bh);
+
+       memset(cd, 0, sizeof(*cd));     /* give'm some reasonable value */
+       cd->sector_last = -1;   /* flag no data buffered */
+       cd->adapter_last = -1;
+       cd->timer.function = cm206_timeout;
+       cd->max_sectors = (inw(r_data_status) & ds_ram_size) ? 24 : 97;
+       printk(KERN_INFO "%d kB adapter memory available, "
+              " %ld bytes kernel memory used.\n", cd->max_sectors * 2,
+              size);
+       return 0;
 }
 
 #ifdef MODULE
@@ -1417,65 +1512,67 @@ int __init cm206_init(void)
 
 static void __init parse_options(void)
 {
-  int i;
-  for (i=0; i<2; i++) {
-    if (0x300 <= cm206[i] && i<= 0x370 && cm206[i] % 0x10 == 0) {
-      cm206_base = cm206[i];
-      auto_probe=0;
-    }
-    else if (3 <= cm206[i] && cm206[i] <= 15) {
-      cm206_irq = cm206[i];
-      auto_probe=0;
-    }
-  }
+       int i;
+       for (i = 0; i < 2; i++) {
+               if (0x300 <= cm206[i] && i <= 0x370
+                   && cm206[i] % 0x10 == 0) {
+                       cm206_base = cm206[i];
+                       auto_probe = 0;
+               } else if (3 <= cm206[i] && cm206[i] <= 15) {
+                       cm206_irq = cm206[i];
+                       auto_probe = 0;
+               }
+       }
 }
 
 int __cm206_init(void)
 {
        parse_options();
 #if !defined(AUTO_PROBE_MODULE)
-       auto_probe=0;
+       auto_probe = 0;
 #endif
        return cm206_init();
 }
 
 void __exit cm206_exit(void)
 {
-  cleanup(4);
-  printk(KERN_INFO "cm206 removed\n");
+       cleanup(4);
+       printk(KERN_INFO "cm206 removed\n");
 }
 
 module_init(__cm206_init);
 module_exit(cm206_exit);
-      
-#else /* !MODULE */
+
+#else                          /* !MODULE */
 
 /* This setup function accepts either `auto' or numbers in the range
  * 3--11 (for irq) or 0x300--0x370 (for base port) or both. */
 
 static int __init cm206_setup(char *s)
 {
-  int i, p[4];
-  
-  (void)get_options(s, ARRAY_SIZE(p), p);
-  
-  if (!strcmp(s, "auto")) auto_probe=1;
-  for(i=1; i<=p[0]; i++) {
-    if (0x300 <= p[i] && i<= 0x370 && p[i] % 0x10 == 0) {
-      cm206_base = p[i];
-      auto_probe = 0;
-    }
-    else if (3 <= p[i] && p[i] <= 15) {
-      cm206_irq = p[i];
-      auto_probe = 0;
-    }
-  }
- return 1;
+       int i, p[4];
+
+       (void) get_options(s, ARRAY_SIZE(p), p);
+
+       if (!strcmp(s, "auto"))
+               auto_probe = 1;
+       for (i = 1; i <= p[0]; i++) {
+               if (0x300 <= p[i] && i <= 0x370 && p[i] % 0x10 == 0) {
+                       cm206_base = p[i];
+                       auto_probe = 0;
+               } else if (3 <= p[i] && p[i] <= 15) {
+                       cm206_irq = p[i];
+                       auto_probe = 0;
+               }
+       }
      return 1;
 }
 
 __setup("cm206=", cm206_setup);
 
-#endif /* !MODULE */
+#endif                         /* !MODULE */
+
+
 /*
  * Local variables:
  * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -m486 -DMODULE -DMODVERSIONS -include /usr/src/linux/include/linux/modversions.h  -c -o cm206.o cm206.c"
index af8e2e33d7b7a33f0c17f6189b064887d442824f..858b0f411a188e684504de25bdbf8661c32affd4 100644 (file)
@@ -41,8 +41,8 @@
 
 */
 
-/* These settings are for various debug-level. Leave they untouched ... */ 
-#define  NO_GSCD_DEBUG 
+/* These settings are for various debug-level. Leave they untouched ... */
+#define  NO_GSCD_DEBUG
 #define  NO_IOCTL_DEBUG
 #define  NO_MODULE_DEBUG
 #define  NO_FUTURE_WORK
 
 #define MAJOR_NR GOLDSTAR_CDROM_MAJOR
 #include <linux/blk.h>
-#define gscd_port gscd /* for compatible parameter passing with "insmod" */
+#define gscd_port gscd         /* for compatible parameter passing with "insmod" */
 #include "gscd.h"
 
-static int gscd_blocksizes[1] = {512};
+static int gscd_blocksizes[1] = { 512 };
 
-static int gscdPresent            = 0;
+static int gscdPresent = 0;
 
-static unsigned char gscd_buf[2048];    /* buffer for block size conversion */
-static int   gscd_bn              = -1;
-static short gscd_port            = GSCD_BASE_ADDR;
+static unsigned char gscd_buf[2048];   /* buffer for block size conversion */
+static int gscd_bn = -1;
+static short gscd_port = GSCD_BASE_ADDR;
 MODULE_PARM(gscd, "h");
 
 /* Kommt spaeter vielleicht noch mal dran ...
  *    static DECLARE_WAIT_QUEUE_HEAD(gscd_waitq);
- */ 
+ */
 
-static void gscd_transfer         (void);
-static void gscd_read_cmd         (void);
-static void gscd_hsg2msf          (long hsg, struct msf *msf);
-static void gscd_bin2bcd          (unsigned char *p);
+static void gscd_transfer(void);
+static void gscd_read_cmd(void);
+static void gscd_hsg2msf(long hsg, struct msf *msf);
+static void gscd_bin2bcd(unsigned char *p);
 
 /* Schnittstellen zum Kern/FS */
 
-static void do_gscd_request       (request_queue_t *);
-static void __do_gscd_request     (unsigned long dummy);
-static int  gscd_ioctl            (struct inode *, struct file *, unsigned int, unsigned long);
-static int  gscd_open             (struct inode *, struct file *);
-static int  gscd_release          (struct inode *, struct file *);
-static int  check_gscd_med_chg    (kdev_t);
+static void do_gscd_request(request_queue_t *);
+static void __do_gscd_request(unsigned long dummy);
+static int gscd_ioctl(struct inode *, struct file *, unsigned int,
+                     unsigned long);
+static int gscd_open(struct inode *, struct file *);
+static int gscd_release(struct inode *, struct file *);
+static int check_gscd_med_chg(kdev_t);
 
 /*      GoldStar Funktionen    */
 
-static void cc_Reset             (void);
-static int  wait_drv_ready       (void);
-static int  find_drives          (void);
-static void cmd_out              (int, char *, char *, int);
-static void cmd_status           (void);
-static void cc_Ident             (char *);
-static void cc_SetSpeed          (void);
-static void init_cd_drive        (int);
+static void cc_Reset(void);
+static int wait_drv_ready(void);
+static int find_drives(void);
+static void cmd_out(int, char *, char *, int);
+static void cmd_status(void);
+static void cc_Ident(char *);
+static void cc_SetSpeed(void);
+static void init_cd_drive(int);
 
-static int  get_status           (void);
-static void clear_Audio          (void);
-static void cc_invalidate        (void);
+static int get_status(void);
+static void clear_Audio(void);
+static void cc_invalidate(void);
 
 /* some things for the next version */
 #ifdef FUTURE_WORK
-static void update_state          (void);
-static long gscd_msf2hsg          (struct msf *mp);
-static int  gscd_bcd2bin          (unsigned char bcd);
+static void update_state(void);
+static long gscd_msf2hsg(struct msf *mp);
+static int gscd_bcd2bin(unsigned char bcd);
 #endif
 
 /*    common GoldStar Initialization    */
 
-static int my_gscd_init (void);
+static int my_gscd_init(void);
 
 
 /*      lo-level cmd-Funktionen    */
 
-static void cmd_info_in          ( char *, int );
-static void cmd_end              ( void );
-static void cmd_read_b           ( char *, int, int );
-static void cmd_read_w           ( char *, int, int );
-static int  cmd_unit_alive       ( void );
-static void cmd_write_cmd        ( char * );
+static void cmd_info_in(char *, int);
+static void cmd_end(void);
+static void cmd_read_b(char *, int, int);
+static void cmd_read_w(char *, int, int);
+static int cmd_unit_alive(void);
+static void cmd_write_cmd(char *);
 
 
 /*      GoldStar Variablen     */
 
-static int  curr_drv_state;
-static int  drv_states[]       = {0,0,0,0,0,0,0,0};
-static int  drv_mode;
-static int  disk_state;
-static int  speed;
-static int  ndrives;
+static int curr_drv_state;
+static int drv_states[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+static int drv_mode;
+static int disk_state;
+static int speed;
+static int ndrives;
 
 static unsigned char drv_num_read;
 static unsigned char f_dsk_valid;
@@ -155,93 +156,91 @@ static unsigned char f_drv_ok;
 
 static char f_AudioPlay;
 static char f_AudioPause;
-static int  AudioStart_m;
-static int  AudioStart_f;
-static int  AudioEnd_m;
-static int  AudioEnd_f;
+static int AudioStart_m;
+static int AudioStart_f;
+static int AudioEnd_m;
+static int AudioEnd_f;
+
 static struct timer_list gscd_timer;
 
 static struct block_device_operations gscd_fops = {
-       open:                   gscd_open,
-       release:                gscd_release,
-       ioctl:                  gscd_ioctl,
-       check_media_change:     check_gscd_med_chg,
+       open:gscd_open,
+       release:gscd_release,
+       ioctl:gscd_ioctl,
+       check_media_change:check_gscd_med_chg,
 };
 
 /* 
  * Checking if the media has been changed
  * (not yet implemented)
  */
-static int check_gscd_med_chg (kdev_t full_dev)
+static int check_gscd_med_chg(kdev_t full_dev)
 {
-   int target;
+       int target;
 
 
-   target = MINOR(full_dev);
+       target = MINOR(full_dev);
 
-   if (target > 0) 
-   {
-      printk("GSCD: GoldStar CD-ROM request error: invalid device.\n");
-      return 0;
-   }
+       if (target > 0) {
+               printk
+                   ("GSCD: GoldStar CD-ROM request error: invalid device.\n");
+               return 0;
+       }
+#ifdef GSCD_DEBUG
+       printk("gscd: check_med_change\n");
+#endif
 
-   #ifdef GSCD_DEBUG
-   printk ("gscd: check_med_change\n");
-   #endif
-  return 0;
+       return 0;
 }
 
 
 #ifndef MODULE
 /* Using new interface for kernel-parameters */
-  
-static int __init gscd_setup (char *str)
+
+static int __init gscd_setup(char *str)
 {
-  int ints[2];
-  (void)get_options(str, ARRAY_SIZE(ints), ints);
-  
-  if (ints[0] > 0) 
-  {
-     gscd_port = ints[1];
-  }
- return 1;
+       int ints[2];
+       (void) get_options(str, ARRAY_SIZE(ints), ints);
+
+       if (ints[0] > 0) {
+               gscd_port = ints[1];
+       }
+       return 1;
 }
 
 __setup("gscd=", gscd_setup);
 
 #endif
 
-static int gscd_ioctl (struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
+static int gscd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
+                     unsigned long arg)
 {
-unsigned char to_do[10];
-unsigned char dummy;
+       unsigned char to_do[10];
+       unsigned char dummy;
 
-                             
-    switch (cmd)
-    {
-       case CDROMSTART:     /* Spin up the drive */
+
+       switch (cmd) {
+       case CDROMSTART:        /* Spin up the drive */
                /* Don't think we can do this.  Even if we could,
-                * I think the drive times out and stops after a while
+                * I think the drive times out and stops after a while
                 * anyway.  For now, ignore it.
                 */
-            return 0;
+               return 0;
 
-       case CDROMRESUME:   /* keine Ahnung was das ist */
-            return 0;
+       case CDROMRESUME:       /* keine Ahnung was das ist */
+               return 0;
 
 
-       case CDROMEJECT:
-            cmd_status ();
-            to_do[0] = CMD_TRAY_CTL;
-            cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
+       case CDROMEJECT:
+               cmd_status();
+               to_do[0] = CMD_TRAY_CTL;
+               cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
 
-            return 0;
+               return 0;
 
-       default:
-            return -EINVAL;
-    }
+       default:
+               return -EINVAL;
+       }
 
 }
 
@@ -251,17 +250,16 @@ unsigned char dummy;
  * When Linux gets variable block sizes this will probably go away.
  */
 
-static void gscd_transfer (void)
+static void gscd_transfer(void)
 {
-long offs;
-
-       while (CURRENT -> nr_sectors > 0 && gscd_bn == CURRENT -> sector / 4)
-       {
-               offs = (CURRENT -> sector & 3) * 512;
-               memcpy(CURRENT -> buffer, gscd_buf + offs, 512);
-               CURRENT -> nr_sectors--;
-               CURRENT -> sector++;
-               CURRENT -> buffer += 512;
+       long offs;
+
+       while (CURRENT->nr_sectors > 0 && gscd_bn == CURRENT->sector / 4) {
+               offs = (CURRENT->sector & 3) * 512;
+               memcpy(CURRENT->buffer, gscd_buf + offs, 512);
+               CURRENT->nr_sectors--;
+               CURRENT->sector++;
+               CURRENT->buffer += 512;
        }
 }
 
@@ -270,17 +268,17 @@ long offs;
  * I/O request routine called from Linux kernel.
  */
 
-static void do_gscd_request (request_queue_t * q)
+static void do_gscd_request(request_queue_t * q)
 {
-  __do_gscd_request(0);
+       __do_gscd_request(0);
 }
 
-static void __do_gscd_request (unsigned long dummy)
+static void __do_gscd_request(unsigned long dummy)
 {
-unsigned int block,dev;
-unsigned int nsect;
+       unsigned int block, dev;
+       unsigned int nsect;
 
-repeat:
+      repeat:
        if (QUEUE_EMPTY || CURRENT->rq_status == RQ_INACTIVE)
                goto out;
        INIT_REQUEST;
@@ -288,18 +286,16 @@ repeat:
        block = CURRENT->sector;
        nsect = CURRENT->nr_sectors;
 
-       if (QUEUE_EMPTY || CURRENT -> sector == -1)
+       if (QUEUE_EMPTY || CURRENT->sector == -1)
                goto out;
 
-       if (CURRENT -> cmd != READ)
-       {
-               printk("GSCD: bad cmd %d\n", CURRENT -> cmd);
+       if (CURRENT->cmd != READ) {
+               printk("GSCD: bad cmd %d\n", CURRENT->cmd);
                end_request(0);
                goto repeat;
        }
 
-       if (MINOR(CURRENT -> rq_dev) != 0)
-       {
+       if (MINOR(CURRENT->rq_dev) != 0) {
                printk("GSCD: this version supports only one device\n");
                end_request(0);
                goto repeat;
@@ -309,18 +305,16 @@ repeat:
 
        /* if we satisfied the request from the buffer, we're done. */
 
-       if (CURRENT -> nr_sectors == 0)
-       {
+       if (CURRENT->nr_sectors == 0) {
                end_request(1);
                goto repeat;
        }
-
 #ifdef GSCD_DEBUG
-        printk ("GSCD: dev %d, block %d, nsect %d\n", dev, block, nsect );
+       printk("GSCD: dev %d, block %d, nsect %d\n", dev, block, nsect);
 #endif
 
-       gscd_read_cmd ();
-out:
+       gscd_read_cmd();
+      out:
        return;
 }
 
@@ -331,47 +325,42 @@ out:
  * read-data command.
  */
 
-static void
-gscd_read_cmd (void)
+static void gscd_read_cmd(void)
 {
-long   block;
-struct gscd_Play_msf gscdcmd;
-char   cmd[] = { CMD_READ, 0x80, 0,0,0, 0,1 }; /* cmd mode M-S-F secth sectl */
-
-
-
-        cmd_status ();
-        if ( disk_state & (ST_NO_DISK | ST_DOOR_OPEN) )
-        {
-           printk ( "GSCD: no disk or door open\n" );
-           end_request (0);
-        }
-        else
-        {
-           if ( disk_state & ST_INVALID )
-           {
-              printk ( "GSCD: disk invalid\n" );
-              end_request (0);
-           }
-           else
-           {
-              gscd_bn = -1;            /* purge our buffer */
-              block = CURRENT -> sector / 4;
-              gscd_hsg2msf(block, &gscdcmd.start);     /* cvt to msf format */
-
-              cmd[2] = gscdcmd.start.min;
-              cmd[3] = gscdcmd.start.sec;
-              cmd[4] = gscdcmd.start.frame;
+       long block;
+       struct gscd_Play_msf gscdcmd;
+       char cmd[] = { CMD_READ, 0x80, 0, 0, 0, 0, 1 }; /* cmd mode M-S-F secth sectl */
+
+
+
+       cmd_status();
+       if (disk_state & (ST_NO_DISK | ST_DOOR_OPEN)) {
+               printk("GSCD: no disk or door open\n");
+               end_request(0);
+       } else {
+               if (disk_state & ST_INVALID) {
+                       printk("GSCD: disk invalid\n");
+                       end_request(0);
+               } else {
+                       gscd_bn = -1;   /* purge our buffer */
+                       block = CURRENT->sector / 4;
+                       gscd_hsg2msf(block, &gscdcmd.start);    /* cvt to msf format */
+
+                       cmd[2] = gscdcmd.start.min;
+                       cmd[3] = gscdcmd.start.sec;
+                       cmd[4] = gscdcmd.start.frame;
 
 #ifdef GSCD_DEBUG
-              printk ("GSCD: read msf %d:%d:%d\n", cmd[2], cmd[3], cmd[4] ); 
-#endif 
-              cmd_out ( TYPE_DATA, (char *)&cmd, (char *)&gscd_buf[0], 1 );
-        
-              gscd_bn = CURRENT -> sector / 4;
-              gscd_transfer();
-              end_request(1);
-          }
+                       printk("GSCD: read msf %d:%d:%d\n", cmd[2], cmd[3],
+                              cmd[4]);
+#endif
+                       cmd_out(TYPE_DATA, (char *) &cmd,
+                               (char *) &gscd_buf[0], 1);
+
+                       gscd_bn = CURRENT->sector / 4;
+                       gscd_transfer();
+                       end_request(1);
+               }
        }
        SET_TIMER(__do_gscd_request, 1);
 }
@@ -381,28 +370,27 @@ char   cmd[] = { CMD_READ, 0x80, 0,0,0, 0,1 }; /* cmd mode M-S-F secth sectl */
  * Open the device special file.  Check that a disk is in.
  */
 
-static int gscd_open (struct inode *ip, struct file *fp)
+static int gscd_open(struct inode *ip, struct file *fp)
 {
-int   st;
+       int st;
 
 #ifdef GSCD_DEBUG
-printk ( "GSCD: open\n" );
+       printk("GSCD: open\n");
 #endif
 
        if (gscdPresent == 0)
-               return -ENXIO;                  /* no hardware */
+               return -ENXIO;  /* no hardware */
 
        MOD_INC_USE_COUNT;
 
-        get_status ();
-        st = disk_state & (ST_NO_DISK | ST_DOOR_OPEN);
-        if ( st )
-        {
-           printk ( "GSCD: no disk or door open\n" );
-           MOD_DEC_USE_COUNT;
-           return -ENXIO;
-        }
-                   
+       get_status();
+       st = disk_state & (ST_NO_DISK | ST_DOOR_OPEN);
+       if (st) {
+               printk("GSCD: no disk or door open\n");
+               MOD_DEC_USE_COUNT;
+               return -ENXIO;
+       }
+
 /*     if (updateToc() < 0)
                return -EIO;
 */
@@ -415,11 +403,11 @@ printk ( "GSCD: open\n" );
  * On close, we flush all gscd blocks from the buffer cache.
  */
 
-static int gscd_release (struct inode * inode, struct file * file)
+static int gscd_release(struct inode *inode, struct file *file)
 {
 
 #ifdef GSCD_DEBUG
-printk ( "GSCD: release\n" );
+       printk("GSCD: release\n");
 #endif
 
        gscd_bn = -1;
@@ -429,692 +417,642 @@ printk ( "GSCD: release\n" );
 }
 
 
-int get_status (void)
+int get_status(void)
 {
-int  status;
-
-    cmd_status ();
-    status = disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01);
-     
-    if ( status == (ST_x08 | ST_x04 | ST_INVALID | ST_x01) )
-    {
-       cc_invalidate ();
-       return 1;
-    }
-    else
-    {
-       return 0;
-    }
+       int status;
+
+       cmd_status();
+       status = disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01);
+
+       if (status == (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) {
+               cc_invalidate();
+               return 1;
+       } else {
+               return 0;
+       }
 }
 
 
-void cc_invalidate (void)
+void cc_invalidate(void)
 {
-   drv_num_read  = 0xFF;
-   f_dsk_valid   = 0xFF;
-   current_drive = 0xFF;
-   f_drv_ok      = 0xFF;
+       drv_num_read = 0xFF;
+       f_dsk_valid = 0xFF;
+       current_drive = 0xFF;
+       f_drv_ok = 0xFF;
 
-   clear_Audio ();
-   
-}   
+       clear_Audio();
+
+}
 
-void clear_Audio (void)
+void clear_Audio(void)
 {
 
-   f_AudioPlay = 0;
-   f_AudioPause = 0;
-   AudioStart_m = 0;
-   AudioStart_f = 0;
-   AudioEnd_m   = 0;
-   AudioEnd_f   = 0;
-   
+       f_AudioPlay = 0;
+       f_AudioPause = 0;
+       AudioStart_m = 0;
+       AudioStart_f = 0;
+       AudioEnd_m = 0;
+       AudioEnd_f = 0;
+
 }
 
 /*
  *   waiting ?  
  */
 
-int wait_drv_ready (void)
+int wait_drv_ready(void)
 {
-int found, read;
-
-   do
-   {  
-       found = inb ( GSCDPORT(0) ); 
-       found &= 0x0f;
-       read  = inb ( GSCDPORT(0) );
-       read  &= 0x0f;
-   } while ( read != found );
-   
+       int found, read;
+
+       do {
+               found = inb(GSCDPORT(0));
+               found &= 0x0f;
+               read = inb(GSCDPORT(0));
+               read &= 0x0f;
+       } while (read != found);
+
 #ifdef GSCD_DEBUG
-printk ( "Wait for: %d\n", read );
-#endif   
-   
-   return read;
+       printk("Wait for: %d\n", read);
+#endif
+
+       return read;
 }
 
-void cc_Ident (char * respons)
+void cc_Ident(char *respons)
 {
-char to_do [] = {CMD_IDENT, 0, 0};
+       char to_do[] = { CMD_IDENT, 0, 0 };
 
-    cmd_out (TYPE_INFO, (char *)&to_do, (char *)respons, (int)0x1E );
+       cmd_out(TYPE_INFO, (char *) &to_do, (char *) respons, (int) 0x1E);
 
 }
 
-void cc_SetSpeed (void)
+void cc_SetSpeed(void)
 {
-char to_do [] = {CMD_SETSPEED, 0, 0};
-char dummy;
-
-    if ( speed > 0 )
-    {
-       to_do[1] = speed & 0x0F;
-       cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
-    }
+       char to_do[] = { CMD_SETSPEED, 0, 0 };
+       char dummy;
+
+       if (speed > 0) {
+               to_do[1] = speed & 0x0F;
+               cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
+       }
 }
 
 
-void cc_Reset (void)
+void cc_Reset(void)
 {
-char to_do [] = {CMD_RESET, 0};
-char dummy;
+       char to_do[] = { CMD_RESET, 0 };
+       char dummy;
 
-   cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
+       cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
 }
 
 
 
-void cmd_status (void)
+void cmd_status(void)
 {
-char to_do [] = {CMD_STATUS, 0};
-char dummy;
+       char to_do[] = { CMD_STATUS, 0 };
+       char dummy;
 
-   cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
+       cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
 
 #ifdef GSCD_DEBUG
-printk ("GSCD: Status: %d\n", disk_state );
+       printk("GSCD: Status: %d\n", disk_state);
 #endif
 
 }
 
-void cmd_out ( int cmd_type, char * cmd, char * respo_buf, int respo_count )
+void cmd_out(int cmd_type, char *cmd, char *respo_buf, int respo_count)
 {
-int        result;
-
-
-       result = wait_drv_ready ();
-       if ( result != drv_mode )
-       {
-       unsigned long test_loops = 0xFFFF;
-       int           i,dummy;
-
-          outb ( curr_drv_state, GSCDPORT(0));
-          
-          /* LOCLOOP_170 */
-          do
-          {
-             result = wait_drv_ready ();
-             test_loops--;
-          } while ( (result != drv_mode) && (test_loops > 0) );
-
-          if ( result != drv_mode )
-          {
-             disk_state = ST_x08 | ST_x04 | ST_INVALID;
-             return;
-          }          
-        
-          /* ...and waiting */
-          for ( i=1,dummy=1 ; i<0xFFFF ; i++ )
-          {
-             dummy *= i;
-          }              
-       }
-
-       /* LOC_172 */    
-       /* check the unit */
-       /* and wake it up */
-       if ( cmd_unit_alive () != 0x08 )
-       {
-          /* LOC_174 */
-          /* game over for this unit */
-          disk_state = ST_x08 | ST_x04 | ST_INVALID;
-          return;
-       }
-       
-       /* LOC_176 */
-       #ifdef GSCD_DEBUG
-        printk ("LOC_176 ");
-       #endif       
-       if ( drv_mode == 0x09 )
-       {
-          /* magic... */
-          printk ("GSCD: magic ...\n");       
-          outb ( result, GSCDPORT(2));
-       }
-
-       /* write the command to the drive */
-       cmd_write_cmd (cmd);
-
-       /* LOC_178 */
-       for (;;)
-       {
-          result = wait_drv_ready ();
-          if ( result != drv_mode )
-          {
-             /* LOC_179 */
-             if ( result == 0x04 )                  /* Mode 4 */
-             {
-                /* LOC_205 */
-                #ifdef GSCD_DEBUG
-                printk ("LOC_205 ");                 
-                #endif
-                disk_state = inb ( GSCDPORT (2));
-             
-                do
-                {
-                   result = wait_drv_ready ();
-                } while ( result != drv_mode );
-                return;
-
-             }
-             else
-             {
-                if ( result == 0x06 )               /* Mode 6 */
-                {
-                   /* LOC_181 */
-                   #ifdef GSCD_DEBUG
-                    printk ("LOC_181 ");                     
-                   #endif
-
-                   if (cmd_type == TYPE_DATA)
-                   {
-                      /* read data */
-                      /* LOC_184 */
-                      if ( drv_mode == 9 )
-                      {
-                         /* read the data to the buffer (word) */
-                         /* (*(cmd+1))?(CD_FRAMESIZE/2):(CD_FRAMESIZE_RAW/2) */
-                         cmd_read_w ( respo_buf, respo_count, CD_FRAMESIZE/2 );
-                         return;
-                      } 
-                      else
-                      { 
-                         /* read the data to the buffer (byte) */
-                         
-                         /* (*(cmd+1))?(CD_FRAMESIZE):(CD_FRAMESIZE_RAW)    */
-                         cmd_read_b ( respo_buf, respo_count, CD_FRAMESIZE );
-                         return;
-                      }
-                   }
-                   else
-                   { 
-                      /* read the info to the buffer */
-                      cmd_info_in ( respo_buf, respo_count ); 
-                      return;
-                   }                  
-
-                   return;
-                }
-             }
-
-          }
-          else
-          {
-             disk_state = ST_x08 | ST_x04 | ST_INVALID;         
-             return;
-          }    
-       } /* for (;;) */
+       int result;
 
 
+       result = wait_drv_ready();
+       if (result != drv_mode) {
+               unsigned long test_loops = 0xFFFF;
+               int i, dummy;
+
+               outb(curr_drv_state, GSCDPORT(0));
+
+               /* LOCLOOP_170 */
+               do {
+                       result = wait_drv_ready();
+                       test_loops--;
+               } while ((result != drv_mode) && (test_loops > 0));
+
+               if (result != drv_mode) {
+                       disk_state = ST_x08 | ST_x04 | ST_INVALID;
+                       return;
+               }
+
+               /* ...and waiting */
+               for (i = 1, dummy = 1; i < 0xFFFF; i++) {
+                       dummy *= i;
+               }
+       }
+
+       /* LOC_172 */
+       /* check the unit */
+       /* and wake it up */
+       if (cmd_unit_alive() != 0x08) {
+               /* LOC_174 */
+               /* game over for this unit */
+               disk_state = ST_x08 | ST_x04 | ST_INVALID;
+               return;
+       }
+
+       /* LOC_176 */
+#ifdef GSCD_DEBUG
+       printk("LOC_176 ");
+#endif
+       if (drv_mode == 0x09) {
+               /* magic... */
+               printk("GSCD: magic ...\n");
+               outb(result, GSCDPORT(2));
+       }
+
+       /* write the command to the drive */
+       cmd_write_cmd(cmd);
+
+       /* LOC_178 */
+       for (;;) {
+               result = wait_drv_ready();
+               if (result != drv_mode) {
+                       /* LOC_179 */
+                       if (result == 0x04) {   /* Mode 4 */
+                               /* LOC_205 */
+#ifdef GSCD_DEBUG
+                               printk("LOC_205 ");
+#endif
+                               disk_state = inb(GSCDPORT(2));
+
+                               do {
+                                       result = wait_drv_ready();
+                               } while (result != drv_mode);
+                               return;
+
+                       } else {
+                               if (result == 0x06) {   /* Mode 6 */
+                                       /* LOC_181 */
 #ifdef GSCD_DEBUG
-printk ("\n");       
-#endif    
+                                       printk("LOC_181 ");
+#endif
+
+                                       if (cmd_type == TYPE_DATA) {
+                                               /* read data */
+                                               /* LOC_184 */
+                                               if (drv_mode == 9) {
+                                                       /* read the data to the buffer (word) */
+
+                                                       /* (*(cmd+1))?(CD_FRAMESIZE/2):(CD_FRAMESIZE_RAW/2) */
+                                                       cmd_read_w
+                                                           (respo_buf,
+                                                            respo_count,
+                                                            CD_FRAMESIZE /
+                                                            2);
+                                                       return;
+                                               } else {
+                                                       /* read the data to the buffer (byte) */
+
+                                                       /* (*(cmd+1))?(CD_FRAMESIZE):(CD_FRAMESIZE_RAW)    */
+                                                       cmd_read_b
+                                                           (respo_buf,
+                                                            respo_count,
+                                                            CD_FRAMESIZE);
+                                                       return;
+                                               }
+                                       } else {
+                                               /* read the info to the buffer */
+                                               cmd_info_in(respo_buf,
+                                                           respo_count);
+                                               return;
+                                       }
+
+                                       return;
+                               }
+                       }
+
+               } else {
+                       disk_state = ST_x08 | ST_x04 | ST_INVALID;
+                       return;
+               }
+       }                       /* for (;;) */
+
+
+#ifdef GSCD_DEBUG
+       printk("\n");
+#endif
 }
 
 
-static void cmd_write_cmd ( char *pstr )
+static void cmd_write_cmd(char *pstr)
 {
-int  i,j;
-
-    /* LOC_177 */
-    #ifdef GSCD_DEBUG
-     printk ("LOC_177 ");       
-    #endif
-       
-    /* calculate the number of parameter */
-    j = *pstr & 0x0F;
-
-    /* shift it out */
-    for ( i=0 ; i<j ; i++ )
-    {
-       outb ( *pstr, GSCDPORT(2) );
-       pstr++;
-    }
+       int i, j;
+
+       /* LOC_177 */
+#ifdef GSCD_DEBUG
+       printk("LOC_177 ");
+#endif
+
+       /* calculate the number of parameter */
+       j = *pstr & 0x0F;
+
+       /* shift it out */
+       for (i = 0; i < j; i++) {
+               outb(*pstr, GSCDPORT(2));
+               pstr++;
+       }
 }
 
 
-static int cmd_unit_alive ( void )
+static int cmd_unit_alive(void)
 {
-int            result;
-unsigned long  max_test_loops;
+       int result;
+       unsigned long max_test_loops;
+
 
+       /* LOC_172 */
+#ifdef GSCD_DEBUG
+       printk("LOC_172 ");
+#endif
 
-    /* LOC_172 */
-    #ifdef GSCD_DEBUG
-     printk ("LOC_172 ");       
-    #endif
+       outb(curr_drv_state, GSCDPORT(0));
+       max_test_loops = 0xFFFF;
 
-    outb ( curr_drv_state, GSCDPORT(0));       
-    max_test_loops = 0xFFFF;
-     
-    do
-    {
-       result = wait_drv_ready ();
-       max_test_loops--;
-    } while ( (result != 0x08) && (max_test_loops > 0) );
+       do {
+               result = wait_drv_ready();
+               max_test_loops--;
+       } while ((result != 0x08) && (max_test_loops > 0));
 
-    return result;
-}       
+       return result;
+}
 
 
-static void cmd_info_in ( char *pb, int count )
+static void cmd_info_in(char *pb, int count)
 {
-int   result;
-char  read;
-
-
-        /* read info */
-        /* LOC_182 */
-        #ifdef GSCD_DEBUG
-         printk ("LOC_182 ");                                        
-        #endif
-       
-        do
-        {
-           read = inb (GSCDPORT(2)); 
-           if ( count > 0 )
-           {
-              *pb = read;
-              pb++;
-              count--;
-           }
-                         
-           /* LOC_183 */
-           do
-           {
-              result = wait_drv_ready ();
-           } while ( result == 0x0E );
-        } while ( result == 6 );                     
-
-        cmd_end ();
-        return;
+       int result;
+       char read;
+
+
+       /* read info */
+       /* LOC_182 */
+#ifdef GSCD_DEBUG
+       printk("LOC_182 ");
+#endif
+
+       do {
+               read = inb(GSCDPORT(2));
+               if (count > 0) {
+                       *pb = read;
+                       pb++;
+                       count--;
+               }
+
+               /* LOC_183 */
+               do {
+                       result = wait_drv_ready();
+               } while (result == 0x0E);
+       } while (result == 6);
+
+       cmd_end();
+       return;
 }
 
 
-static void cmd_read_b ( char *pb, int count, int size )
+static void cmd_read_b(char *pb, int count, int size)
 {
-int  result;
-int  i;
-                     
-                     
-       /* LOC_188 */
-       /* LOC_189 */
-       #ifdef GSCD_DEBUG
-        printk ("LOC_189 ");                                 
-       #endif
-
-       do 
-       {
-          do
-          {
-             result = wait_drv_ready ();
-          } while ( result != 6 || result == 0x0E );
-                         
-          if ( result != 6 )
-          {
-             cmd_end ();
-             return;
-          }                       
-          
-          #ifdef GSCD_DEBUG
-           printk ("LOC_191 ");       
-          #endif
-
-          for ( i=0 ; i< size ; i++ )
-          {
-             *pb = inb (GSCDPORT(2));
-             pb++;
-          }
-          count--;
-       } while ( count > 0 );
-       
-       cmd_end ();
-       return;
+       int result;
+       int i;
+
+
+       /* LOC_188 */
+       /* LOC_189 */
+#ifdef GSCD_DEBUG
+       printk("LOC_189 ");
+#endif
+
+       do {
+               do {
+                       result = wait_drv_ready();
+               } while (result != 6 || result == 0x0E);
+
+               if (result != 6) {
+                       cmd_end();
+                       return;
+               }
+#ifdef GSCD_DEBUG
+               printk("LOC_191 ");
+#endif
+
+               for (i = 0; i < size; i++) {
+                       *pb = inb(GSCDPORT(2));
+                       pb++;
+               }
+               count--;
+       } while (count > 0);
+
+       cmd_end();
+       return;
 }
 
 
-static void cmd_end (void)
+static void cmd_end(void)
 {
-int   result;
-
-
-      /* LOC_204 */
-      #ifdef GSCD_DEBUG
-       printk ("LOC_204 ");                                          
-      #endif
-      
-      do
-      {
-         result = wait_drv_ready ();
-         if ( result == drv_mode )
-         {
-            return;
-         }
-      } while ( result != 4 );
-
-      /* LOC_205 */
-      #ifdef GSCD_DEBUG
-       printk ("LOC_205 ");                                  
-      #endif
-       
-      disk_state = inb ( GSCDPORT (2));
-             
-      do
-      {
-         result = wait_drv_ready ();
-      } while ( result != drv_mode );
-      return;
+       int result;
+
+
+       /* LOC_204 */
+#ifdef GSCD_DEBUG
+       printk("LOC_204 ");
+#endif
+
+       do {
+               result = wait_drv_ready();
+               if (result == drv_mode) {
+                       return;
+               }
+       } while (result != 4);
+
+       /* LOC_205 */
+#ifdef GSCD_DEBUG
+       printk("LOC_205 ");
+#endif
+
+       disk_state = inb(GSCDPORT(2));
+
+       do {
+               result = wait_drv_ready();
+       } while (result != drv_mode);
+       return;
 
 }
 
 
-static void cmd_read_w ( char *pb, int count, int size )
+static void cmd_read_w(char *pb, int count, int size)
 {
-int  result;
-int  i;
-
-
-    #ifdef GSCD_DEBUG
-     printk ("LOC_185 ");                                    
-    #endif
-    do 
-    {
-       /* LOC_185 */
-       do
-       {
-          result = wait_drv_ready ();
-       } while ( result != 6 || result == 0x0E );
-                         
-       if ( result != 6 )
-       {
-          cmd_end ();
-          return;
-       }                       
-                         
-       for ( i=0 ; i<size ; i++ )
-       {
-           /* na, hier muss ich noch mal drueber nachdenken */
-           *pb = inw(GSCDPORT(2));
-           pb++;
-        }
-        count--;
-     } while ( count > 0 );
-                    
-     cmd_end ();
-     return;
+       int result;
+       int i;
+
+
+#ifdef GSCD_DEBUG
+       printk("LOC_185 ");
+#endif
+
+       do {
+               /* LOC_185 */
+               do {
+                       result = wait_drv_ready();
+               } while (result != 6 || result == 0x0E);
+
+               if (result != 6) {
+                       cmd_end();
+                       return;
+               }
+
+               for (i = 0; i < size; i++) {
+                       /* na, hier muss ich noch mal drueber nachdenken */
+                       *pb = inw(GSCDPORT(2));
+                       pb++;
+               }
+               count--;
+       } while (count > 0);
+
+       cmd_end();
+       return;
 }
 
-int __init find_drives (void)
+int __init find_drives(void)
 {
-int *pdrv;
-int drvnum;
-int subdrv;
-int i;
-
-    speed           = 0;
-    pdrv            = (int *)&drv_states;
-    curr_drv_state  = 0xFE;
-    subdrv          = 0;
-    drvnum          = 0;
-
-    for ( i=0 ; i<8 ; i++ )
-    { 
-       subdrv++;
-       cmd_status ();
-       disk_state &= ST_x08 | ST_x04 | ST_INVALID | ST_x01;
-       if ( disk_state != (ST_x08 | ST_x04 | ST_INVALID) )
-       {
-          /* LOC_240 */
-          *pdrv = curr_drv_state;
-          init_cd_drive (drvnum);
-          pdrv++;
-          drvnum++;
-       }
-       else
-       {
-          if ( subdrv < 2 )
-          {
-             continue;
-          }
-          else
-          {
-             subdrv = 0;
-          }
-       }   
-
-/*       curr_drv_state<<1;         <-- das geht irgendwie nicht */ 
+       int *pdrv;
+       int drvnum;
+       int subdrv;
+       int i;
+
+       speed = 0;
+       pdrv = (int *) &drv_states;
+       curr_drv_state = 0xFE;
+       subdrv = 0;
+       drvnum = 0;
+
+       for (i = 0; i < 8; i++) {
+               subdrv++;
+               cmd_status();
+               disk_state &= ST_x08 | ST_x04 | ST_INVALID | ST_x01;
+               if (disk_state != (ST_x08 | ST_x04 | ST_INVALID)) {
+                       /* LOC_240 */
+                       *pdrv = curr_drv_state;
+                       init_cd_drive(drvnum);
+                       pdrv++;
+                       drvnum++;
+               } else {
+                       if (subdrv < 2) {
+                               continue;
+                       } else {
+                               subdrv = 0;
+                       }
+               }
+
+/*       curr_drv_state<<1;         <-- das geht irgendwie nicht */
 /* muss heissen:    curr_drv_state <<= 1; (ist ja Wert-Zuweisung) */
-         curr_drv_state *= 2;
-         curr_drv_state |= 1;
+               curr_drv_state *= 2;
+               curr_drv_state |= 1;
 #ifdef GSCD_DEBUG
-         printk ("DriveState: %d\n", curr_drv_state );
+               printk("DriveState: %d\n", curr_drv_state);
 #endif
-    } 
+       }
 
-    ndrives = drvnum;
-    return drvnum;
-}    
+       ndrives = drvnum;
+       return drvnum;
+}
 
-void __init init_cd_drive ( int num )
+void __init init_cd_drive(int num)
 {
-char resp [50];
-int  i;
+       char resp[50];
+       int i;
 
-   printk ("GSCD: init unit %d\n", num );
-   cc_Ident ((char *)&resp);
+       printk("GSCD: init unit %d\n", num);
+       cc_Ident((char *) &resp);
 
-   printk ("GSCD: identification: ");
-   for ( i=0 ; i<0x1E; i++ )
-   {
-      printk ( "%c", resp[i] );
-   }
-   printk ("\n");
-   
-   cc_SetSpeed ();  
+       printk("GSCD: identification: ");
+       for (i = 0; i < 0x1E; i++) {
+               printk("%c", resp[i]);
+       }
+       printk("\n");
 
-}    
+       cc_SetSpeed();
+
+}
 
 #ifdef FUTURE_WORK
 /* return_done */
-static void update_state ( void )
+static void update_state(void)
 {
-unsigned int AX;
-
-
-    if ( (disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0 )
-    {
-       if ( disk_state == (ST_x08 | ST_x04 | ST_INVALID))
-       {
-          AX = ST_INVALID;
-       }
-  
-       if ( (disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0 )
-       {
-          invalidate ();
-          f_drv_ok = 0;
-       }
-       
-       AX |= 0x8000;
-    }
-    
-    if ( disk_state & ST_PLAYING )
-    {
-       AX |= 0x200;
-    }
-    
-    AX |= 0x100;
-    /* pkt_esbx = AX; */
-
-    disk_state = 0;
-    
+       unsigned int AX;
+
+
+       if ((disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0) {
+               if (disk_state == (ST_x08 | ST_x04 | ST_INVALID)) {
+                       AX = ST_INVALID;
+               }
+
+               if ((disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01))
+                   == 0) {
+                       invalidate();
+                       f_drv_ok = 0;
+               }
+
+               AX |= 0x8000;
+       }
+
+       if (disk_state & ST_PLAYING) {
+               AX |= 0x200;
+       }
+
+       AX |= 0x100;
+       /* pkt_esbx = AX; */
+
+       disk_state = 0;
+
 }
 #endif
 
 /* Init for the Module-Version */
 int init_gscd(void)
 {
-long err;
+       long err;
 
 
-     /* call the GoldStar-init */
-     err = my_gscd_init ( );
+       /* call the GoldStar-init */
+       err = my_gscd_init();
 
-     if ( err < 0 )
-     {
-         return err;
-     }
-     else
-     {
-        printk (KERN_INFO "Happy GoldStar !\n" );
-        return 0;
-     }    
+       if (err < 0) {
+               return err;
+       } else {
+               printk(KERN_INFO "Happy GoldStar !\n");
+               return 0;
+       }
 }
 
 void __exit exit_gscd(void)
 {
-   CLEAR_TIMER;
-
-   devfs_unregister(devfs_find_handle(NULL, "gscd", 0, 0, DEVFS_SPECIAL_BLK,
-                                     0));
-   if ((devfs_unregister_blkdev(MAJOR_NR, "gscd" ) == -EINVAL))
-   {
-      printk("What's that: can't unregister GoldStar-module\n" );
-      return;
-   }
-   blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-   release_region (gscd_port,4);
-   printk(KERN_INFO "GoldStar-module released.\n" );
+       CLEAR_TIMER;
+
+       devfs_unregister(devfs_find_handle
+                        (NULL, "gscd", 0, 0, DEVFS_SPECIAL_BLK, 0));
+       if ((devfs_unregister_blkdev(MAJOR_NR, "gscd") == -EINVAL)) {
+               printk("What's that: can't unregister GoldStar-module\n");
+               return;
+       }
+       blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+       release_region(gscd_port, 4);
+       printk(KERN_INFO "GoldStar-module released.\n");
 }
 
 #ifdef MODULE
 module_init(init_gscd);
-#endif 
+#endif
 module_exit(exit_gscd);
 
 
 /* Test for presence of drive and initialize it.  Called only at boot time. */
-int __init gscd_init (void)
+int __init gscd_init(void)
 {
-   return my_gscd_init ();
+       return my_gscd_init();
 }
 
 
 /* This is the common initialisation for the GoldStar drive. */
 /* It is called at boot time AND for module init.           */
-int __init my_gscd_init (void)
+int __init my_gscd_init(void)
 {
-int i;
-int result;
+       int i;
+       int result;
+
+       printk(KERN_INFO "GSCD: version %s\n", GSCD_VERSION);
+       printk(KERN_INFO
+              "GSCD: Trying to detect a Goldstar R420 CD-ROM drive at 0x%X.\n",
+              gscd_port);
+
+       if (check_region(gscd_port, 4)) {
+               printk
+                   ("GSCD: Init failed, I/O port (%X) already in use.\n",
+                    gscd_port);
+               return -EIO;
+       }
 
-        printk (KERN_INFO "GSCD: version %s\n", GSCD_VERSION);
-        printk (KERN_INFO "GSCD: Trying to detect a Goldstar R420 CD-ROM drive at 0x%X.\n", gscd_port);
 
-        if (check_region(gscd_port, 4)) 
-        {
-         printk("GSCD: Init failed, I/O port (%X) already in use.\n", gscd_port);
-         return -EIO;
+       /* check for card */
+       result = wait_drv_ready();
+       if (result == 0x09) {
+               printk("GSCD: DMA kann ich noch nicht!\n");
+               return -EIO;
        }
-         
 
-       /* check for card */
-       result = wait_drv_ready ();
-        if ( result == 0x09 )
-        {
-           printk ("GSCD: DMA kann ich noch nicht!\n" );
-           return -EIO;
-        }
-        if ( result == 0x0b )
-        {
-           drv_mode = result;
-           i = find_drives ();
-           if ( i == 0 )
-           {
-              printk ( "GSCD: GoldStar CD-ROM Drive is not found.\n" );
-              return -EIO;
-           }
-        }
-
-        if ( (result != 0x0b) && (result != 0x09) )
-        {
-              printk ("GSCD: GoldStar Interface Adapter does not exist or H/W error\n" );
-              return -EIO;
-        }                                  
-
-        /* reset all drives */
-        i = 0;
-        while ( drv_states[i] != 0 )
-        {
-           curr_drv_state = drv_states[i];
-           printk (KERN_INFO "GSCD: Reset unit %d ... ",i );
-           cc_Reset ();
-           printk ( "done\n" );
-           i++;
-        }
-
-       if (devfs_register_blkdev(MAJOR_NR, "gscd", &gscd_fops) != 0)
-       {
-               printk("GSCD: Unable to get major %d for GoldStar CD-ROM\n",
-                      MAJOR_NR);
+       if (result == 0x0b) {
+               drv_mode = result;
+               i = find_drives();
+               if (i == 0) {
+                       printk
+                           ("GSCD: GoldStar CD-ROM Drive is not found.\n");
+                       return -EIO;
+               }
+       }
+
+       if ((result != 0x0b) && (result != 0x09)) {
+               printk
+                   ("GSCD: GoldStar Interface Adapter does not exist or H/W error\n");
                return -EIO;
        }
-       devfs_register (NULL, "gscd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
-                       S_IFBLK | S_IRUGO | S_IWUGO, &gscd_fops, NULL);
+
+       /* reset all drives */
+       i = 0;
+       while (drv_states[i] != 0) {
+               curr_drv_state = drv_states[i];
+               printk(KERN_INFO "GSCD: Reset unit %d ... ", i);
+               cc_Reset();
+               printk("done\n");
+               i++;
+       }
+
+       if (devfs_register_blkdev(MAJOR_NR, "gscd", &gscd_fops) != 0) {
+               printk
+                   ("GSCD: Unable to get major %d for GoldStar CD-ROM\n",
+                    MAJOR_NR);
+               return -EIO;
+       }
+       devfs_register(NULL, "gscd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
+                      S_IFBLK | S_IRUGO | S_IWUGO, &gscd_fops, NULL);
 
        blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
        blksize_size[MAJOR_NR] = gscd_blocksizes;
        read_ahead[MAJOR_NR] = 4;
-        
-        disk_state = 0;
-        gscdPresent = 1;
+
+       disk_state = 0;
+       gscdPresent = 1;
 
        request_region(gscd_port, 4, "gscd");
-       register_disk(NULL, MKDEV(MAJOR_NR,0), 1, &gscd_fops, 0);
+       register_disk(NULL, MKDEV(MAJOR_NR, 0), 1, &gscd_fops, 0);
 
-        printk (KERN_INFO "GSCD: GoldStar CD-ROM Drive found.\n" );
+       printk(KERN_INFO "GSCD: GoldStar CD-ROM Drive found.\n");
        return 0;
 }
 
-static void gscd_hsg2msf (long hsg, struct msf *msf)
+static void gscd_hsg2msf(long hsg, struct msf *msf)
 {
        hsg += CD_MSF_OFFSET;
-       msf -> min = hsg / (CD_FRAMES*CD_SECS);
-       hsg %= CD_FRAMES*CD_SECS;
-       msf -> sec = hsg / CD_FRAMES;
-       msf -> frame = hsg % CD_FRAMES;
-
-       gscd_bin2bcd(&msf -> min);              /* convert to BCD */
-       gscd_bin2bcd(&msf -> sec);
-       gscd_bin2bcd(&msf -> frame);
+       msf->min = hsg / (CD_FRAMES * CD_SECS);
+       hsg %= CD_FRAMES * CD_SECS;
+       msf->sec = hsg / CD_FRAMES;
+       msf->frame = hsg % CD_FRAMES;
+
+       gscd_bin2bcd(&msf->min);        /* convert to BCD */
+       gscd_bin2bcd(&msf->sec);
+       gscd_bin2bcd(&msf->frame);
 }
 
-static void gscd_bin2bcd (unsigned char *p)
+
+static void gscd_bin2bcd(unsigned char *p)
 {
-int u, t;
+       int u, t;
 
        u = *p % 10;
        t = *p / 10;
@@ -1123,18 +1061,19 @@ int u, t;
 
 
 #ifdef FUTURE_WORK
-static long gscd_msf2hsg (struct msf *mp)
+static long gscd_msf2hsg(struct msf *mp)
 {
-       return gscd_bcd2bin(mp -> frame)
-               + gscd_bcd2bin(mp -> sec) * CD_FRAMES
-               + gscd_bcd2bin(mp -> min) * CD_FRAMES * CD_SECS
-               - CD_MSF_OFFSET;
+       return gscd_bcd2bin(mp->frame)
+           + gscd_bcd2bin(mp->sec) * CD_FRAMES
+           + gscd_bcd2bin(mp->min) * CD_FRAMES * CD_SECS - CD_MSF_OFFSET;
 }
 
-static int gscd_bcd2bin (unsigned char bcd)
+static int gscd_bcd2bin(unsigned char bcd)
 {
        return (bcd >> 4) * 10 + (bcd & 0xF);
 }
 #endif
 
-
+MODULE_AUTHOR("Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
index c2859f450f9879313cc7f970fd8720a81a795b6a..ea27aab96000781cc510a232aca8747d3f94dbfe 100644 (file)
@@ -44,9 +44,7 @@
 #define ISP16_VERSION_MAJOR 0
 #define ISP16_VERSION_MINOR 6
 
-#ifdef MODULE
 #include <linux/module.h>
-#endif  /* MODULE */
 
 #include <linux/fs.h>
 #include <linux/kernel.h>
@@ -59,8 +57,9 @@
 static short isp16_detect(void);
 static short isp16_c928__detect(void);
 static short isp16_c929__detect(void);
-static short isp16_cdi_config(int base, u_char drive_type, int irq, int dma);
-static short isp16_type; /* dependent on type of interface card */
+static short isp16_cdi_config(int base, u_char drive_type, int irq,
+                             int dma);
+static short isp16_type;       /* dependent on type of interface card */
 static u_char isp16_ctrl;
 static u_short isp16_enable_port;
 
@@ -69,11 +68,12 @@ static int isp16_cdrom_irq = ISP16_CDROM_IRQ;
 static int isp16_cdrom_dma = ISP16_CDROM_DMA;
 static char *isp16_cdrom_type = ISP16_CDROM_TYPE;
 
-#ifdef MODULE
 MODULE_PARM(isp16_cdrom_base, "i");
 MODULE_PARM(isp16_cdrom_irq, "i");
 MODULE_PARM(isp16_cdrom_dma, "i");
 MODULE_PARM(isp16_cdrom_type, "s");
+
+#ifdef MODULE
 void isp16_exit(void);
 #endif
 
@@ -82,243 +82,279 @@ void isp16_exit(void);
 
 #ifndef MODULE
 
-static int 
+static int
 __init isp16_setup(char *str)
 {
-  int ints[4];
-  
-  (void)get_options(str, ARRAY_SIZE(ints), ints);
-  if ( ints[0] > 0 )
-    isp16_cdrom_base = ints[1];
-  if ( ints[0] > 1 )      
-    isp16_cdrom_irq = ints[2];
-  if ( ints[0] > 2 )      
-    isp16_cdrom_dma = ints[3];
-  if ( str )
-    isp16_cdrom_type = str;
-
-  return 1;
+       int ints[4];
+
+       (void) get_options(str, ARRAY_SIZE(ints), ints);
+       if (ints[0] > 0)
+               isp16_cdrom_base = ints[1];
+       if (ints[0] > 1)
+               isp16_cdrom_irq = ints[2];
+       if (ints[0] > 2)
+               isp16_cdrom_dma = ints[3];
+       if (str)
+               isp16_cdrom_type = str;
+
+       return 1;
 }
 
 __setup("isp16=", isp16_setup);
 
-#endif /* MODULE */
+#endif                         /* MODULE */
 
 /*
  *  ISP16 initialisation.
  *
  */
-int __init 
-isp16_init(void)
+int __init isp16_init(void)
 {
-  u_char expected_drive;
-
-  printk(KERN_INFO "ISP16: configuration cdrom interface, version %d.%d.\n", ISP16_VERSION_MAJOR,
-    ISP16_VERSION_MINOR);
-
-  if ( !strcmp(isp16_cdrom_type, "noisp16") ) {
-    printk("ISP16: no cdrom interface configured.\n");
-    return(0);
-  }
-
-  if (check_region(ISP16_IO_BASE, ISP16_IO_SIZE)) {
-    printk("ISP16: i/o ports already in use.\n");
-    return(-EIO);
-  }
-
-  if ( (isp16_type=isp16_detect()) < 0 ) {
-    printk("ISP16: no cdrom interface found.\n");
-    return(-EIO);
-  }
-
-  printk(KERN_INFO "ISP16: cdrom interface (with OPTi 82C92%d chip) detected.\n",
-    (isp16_type==2) ? 9 : 8);
-
-  if ( !strcmp(isp16_cdrom_type, "Sanyo") )
-    expected_drive = (isp16_type ? ISP16_SANYO1 : ISP16_SANYO0);
-  else if ( !strcmp(isp16_cdrom_type, "Sony") )
-    expected_drive = ISP16_SONY;
-  else if ( !strcmp(isp16_cdrom_type, "Panasonic") )
-    expected_drive = (isp16_type ? ISP16_PANASONIC1 : ISP16_PANASONIC0);
-  else if ( !strcmp(isp16_cdrom_type, "Mitsumi") )
-    expected_drive = ISP16_MITSUMI;
-  else {
-    printk("ISP16: %s not supported by cdrom interface.\n", isp16_cdrom_type);
-    return(-EIO);
-  }
-
-  if ( isp16_cdi_config(isp16_cdrom_base, expected_drive,
-    isp16_cdrom_irq, isp16_cdrom_dma ) < 0) {
-    printk("ISP16: cdrom interface has not been properly configured.\n");
-    return(-EIO);
-  }
-  printk(KERN_INFO "ISP16: cdrom interface set up with io base 0x%03X, irq %d, dma %d,"
-    " type %s.\n", isp16_cdrom_base, isp16_cdrom_irq, isp16_cdrom_dma,
-    isp16_cdrom_type);
-  return(0);
+       u_char expected_drive;
+
+       printk(KERN_INFO
+              "ISP16: configuration cdrom interface, version %d.%d.\n",
+              ISP16_VERSION_MAJOR, ISP16_VERSION_MINOR);
+
+       if (!strcmp(isp16_cdrom_type, "noisp16")) {
+               printk("ISP16: no cdrom interface configured.\n");
+               return (0);
+       }
+
+       if (check_region(ISP16_IO_BASE, ISP16_IO_SIZE)) {
+               printk("ISP16: i/o ports already in use.\n");
+               return (-EIO);
+       }
+
+       if ((isp16_type = isp16_detect()) < 0) {
+               printk("ISP16: no cdrom interface found.\n");
+               return (-EIO);
+       }
+
+       printk(KERN_INFO
+              "ISP16: cdrom interface (with OPTi 82C92%d chip) detected.\n",
+              (isp16_type == 2) ? 9 : 8);
+
+       if (!strcmp(isp16_cdrom_type, "Sanyo"))
+               expected_drive =
+                   (isp16_type ? ISP16_SANYO1 : ISP16_SANYO0);
+       else if (!strcmp(isp16_cdrom_type, "Sony"))
+               expected_drive = ISP16_SONY;
+       else if (!strcmp(isp16_cdrom_type, "Panasonic"))
+               expected_drive =
+                   (isp16_type ? ISP16_PANASONIC1 : ISP16_PANASONIC0);
+       else if (!strcmp(isp16_cdrom_type, "Mitsumi"))
+               expected_drive = ISP16_MITSUMI;
+       else {
+               printk("ISP16: %s not supported by cdrom interface.\n",
+                      isp16_cdrom_type);
+               return (-EIO);
+       }
+
+       if (isp16_cdi_config(isp16_cdrom_base, expected_drive,
+                            isp16_cdrom_irq, isp16_cdrom_dma) < 0) {
+               printk
+                   ("ISP16: cdrom interface has not been properly configured.\n");
+               return (-EIO);
+       }
+       printk(KERN_INFO
+              "ISP16: cdrom interface set up with io base 0x%03X, irq %d, dma %d,"
+              " type %s.\n", isp16_cdrom_base, isp16_cdrom_irq,
+              isp16_cdrom_dma, isp16_cdrom_type);
+       return (0);
 }
 
-static short __init 
-isp16_detect(void)
+static short __init isp16_detect(void)
 {
 
-  if ( isp16_c929__detect() >= 0 )
-    return(2);
-  else
-    return(isp16_c928__detect());
+       if (isp16_c929__detect() >= 0)
+               return (2);
+       else
+               return (isp16_c928__detect());
 }
 
-static short __init 
-isp16_c928__detect(void)
+static short __init isp16_c928__detect(void)
 {
-  u_char ctrl;
-  u_char enable_cdrom;
-  u_char io;
-  short i = -1;
-
-  isp16_ctrl = ISP16_C928__CTRL;
-  isp16_enable_port = ISP16_C928__ENABLE_PORT;
-
-  /* read' and write' are a special read and write, respectively */
-
-  /* read' ISP16_CTRL_PORT, clear last two bits and write' back the result */
-  ctrl = ISP16_IN( ISP16_CTRL_PORT ) & 0xFC;
-  ISP16_OUT( ISP16_CTRL_PORT, ctrl );
-
-  /* read' 3,4 and 5-bit from the cdrom enable port */
-  enable_cdrom = ISP16_IN( ISP16_C928__ENABLE_PORT ) & 0x38;
-
-  if ( !(enable_cdrom & 0x20) ) {  /* 5-bit not set */
-    /* read' last 2 bits of ISP16_IO_SET_PORT */
-    io = ISP16_IN( ISP16_IO_SET_PORT ) & 0x03;
-    if ( ((io&0x01)<<1) == (io&0x02) ) {  /* bits are the same */
-      if ( io == 0 ) {  /* ...the same and 0 */
-        i = 0;
-        enable_cdrom |= 0x20;
-      }
-      else {  /* ...the same and 1 */  /* my card, first time 'round */
-        i = 1;
-        enable_cdrom |= 0x28;
-      }
-      ISP16_OUT( ISP16_C928__ENABLE_PORT, enable_cdrom );
-    }
-    else {  /* bits are not the same */
-      ISP16_OUT( ISP16_CTRL_PORT, ctrl );
-      return(i); /* -> not detected: possibly incorrect conclusion */
-    }
-  }
-  else if ( enable_cdrom == 0x20 )
-    i = 0;
-  else if ( enable_cdrom == 0x28 )  /* my card, already initialised */
-    i = 1;
-
-  ISP16_OUT( ISP16_CTRL_PORT, ctrl );
-
-  return(i);
+       u_char ctrl;
+       u_char enable_cdrom;
+       u_char io;
+       short i = -1;
+
+       isp16_ctrl = ISP16_C928__CTRL;
+       isp16_enable_port = ISP16_C928__ENABLE_PORT;
+
+       /* read' and write' are a special read and write, respectively */
+
+       /* read' ISP16_CTRL_PORT, clear last two bits and write' back the result */
+       ctrl = ISP16_IN(ISP16_CTRL_PORT) & 0xFC;
+       ISP16_OUT(ISP16_CTRL_PORT, ctrl);
+
+       /* read' 3,4 and 5-bit from the cdrom enable port */
+       enable_cdrom = ISP16_IN(ISP16_C928__ENABLE_PORT) & 0x38;
+
+       if (!(enable_cdrom & 0x20)) {   /* 5-bit not set */
+               /* read' last 2 bits of ISP16_IO_SET_PORT */
+               io = ISP16_IN(ISP16_IO_SET_PORT) & 0x03;
+               if (((io & 0x01) << 1) == (io & 0x02)) {        /* bits are the same */
+                       if (io == 0) {  /* ...the same and 0 */
+                               i = 0;
+                               enable_cdrom |= 0x20;
+                       } else {        /* ...the same and 1 *//* my card, first time 'round */
+                               i = 1;
+                               enable_cdrom |= 0x28;
+                       }
+                       ISP16_OUT(ISP16_C928__ENABLE_PORT, enable_cdrom);
+               } else {        /* bits are not the same */
+                       ISP16_OUT(ISP16_CTRL_PORT, ctrl);
+                       return (i);     /* -> not detected: possibly incorrect conclusion */
+               }
+       } else if (enable_cdrom == 0x20)
+               i = 0;
+       else if (enable_cdrom == 0x28)  /* my card, already initialised */
+               i = 1;
+
+       ISP16_OUT(ISP16_CTRL_PORT, ctrl);
+
+       return (i);
 }
 
-static short __init 
-isp16_c929__detect(void)
+static short __init isp16_c929__detect(void)
 {
-  u_char ctrl;
-  u_char tmp;
+       u_char ctrl;
+       u_char tmp;
+
+       isp16_ctrl = ISP16_C929__CTRL;
+       isp16_enable_port = ISP16_C929__ENABLE_PORT;
 
-  isp16_ctrl = ISP16_C929__CTRL;
-  isp16_enable_port = ISP16_C929__ENABLE_PORT;
+       /* read' and write' are a special read and write, respectively */
 
-  /* read' and write' are a special read and write, respectively */
+       /* read' ISP16_CTRL_PORT and save */
+       ctrl = ISP16_IN(ISP16_CTRL_PORT);
 
-  /* read' ISP16_CTRL_PORT and save */
-  ctrl = ISP16_IN( ISP16_CTRL_PORT );
+       /* write' zero to the ctrl port and get response */
+       ISP16_OUT(ISP16_CTRL_PORT, 0);
+       tmp = ISP16_IN(ISP16_CTRL_PORT);
 
-  /* write' zero to the ctrl port and get response */
-  ISP16_OUT( ISP16_CTRL_PORT, 0 );
-  tmp = ISP16_IN( ISP16_CTRL_PORT );
+       if (tmp != 2)           /* isp16 with 82C929 not detected */
+               return (-1);
 
-  if ( tmp != 2 )  /* isp16 with 82C929 not detected */
-    return(-1);
+       /* restore ctrl port value */
+       ISP16_OUT(ISP16_CTRL_PORT, ctrl);
 
-  /* restore ctrl port value */
-  ISP16_OUT( ISP16_CTRL_PORT, ctrl );
-  
-  return(2);
+       return (2);
 }
 
-static short __init 
+static short __init
 isp16_cdi_config(int base, u_char drive_type, int irq, int dma)
 {
-  u_char base_code;
-  u_char irq_code;
-  u_char dma_code;
-  u_char i;
-
-  if ( (drive_type == ISP16_MITSUMI) && (dma != 0) )
-    printk("ISP16: Mitsumi cdrom drive has no dma support.\n");
-
-  switch (base) {
-  case 0x340: base_code = ISP16_BASE_340; break;
-  case 0x330: base_code = ISP16_BASE_330; break;
-  case 0x360: base_code = ISP16_BASE_360; break;
-  case 0x320: base_code = ISP16_BASE_320; break;
-  default:
-    printk("ISP16: base address 0x%03X not supported by cdrom interface.\n",
-      base);
-    return(-1);
-  }
-  switch (irq) {
-  case 0: irq_code = ISP16_IRQ_X; break; /* disable irq */
-  case 5: irq_code = ISP16_IRQ_5;
-          printk("ISP16: irq 5 shouldn't be used by cdrom interface,"
-            " due to possible conflicts with the sound card.\n");
-          break;
-  case 7: irq_code = ISP16_IRQ_7;
-          printk("ISP16: irq 7 shouldn't be used by cdrom interface,"
-            " due to possible conflicts with the sound card.\n");
-          break;
-  case 3: irq_code = ISP16_IRQ_3; break;
-  case 9: irq_code = ISP16_IRQ_9; break;
-  case 10: irq_code = ISP16_IRQ_10; break;
-  case 11: irq_code = ISP16_IRQ_11; break;
-  default:
-    printk("ISP16: irq %d not supported by cdrom interface.\n", irq );
-    return(-1);
-  }
-  switch (dma) {
-  case 0: dma_code = ISP16_DMA_X; break;  /* disable dma */
-  case 1: printk("ISP16: dma 1 cannot be used by cdrom interface,"
-            " due to conflict with the sound card.\n");
-          return(-1); break;
-  case 3: dma_code = ISP16_DMA_3; break;
-  case 5: dma_code = ISP16_DMA_5; break;
-  case 6: dma_code = ISP16_DMA_6; break;
-  case 7: dma_code = ISP16_DMA_7; break;
-  default:
-    printk("ISP16: dma %d not supported by cdrom interface.\n", dma);
-    return(-1);
-  }
-
-  if ( drive_type != ISP16_SONY && drive_type != ISP16_PANASONIC0 &&
-    drive_type != ISP16_PANASONIC1 && drive_type != ISP16_SANYO0 &&
-    drive_type != ISP16_SANYO1 && drive_type != ISP16_MITSUMI &&
-    drive_type != ISP16_DRIVE_X ) {
-    printk("ISP16: drive type (code 0x%02X) not supported by cdrom"
-     " interface.\n", drive_type );
-    return(-1);
-  }
-
-  /* set type of interface */
-  i = ISP16_IN(ISP16_DRIVE_SET_PORT) & ISP16_DRIVE_SET_MASK;  /* clear some bits */
-  ISP16_OUT( ISP16_DRIVE_SET_PORT, i|drive_type );
-
-  /* enable cdrom on interface with 82C929 chip */
-  if ( isp16_type > 1 )
-    ISP16_OUT( isp16_enable_port, ISP16_ENABLE_CDROM );
-
-  /* set base address, irq and dma */
-  i = ISP16_IN(ISP16_IO_SET_PORT) & ISP16_IO_SET_MASK;  /* keep some bits */
-  ISP16_OUT( ISP16_IO_SET_PORT, i|base_code|irq_code|dma_code );
-
-  return(0);
+       u_char base_code;
+       u_char irq_code;
+       u_char dma_code;
+       u_char i;
+
+       if ((drive_type == ISP16_MITSUMI) && (dma != 0))
+               printk("ISP16: Mitsumi cdrom drive has no dma support.\n");
+
+       switch (base) {
+       case 0x340:
+               base_code = ISP16_BASE_340;
+               break;
+       case 0x330:
+               base_code = ISP16_BASE_330;
+               break;
+       case 0x360:
+               base_code = ISP16_BASE_360;
+               break;
+       case 0x320:
+               base_code = ISP16_BASE_320;
+               break;
+       default:
+               printk
+                   ("ISP16: base address 0x%03X not supported by cdrom interface.\n",
+                    base);
+               return (-1);
+       }
+       switch (irq) {
+       case 0:
+               irq_code = ISP16_IRQ_X;
+               break;          /* disable irq */
+       case 5:
+               irq_code = ISP16_IRQ_5;
+               printk("ISP16: irq 5 shouldn't be used by cdrom interface,"
+                      " due to possible conflicts with the sound card.\n");
+               break;
+       case 7:
+               irq_code = ISP16_IRQ_7;
+               printk("ISP16: irq 7 shouldn't be used by cdrom interface,"
+                      " due to possible conflicts with the sound card.\n");
+               break;
+       case 3:
+               irq_code = ISP16_IRQ_3;
+               break;
+       case 9:
+               irq_code = ISP16_IRQ_9;
+               break;
+       case 10:
+               irq_code = ISP16_IRQ_10;
+               break;
+       case 11:
+               irq_code = ISP16_IRQ_11;
+               break;
+       default:
+               printk("ISP16: irq %d not supported by cdrom interface.\n",
+                      irq);
+               return (-1);
+       }
+       switch (dma) {
+       case 0:
+               dma_code = ISP16_DMA_X;
+               break;          /* disable dma */
+       case 1:
+               printk("ISP16: dma 1 cannot be used by cdrom interface,"
+                      " due to conflict with the sound card.\n");
+               return (-1);
+               break;
+       case 3:
+               dma_code = ISP16_DMA_3;
+               break;
+       case 5:
+               dma_code = ISP16_DMA_5;
+               break;
+       case 6:
+               dma_code = ISP16_DMA_6;
+               break;
+       case 7:
+               dma_code = ISP16_DMA_7;
+               break;
+       default:
+               printk("ISP16: dma %d not supported by cdrom interface.\n",
+                      dma);
+               return (-1);
+       }
+
+       if (drive_type != ISP16_SONY && drive_type != ISP16_PANASONIC0 &&
+           drive_type != ISP16_PANASONIC1 && drive_type != ISP16_SANYO0 &&
+           drive_type != ISP16_SANYO1 && drive_type != ISP16_MITSUMI &&
+           drive_type != ISP16_DRIVE_X) {
+               printk
+                   ("ISP16: drive type (code 0x%02X) not supported by cdrom"
+                    " interface.\n", drive_type);
+               return (-1);
+       }
+
+       /* set type of interface */
+       i = ISP16_IN(ISP16_DRIVE_SET_PORT) & ISP16_DRIVE_SET_MASK;      /* clear some bits */
+       ISP16_OUT(ISP16_DRIVE_SET_PORT, i | drive_type);
+
+       /* enable cdrom on interface with 82C929 chip */
+       if (isp16_type > 1)
+               ISP16_OUT(isp16_enable_port, ISP16_ENABLE_CDROM);
+
+       /* set base address, irq and dma */
+       i = ISP16_IN(ISP16_IO_SET_PORT) & ISP16_IO_SET_MASK;    /* keep some bits */
+       ISP16_OUT(ISP16_IO_SET_PORT, i | base_code | irq_code | dma_code);
+
+       return (0);
 }
 
 void __exit isp16_exit(void)
@@ -332,4 +368,5 @@ module_init(isp16_init);
 #endif
 module_exit(isp16_exit);
 
-
+EXPORT_NO_SYMBOLS;
+MODULE_LICENSE("GPL");
index 4855079cc3321718f8ccb1b046b11a959ccfc77d..85cc35b449e474c8751ec119b8a07b77ecff9a6e 100644 (file)
 #define MAJOR_NR MITSUMI_CDROM_MAJOR
 #include <linux/blk.h>
 
-#define mcd_port mcd    /* for compatible parameter passing with "insmod" */
+#define mcd_port mcd           /* for compatible parameter passing with "insmod" */
 #include "mcd.h"
 
 static int mcd_blocksizes[1];
 
 
 /* I added A flag to drop to 1x speed if too many errors 0 = 1X ; 1 = 2X */
-static int mcdDouble; 
+static int mcdDouble;
 
 /* How many sectors to hold at 1x speed counter */
 static int mcd1xhold;
@@ -118,19 +118,19 @@ static int mcd1xhold;
 static int mcdPresent;
 
 #if 0
-#define TEST1 /* <int-..> */
-#define TEST2 /* do_mcd_req */
-#define TEST3 */ /* MCD_S_state */
-#define TEST4 /* QUICK_LOOP-counter */
-#define TEST5 */ /* port(1) state */
+#define TEST1                  /* <int-..> */
+#define TEST2                  /* do_mcd_req */
+#define TEST3 */               /* MCD_S_state */
+#define TEST4                  /* QUICK_LOOP-counter */
+#define TEST5 */               /* port(1) state */
 #endif
 
 #if 1
-#define QUICK_LOOP_DELAY udelay(45)  /* use udelay */
+#define QUICK_LOOP_DELAY udelay(45)    /* use udelay */
 #define QUICK_LOOP_COUNT 20
 #else
 #define QUICK_LOOP_DELAY
-#define QUICK_LOOP_COUNT 140 /* better wait constant time */
+#define QUICK_LOOP_COUNT 140   /* better wait constant time */
 #endif
 /* #define DOUBLE_QUICK_ONLY */
 
@@ -141,32 +141,32 @@ static int mcdPresent;
 #define MFL_STATUSorDATA (MFL_STATUS | MFL_DATA)
 #define MCD_BUF_SIZ 16
 static volatile int mcd_transfer_is_active;
-static char mcd_buf[2048*MCD_BUF_SIZ]; /* buffer for block size conversion */
+static char mcd_buf[2048 * MCD_BUF_SIZ];       /* buffer for block size conversion */
 static volatile int mcd_buf_bn[MCD_BUF_SIZ], mcd_next_bn;
 static volatile int mcd_buf_in, mcd_buf_out = -1;
 static volatile int mcd_error;
 static int mcd_open_count;
 enum mcd_state_e {
-  MCD_S_IDLE,   /* 0 */
-  MCD_S_START,  /* 1 */
-  MCD_S_MODE, /* 2 */
-  MCD_S_READ,   /* 3 */
-  MCD_S_DATA,   /* 4 */
-  MCD_S_STOP,   /* 5 */
-  MCD_S_STOPPING /* 6 */
+       MCD_S_IDLE,             /* 0 */
+       MCD_S_START,            /* 1 */
+       MCD_S_MODE,             /* 2 */
+       MCD_S_READ,             /* 3 */
+       MCD_S_DATA,             /* 4 */
+       MCD_S_STOP,             /* 5 */
+       MCD_S_STOPPING          /* 6 */
 };
 static volatile enum mcd_state_e mcd_state = MCD_S_IDLE;
 static int mcd_mode = -1;
-static int MCMD_DATA_READ= MCMD_PLAY_READ;
+static int MCMD_DATA_READ = MCMD_PLAY_READ;
 #define READ_TIMEOUT 3000
 #define WORK_AROUND_MITSUMI_BUG_92
 #define WORK_AROUND_MITSUMI_BUG_93
 #ifdef WORK_AROUND_MITSUMI_BUG_93
 int mitsumi_bug_93_wait;
-#endif /* WORK_AROUND_MITSUMI_BUG_93 */
+#endif                         /* WORK_AROUND_MITSUMI_BUG_93 */
 
-static short mcd_port = CONFIG_MCD_BASE; /* used as "mcd" by "insmod" */
-static int   mcd_irq  = CONFIG_MCD_IRQ; /* must directly follow mcd_port */
+static short mcd_port = CONFIG_MCD_BASE;       /* used as "mcd" by "insmod" */
+static int mcd_irq = CONFIG_MCD_IRQ;   /* must directly follow mcd_port */
 MODULE_PARM(mcd, "1-2i");
 
 static int McdTimeout, McdTries;
@@ -195,75 +195,76 @@ static int updateToc(void);
 static int GetDiskInfo(void);
 static int GetToc(void);
 static int getValue(unsigned char *result);
-static int mcd_open(struct cdrom_device_info * cdi, int purpose);
-static void mcd_release(struct cdrom_device_info * cdi);
-static int mcd_media_changed(struct cdrom_device_info * cdi, int disc_nr);
-static int mcd_tray_move(struct cdrom_device_info * cdi, int position);
-int mcd_audio_ioctl(struct cdrom_device_info * cdi, unsigned int cmd,
-                      void * arg);
-int mcd_drive_status(struct cdrom_device_info * cdi, int slot_nr);
+static int mcd_open(struct cdrom_device_info *cdi, int purpose);
+static void mcd_release(struct cdrom_device_info *cdi);
+static int mcd_media_changed(struct cdrom_device_info *cdi, int disc_nr);
+static int mcd_tray_move(struct cdrom_device_info *cdi, int position);
+int mcd_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
+                   void *arg);
+int mcd_drive_status(struct cdrom_device_info *cdi, int slot_nr);
 
 static struct timer_list mcd_timer;
 
 static struct cdrom_device_ops mcd_dops = {
-       open:                   mcd_open,
-       release:                mcd_release,
-       drive_status:           mcd_drive_status,
-       media_changed:          mcd_media_changed,
-       tray_move:              mcd_tray_move,
-       audio_ioctl:            mcd_audio_ioctl,
-       capability:             CDC_OPEN_TRAY | CDC_MEDIA_CHANGED |
-                               CDC_PLAY_AUDIO | CDC_DRIVE_STATUS,
+       open:mcd_open,
+       release:mcd_release,
+       drive_status:mcd_drive_status,
+       media_changed:mcd_media_changed,
+       tray_move:mcd_tray_move,
+       audio_ioctl:mcd_audio_ioctl,
+       capability:CDC_OPEN_TRAY | CDC_MEDIA_CHANGED |
+           CDC_PLAY_AUDIO | CDC_DRIVE_STATUS,
 };
 
 static struct cdrom_device_info mcd_info = {
-       ops:                    &mcd_dops,
-       speed:                  2,
-       capacity:               1,
-       name:                   "mcd",
+       ops:&mcd_dops,
+       speed:2,
+       capacity:1,
+       name:"mcd",
 };
 
 #ifndef MODULE
 static int __init mcd_setup(char *str)
 {
-   int ints[9];
-   
-   (void)get_options(str, ARRAY_SIZE(ints), ints);
-   
-   if (ints[0] > 0)
-      mcd_port = ints[1];
-   if (ints[0] > 1)      
-      mcd_irq  = ints[2];
+       int ints[9];
+
+       (void) get_options(str, ARRAY_SIZE(ints), ints);
+
+       if (ints[0] > 0)
+               mcd_port = ints[1];
+       if (ints[0] > 1)
+               mcd_irq = ints[2];
 #ifdef WORK_AROUND_MITSUMI_BUG_93
-   if (ints[0] > 2)
-      mitsumi_bug_93_wait = ints[3];
-#endif /* WORK_AROUND_MITSUMI_BUG_93 */
+       if (ints[0] > 2)
+               mitsumi_bug_93_wait = ints[3];
+#endif                         /* WORK_AROUND_MITSUMI_BUG_93 */
 
- return 1;
      return 1;
 }
 
 __setup("mcd=", mcd_setup);
 
-#endif /* MODULE */ 
+#endif                         /* MODULE */
 
-static int mcd_media_changed(struct cdrom_device_info * cdi, int disc_nr)
+static int mcd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
 {
-   int retval;
+       int retval;
 
 
-#if 1   /* the below is not reliable */
-   return 0;
-#endif  
+#if 1                          /* the below is not reliable */
+       return 0;
+#endif
 
-   if (cdi->dev) {
-      printk("mcd: Mitsumi CD-ROM request error: invalid device.\n");
-      return 0;
-   }
+       if (cdi->dev) {
+               printk
+                   ("mcd: Mitsumi CD-ROM request error: invalid device.\n");
+               return 0;
+       }
 
-   retval = mcdDiskChanged;
-   mcdDiskChanged = 0;
+       retval = mcdDiskChanged;
+       mcdDiskChanged = 0;
 
-   return retval;
+       return retval;
 }
 
 
@@ -272,18 +273,16 @@ static int mcd_media_changed(struct cdrom_device_info * cdi, int disc_nr)
  * because it calls 'getMcdStatus' which sleeps.
  */
 
-static int
-statusCmd(void)
+static int statusCmd(void)
 {
        int st = -1, retry;
 
-       for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
-       {
-               outb(MCMD_GET_STATUS, MCDPORT(0));    /* send get-status cmd */
+       for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
+               outb(MCMD_GET_STATUS, MCDPORT(0));      /* send get-status cmd */
 
                st = getMcdStatus(MCD_STATUS_DELAY);
-               if (st != -1) 
-                       break;
+               if (st != -1)
+                       break;
        }
 
        return st;
@@ -294,13 +293,11 @@ statusCmd(void)
  * Send a 'Play' command and get the status.  Use only from the top half.
  */
 
-static int
-mcdPlay(struct mcd_Play_msf *arg)
+static int mcdPlay(struct mcd_Play_msf *arg)
 {
        int retry, st = -1;
 
-       for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
-       {
+       for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
                sendMcdCmd(MCMD_PLAY_READ, arg);
                st = getMcdStatus(2 * MCD_STATUS_DELAY);
                if (st != -1)
@@ -311,45 +308,40 @@ mcdPlay(struct mcd_Play_msf *arg)
 }
 
 
-static int 
-mcd_tray_move(struct cdrom_device_info * cdi, int position)
+static int mcd_tray_move(struct cdrom_device_info *cdi, int position)
 {
        int i;
        if (position) {
-       /*  Eject */
-                       /* all drives can at least stop! */
+               /*  Eject */
+               /* all drives can at least stop! */
                if (audioStatus == CDROM_AUDIO_PLAY) {
-               outb(MCMD_STOP, MCDPORT(0));
-               i = getMcdStatus(MCD_STATUS_DELAY);
+                       outb(MCMD_STOP, MCDPORT(0));
+                       i = getMcdStatus(MCD_STATUS_DELAY);
                }
 
-                audioStatus = CDROM_AUDIO_NO_STATUS;
+               audioStatus = CDROM_AUDIO_NO_STATUS;
 
-                outb(MCMD_EJECT, MCDPORT(0));
-                /*
-                 * the status (i) shows failure on all but the FX drives.
-                 * But nothing we can do about that in software!
-                 * So just read the status and forget it. - Jon.
-                 */
-                i = getMcdStatus(MCD_STATUS_DELAY);
-                return 0;
-       }
-       else 
+               outb(MCMD_EJECT, MCDPORT(0));
+               /*
+                * the status (i) shows failure on all but the FX drives.
+                * But nothing we can do about that in software!
+                * So just read the status and forget it. - Jon.
+                */
+               i = getMcdStatus(MCD_STATUS_DELAY);
+               return 0;
+       } else
                return -EINVAL;
 }
 
-long
-msf2hsg(struct msf *mp)
+long msf2hsg(struct msf *mp)
 {
-       return bcd2bin(mp -> frame)
-               + bcd2bin(mp -> sec) * 75
-               + bcd2bin(mp -> min) * 4500
-               - 150;
+       return bcd2bin(mp->frame)
+           + bcd2bin(mp->sec) * 75 + bcd2bin(mp->min) * 4500 - 150;
 }
 
 
-int mcd_audio_ioctl(struct cdrom_device_info * cdi, unsigned int cmd,
-                      void * arg)
+int mcd_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
+                   void *arg)
 {
        int i, st;
        struct mcd_Toc qInfo;
@@ -365,24 +357,22 @@ int mcd_audio_ioctl(struct cdrom_device_info * cdi, unsigned int cmd,
        if (st < 0)
                return -EIO;
 
-       if (!tocUpToDate)
-       {
+       if (!tocUpToDate) {
                i = updateToc();
-               if (i < 0) 
+               if (i < 0)
                        return i;       /* error reading TOC */
        }
 
-       switch (cmd)
-       {
-       case CDROMSTART:     /* Spin up the drive */
+       switch (cmd) {
+       case CDROMSTART:        /* Spin up the drive */
                /* Don't think we can do this.  Even if we could,
-                * I think the drive times out and stops after a while
+                * I think the drive times out and stops after a while
                 * anyway.  For now, ignore it.
                 */
 
                return 0;
 
-       case CDROMSTOP:      /* Spin down the drive */
+       case CDROMSTOP: /* Spin down the drive */
                outb(MCMD_STOP, MCDPORT(0));
                i = getMcdStatus(MCD_STATUS_DELAY);
 
@@ -391,15 +381,14 @@ int mcd_audio_ioctl(struct cdrom_device_info * cdi, unsigned int cmd,
                audioStatus = CDROM_AUDIO_NO_STATUS;
                return 0;
 
-       case CDROMPAUSE:     /* Pause the drive */
+       case CDROMPAUSE:        /* Pause the drive */
                if (audioStatus != CDROM_AUDIO_PLAY)
                        return -EINVAL;
 
                outb(MCMD_STOP, MCDPORT(0));
                i = getMcdStatus(MCD_STATUS_DELAY);
 
-               if (GetQChannelInfo(&qInfo) < 0)
-               {
+               if (GetQChannelInfo(&qInfo) < 0) {
                        /* didn't get q channel info */
 
                        audioStatus = CDROM_AUDIO_NO_STATUS;
@@ -411,15 +400,14 @@ int mcd_audio_ioctl(struct cdrom_device_info * cdi, unsigned int cmd,
                audioStatus = CDROM_AUDIO_PAUSED;
                return 0;
 
-       case CDROMRESUME:    /* Play it again, Sam */
+       case CDROMRESUME:       /* Play it again, Sam */
                if (audioStatus != CDROM_AUDIO_PAUSED)
                        return -EINVAL;
 
                /* restart the drive at the saved position. */
 
                i = mcdPlay(&mcd_Play);
-               if (i < 0)
-               {
+               if (i < 0) {
                        audioStatus = CDROM_AUDIO_ERROR;
                        return -EIO;
                }
@@ -427,14 +415,13 @@ int mcd_audio_ioctl(struct cdrom_device_info * cdi, unsigned int cmd,
                audioStatus = CDROM_AUDIO_PLAY;
                return 0;
 
-       case CDROMPLAYTRKIND:     /* Play a track.  This currently ignores index. */
+       case CDROMPLAYTRKIND:   /* Play a track.  This currently ignores index. */
 
-               ti=(struct cdrom_ti *) arg;
+               ti = (struct cdrom_ti *) arg;
 
                if (ti->cdti_trk0 < DiskInfo.first
-                       || ti->cdti_trk0 > DiskInfo.last
-                       || ti->cdti_trk1 < ti->cdti_trk0)
-               {
+                   || ti->cdti_trk0 > DiskInfo.last
+                   || ti->cdti_trk1 < ti->cdti_trk0) {
                        return -EINVAL;
                }
 
@@ -445,14 +432,14 @@ int mcd_audio_ioctl(struct cdrom_device_info * cdi, unsigned int cmd,
                mcd_Play.end = Toc[ti->cdti_trk1 + 1].diskTime;
 
 #ifdef MCD_DEBUG
-printk("play: %02x:%02x.%02x to %02x:%02x.%02x\n",
-       mcd_Play.start.min, mcd_Play.start.sec, mcd_Play.start.frame,
-       mcd_Play.end.min, mcd_Play.end.sec, mcd_Play.end.frame);
+               printk("play: %02x:%02x.%02x to %02x:%02x.%02x\n",
+                      mcd_Play.start.min, mcd_Play.start.sec,
+                      mcd_Play.start.frame, mcd_Play.end.min,
+                      mcd_Play.end.sec, mcd_Play.end.frame);
 #endif
 
                i = mcdPlay(&mcd_Play);
-               if (i < 0)
-               {
+               if (i < 0) {
                        audioStatus = CDROM_AUDIO_ERROR;
                        return -EIO;
                }
@@ -460,15 +447,15 @@ printk("play: %02x:%02x.%02x to %02x:%02x.%02x\n",
                audioStatus = CDROM_AUDIO_PLAY;
                return 0;
 
-       case CDROMPLAYMSF:   /* Play starting at the given MSF address. */
+       case CDROMPLAYMSF:      /* Play starting at the given MSF address. */
 
                if (audioStatus == CDROM_AUDIO_PLAY) {
-                 outb(MCMD_STOP, MCDPORT(0));
-                 i = getMcdStatus(MCD_STATUS_DELAY);
-                 audioStatus = CDROM_AUDIO_NO_STATUS;
+                       outb(MCMD_STOP, MCDPORT(0));
+                       i = getMcdStatus(MCD_STATUS_DELAY);
+                       audioStatus = CDROM_AUDIO_NO_STATUS;
                }
 
-               msf=(struct cdrom_msf *) arg;
+               msf = (struct cdrom_msf *) arg;
 
                /* convert to bcd */
 
@@ -487,14 +474,14 @@ printk("play: %02x:%02x.%02x to %02x:%02x.%02x\n",
                mcd_Play.end.frame = msf->cdmsf_frame1;
 
 #ifdef MCD_DEBUG
-printk("play: %02x:%02x.%02x to %02x:%02x.%02x\n",
-mcd_Play.start.min, mcd_Play.start.sec, mcd_Play.start.frame,
-mcd_Play.end.min, mcd_Play.end.sec, mcd_Play.end.frame);
+               printk("play: %02x:%02x.%02x to %02x:%02x.%02x\n",
+                      mcd_Play.start.min, mcd_Play.start.sec,
+                      mcd_Play.start.frame, mcd_Play.end.min,
+                      mcd_Play.end.sec, mcd_Play.end.frame);
 #endif
 
                i = mcdPlay(&mcd_Play);
-               if (i < 0)
-               {
+               if (i < 0) {
                        audioStatus = CDROM_AUDIO_ERROR;
                        return -EIO;
                }
@@ -502,35 +489,37 @@ mcd_Play.end.min, mcd_Play.end.sec, mcd_Play.end.frame);
                audioStatus = CDROM_AUDIO_PLAY;
                return 0;
 
-       case CDROMREADTOCHDR:        /* Read the table of contents header */
-               tocHdr=(struct cdrom_tochdr *) arg; 
+       case CDROMREADTOCHDR:   /* Read the table of contents header */
+               tocHdr = (struct cdrom_tochdr *) arg;
                tocHdr->cdth_trk0 = DiskInfo.first;
                tocHdr->cdth_trk1 = DiskInfo.last;
                return 0;
 
-       case CDROMREADTOCENTRY:      /* Read an entry in the table of contents */
-               entry=(struct cdrom_tocentry *) arg;
+       case CDROMREADTOCENTRY: /* Read an entry in the table of contents */
+               entry = (struct cdrom_tocentry *) arg;
                if (entry->cdte_track == CDROM_LEADOUT)
                        tocPtr = &Toc[DiskInfo.last - DiskInfo.first + 1];
 
                else if (entry->cdte_track > DiskInfo.last
-                               || entry->cdte_track < DiskInfo.first)
+                        || entry->cdte_track < DiskInfo.first)
                        return -EINVAL;
 
                else
                        tocPtr = &Toc[entry->cdte_track];
 
-               entry->cdte_adr = tocPtr -> ctrl_addr;
-               entry->cdte_ctrl = tocPtr -> ctrl_addr >> 4;
+               entry->cdte_adr = tocPtr->ctrl_addr;
+               entry->cdte_ctrl = tocPtr->ctrl_addr >> 4;
 
                if (entry->cdte_format == CDROM_LBA)
-                       entry->cdte_addr.lba = msf2hsg(&tocPtr -> diskTime);
-
-               else if (entry->cdte_format == CDROM_MSF)
-               {
-                       entry->cdte_addr.msf.minute = bcd2bin(tocPtr -> diskTime.min);
-                       entry->cdte_addr.msf.second = bcd2bin(tocPtr -> diskTime.sec);
-                       entry->cdte_addr.msf.frame = bcd2bin(tocPtr -> diskTime.frame);
+                       entry->cdte_addr.lba = msf2hsg(&tocPtr->diskTime);
+
+               else if (entry->cdte_format == CDROM_MSF) {
+                       entry->cdte_addr.msf.minute =
+                           bcd2bin(tocPtr->diskTime.min);
+                       entry->cdte_addr.msf.second =
+                           bcd2bin(tocPtr->diskTime.sec);
+                       entry->cdte_addr.msf.frame =
+                           bcd2bin(tocPtr->diskTime.frame);
                }
 
                else
@@ -538,9 +527,9 @@ mcd_Play.end.min, mcd_Play.end.sec, mcd_Play.end.frame);
 
                return 0;
 
-       case CDROMSUBCHNL:   /* Get subchannel info */
+       case CDROMSUBCHNL:      /* Get subchannel info */
 
-                subchnl=(struct cdrom_subchnl *) arg;
+               subchnl = (struct cdrom_subchnl *) arg;
                if (GetQChannelInfo(&qInfo) < 0)
                        return -EIO;
 
@@ -549,16 +538,22 @@ mcd_Play.end.min, mcd_Play.end.sec, mcd_Play.end.frame);
                subchnl->cdsc_ctrl = qInfo.ctrl_addr >> 4;
                subchnl->cdsc_trk = bcd2bin(qInfo.track);
                subchnl->cdsc_ind = bcd2bin(qInfo.pointIndex);
-               subchnl->cdsc_absaddr.msf.minute = bcd2bin(qInfo.diskTime.min);
-               subchnl->cdsc_absaddr.msf.second = bcd2bin(qInfo.diskTime.sec);
-               subchnl->cdsc_absaddr.msf.frame = bcd2bin(qInfo.diskTime.frame);
-               subchnl->cdsc_reladdr.msf.minute = bcd2bin(qInfo.trackTime.min);
-               subchnl->cdsc_reladdr.msf.second = bcd2bin(qInfo.trackTime.sec);
-               subchnl->cdsc_reladdr.msf.frame = bcd2bin(qInfo.trackTime.frame);
-               return(0);
-
-       case CDROMVOLCTRL:   /* Volume control */
-               volctrl=(struct cdrom_volctrl *) arg;
+               subchnl->cdsc_absaddr.msf.minute =
+                   bcd2bin(qInfo.diskTime.min);
+               subchnl->cdsc_absaddr.msf.second =
+                   bcd2bin(qInfo.diskTime.sec);
+               subchnl->cdsc_absaddr.msf.frame =
+                   bcd2bin(qInfo.diskTime.frame);
+               subchnl->cdsc_reladdr.msf.minute =
+                   bcd2bin(qInfo.trackTime.min);
+               subchnl->cdsc_reladdr.msf.second =
+                   bcd2bin(qInfo.trackTime.sec);
+               subchnl->cdsc_reladdr.msf.frame =
+                   bcd2bin(qInfo.trackTime.frame);
+               return (0);
+
+       case CDROMVOLCTRL:      /* Volume control */
+               volctrl = (struct cdrom_volctrl *) arg;
                outb(MCMD_SET_VOLUME, MCDPORT(0));
                outb(volctrl->channel0, MCDPORT(0));
                outb(255, MCDPORT(0));
@@ -590,37 +585,38 @@ mcd_Play.end.min, mcd_Play.end.sec, mcd_Play.end.frame);
  * When Linux gets variable block sizes this will probably go away.
  */
 
-static void
-mcd_transfer(void)
+static void mcd_transfer(void)
 {
-  if (CURRENT_VALID) {
-    while (CURRENT -> nr_sectors) {
-      int bn = CURRENT -> sector / 4;
-      int i;
-      for (i = 0; i < MCD_BUF_SIZ && mcd_buf_bn[i] != bn; ++i)
-       ;
-      if (i < MCD_BUF_SIZ) {
-       int offs = (i * 4 + (CURRENT -> sector & 3)) * 512;
-       int nr_sectors = 4 - (CURRENT -> sector & 3);
-       if (mcd_buf_out != i) {
-         mcd_buf_out = i;
-         if (mcd_buf_bn[i] != bn) {
-           mcd_buf_out = -1;
-           continue;
-         }
+       if (CURRENT_VALID) {
+               while (CURRENT->nr_sectors) {
+                       int bn = CURRENT->sector / 4;
+                       int i;
+                       for (i = 0; i < MCD_BUF_SIZ && mcd_buf_bn[i] != bn;
+                            ++i);
+                       if (i < MCD_BUF_SIZ) {
+                               int offs =
+                                   (i * 4 + (CURRENT->sector & 3)) * 512;
+                               int nr_sectors = 4 - (CURRENT->sector & 3);
+                               if (mcd_buf_out != i) {
+                                       mcd_buf_out = i;
+                                       if (mcd_buf_bn[i] != bn) {
+                                               mcd_buf_out = -1;
+                                               continue;
+                                       }
+                               }
+                               if (nr_sectors > CURRENT->nr_sectors)
+                                       nr_sectors = CURRENT->nr_sectors;
+                               memcpy(CURRENT->buffer, mcd_buf + offs,
+                                      nr_sectors * 512);
+                               CURRENT->nr_sectors -= nr_sectors;
+                               CURRENT->sector += nr_sectors;
+                               CURRENT->buffer += nr_sectors * 512;
+                       } else {
+                               mcd_buf_out = -1;
+                               break;
+                       }
+               }
        }
-       if (nr_sectors > CURRENT -> nr_sectors)
-         nr_sectors = CURRENT -> nr_sectors;
-       memcpy(CURRENT -> buffer, mcd_buf + offs, nr_sectors * 512);
-       CURRENT -> nr_sectors -= nr_sectors;
-       CURRENT -> sector += nr_sectors;
-       CURRENT -> buffer += nr_sectors * 512;
-      } else {
-       mcd_buf_out = -1;
-       break;
-      }
-    }
-  }
 }
 
 
@@ -629,500 +625,512 @@ mcd_transfer(void)
  * Just take the interrupt and clear out the status reg.
  */
 
-static void
-mcd_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static void mcd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
        int st;
 
        st = inb(MCDPORT(1)) & 0xFF;
 #ifdef TEST1
-               printk("<int1-%02X>", st);
+       printk("<int1-%02X>", st);
 #endif
-       if (!(st & MFL_STATUS))
-       {
+       if (!(st & MFL_STATUS)) {
                st = inb(MCDPORT(0)) & 0xFF;
 #ifdef TEST1
                printk("<int0-%02X>", st);
 #endif
                if ((st & 0xFF) != 0xFF)
-                 mcd_error = st ? st & 0xFF : -1;
+                       mcd_error = st ? st & 0xFF : -1;
        }
 }
 
 
-static void
-do_mcd_request(request_queue_t * q)
+static void do_mcd_request(request_queue_t * q)
 {
 #ifdef TEST2
-  printk(" do_mcd_request(%ld+%ld)\n", CURRENT -> sector, CURRENT -> nr_sectors);
+       printk(" do_mcd_request(%ld+%ld)\n", CURRENT->sector,
+              CURRENT->nr_sectors);
 #endif
-  mcd_transfer_is_active = 1;
-  while (CURRENT_VALID) {
-    if (CURRENT->bh) {
-      if (!buffer_locked(CURRENT->bh))
-       panic(DEVICE_NAME ": block not locked");
-    }
-    mcd_transfer();
-    if (CURRENT -> nr_sectors == 0) {
-      end_request(1);
-    } else {
-      mcd_buf_out = -1;                /* Want to read a block not in buffer */
-      if (mcd_state == MCD_S_IDLE) {
-       if (!tocUpToDate) {
-         if (updateToc() < 0) {
-           while (CURRENT_VALID)
-             end_request(0);
-           break;
-         }
+       mcd_transfer_is_active = 1;
+       while (CURRENT_VALID) {
+               if (CURRENT->bh) {
+                       if (!buffer_locked(CURRENT->bh))
+                               panic(DEVICE_NAME ": block not locked");
+               }
+               mcd_transfer();
+               if (CURRENT->nr_sectors == 0) {
+                       end_request(1);
+               } else {
+                       mcd_buf_out = -1;       /* Want to read a block not in buffer */
+                       if (mcd_state == MCD_S_IDLE) {
+                               if (!tocUpToDate) {
+                                       if (updateToc() < 0) {
+                                               while (CURRENT_VALID)
+                                                       end_request(0);
+                                               break;
+                                       }
+                               }
+                               mcd_state = MCD_S_START;
+                               McdTries = 5;
+                               SET_TIMER(mcd_poll, 1);
+                       }
+                       break;
+               }
        }
-       mcd_state = MCD_S_START;
-       McdTries = 5;
-       SET_TIMER(mcd_poll, 1);
-      }
-      break;
-    }
-  }
-  mcd_transfer_is_active = 0;
+       mcd_transfer_is_active = 0;
 #ifdef TEST2
-  printk(" do_mcd_request ends\n");
+       printk(" do_mcd_request ends\n");
 #endif
 }
 
 
 
-static void
-mcd_poll(unsigned long dummy)
+static void mcd_poll(unsigned long dummy)
 {
-  int st;
-
-
-  if (mcd_error) 
-  {
-    if (mcd_error & 0xA5) 
-    {
-      printk("mcd: I/O error 0x%02x", mcd_error);
-      if (mcd_error & 0x80)
-       printk(" (Door open)");
-      if (mcd_error & 0x20)
-       printk(" (Disk changed)");
-      if (mcd_error & 0x04)
-       {
-       printk(" (Read error)"); /* Bitch about the problem. */
-       
-       /* Time to get fancy! If at 2x speed and 1 error, drop to 1x speed! */
-       /* Interesting how it STAYS at MCD_RETRY_ATTEMPTS on first error! */
-       /* But I find that rather HANDY!!! */
-       /* Neat! it REALLY WORKS on those LOW QUALITY CD's!!! Smile! :) */
-       /* AJK [06/17/95] */
-       
-       /* Slap the CD down to single speed! */
-       if (mcdDouble == 1 && McdTries == MCD_RETRY_ATTEMPTS && MCMD_DATA_READ == MCMD_2X_READ) 
-               {
-               MCMD_DATA_READ = MCMD_PLAY_READ; /* Uhhh, Ummmm, muhuh-huh! */
-               mcd1xhold = SINGLE_HOLD_SECTORS; /* Hey Beavis! */
-               printk(" Speed now 1x");         /* Pull my finger! */
-               }
-       }
-      printk("\n");
-      mcd_invalidate_buffers();
+       int st;
+
+
+       if (mcd_error) {
+               if (mcd_error & 0xA5) {
+                       printk("mcd: I/O error 0x%02x", mcd_error);
+                       if (mcd_error & 0x80)
+                               printk(" (Door open)");
+                       if (mcd_error & 0x20)
+                               printk(" (Disk changed)");
+                       if (mcd_error & 0x04) {
+                               printk(" (Read error)");        /* Bitch about the problem. */
+
+                               /* Time to get fancy! If at 2x speed and 1 error, drop to 1x speed! */
+                               /* Interesting how it STAYS at MCD_RETRY_ATTEMPTS on first error! */
+                               /* But I find that rather HANDY!!! */
+                               /* Neat! it REALLY WORKS on those LOW QUALITY CD's!!! Smile! :) */
+                               /* AJK [06/17/95] */
+
+                               /* Slap the CD down to single speed! */
+                               if (mcdDouble == 1
+                                   && McdTries == MCD_RETRY_ATTEMPTS
+                                   && MCMD_DATA_READ == MCMD_2X_READ) {
+                                       MCMD_DATA_READ = MCMD_PLAY_READ;        /* Uhhh, Ummmm, muhuh-huh! */
+                                       mcd1xhold = SINGLE_HOLD_SECTORS;        /* Hey Beavis! */
+                                       printk(" Speed now 1x");        /* Pull my finger! */
+                               }
+                       }
+                       printk("\n");
+                       mcd_invalidate_buffers();
 #ifdef WARN_IF_READ_FAILURE
-      if (McdTries == MCD_RETRY_ATTEMPTS)
-       printk("mcd: read of block %d failed\n", mcd_next_bn);
+                       if (McdTries == MCD_RETRY_ATTEMPTS)
+                               printk("mcd: read of block %d failed\n",
+                                      mcd_next_bn);
 #endif
-      if (!McdTries--) 
-        {
-       /* Nuts! This cd is ready for recycling! */
-       /* When WAS the last time YOU cleaned it CORRECTLY?! */
-       printk("mcd: read of block %d failed, giving up\n", mcd_next_bn);
-       if (mcd_transfer_is_active) 
-       {
-         McdTries = 0;
-         goto ret;
+                       if (!McdTries--) {
+                               /* Nuts! This cd is ready for recycling! */
+                               /* When WAS the last time YOU cleaned it CORRECTLY?! */
+                               printk
+                                   ("mcd: read of block %d failed, giving up\n",
+                                    mcd_next_bn);
+                               if (mcd_transfer_is_active) {
+                                       McdTries = 0;
+                                       goto ret;
+                               }
+                               if (CURRENT_VALID)
+                                       end_request(0);
+                               McdTries = MCD_RETRY_ATTEMPTS;
+                       }
+               }
+               mcd_error = 0;
+               mcd_state = MCD_S_STOP;
        }
-       if (CURRENT_VALID)
-         end_request(0);
-       McdTries = MCD_RETRY_ATTEMPTS;
-      }
-    }
-    mcd_error = 0;
-    mcd_state = MCD_S_STOP;
-  }
        /* Switch back to Double speed if enough GOOD sectors were read! */
-       
+
        /* Are we a double speed with a crappy CD?! */
-    if (mcdDouble == 1 && McdTries == MCD_RETRY_ATTEMPTS && MCMD_DATA_READ == MCMD_PLAY_READ)
-       {
-       /* We ARE a double speed and we ARE bitching! */
-       if (mcd1xhold == 0) /* Okay, Like are we STILL at single speed? */
-               { /* We need to switch back to double speed now... */
-               MCMD_DATA_READ = MCMD_2X_READ; /* Uhhh... BACK You GO! */
-               printk("mcd: Switching back to 2X speed!\n"); /* Tell 'em! */
-               }
-       else mcd1xhold--; /* No?! Count down the good reads some more... */
-                               /* and try, try again! */
-       }
+       if (mcdDouble == 1 && McdTries == MCD_RETRY_ATTEMPTS
+           && MCMD_DATA_READ == MCMD_PLAY_READ) {
+               /* We ARE a double speed and we ARE bitching! */
+               if (mcd1xhold == 0) {   /* Okay, Like are we STILL at single speed? *//* We need to switch back to double speed now... */
+                       MCMD_DATA_READ = MCMD_2X_READ;  /* Uhhh... BACK You GO! */
+                       printk("mcd: Switching back to 2X speed!\n");   /* Tell 'em! */
+               } else
+                       mcd1xhold--;    /* No?! Count down the good reads some more... */
+               /* and try, try again! */
+       }
 
 
 
- immediately:
-  switch (mcd_state) {
     immediately:
+       switch (mcd_state) {
 
 
 
-  case MCD_S_IDLE:
+       case MCD_S_IDLE:
 #ifdef TEST3
-    printk("MCD_S_IDLE\n");
+               printk("MCD_S_IDLE\n");
 #endif
-    goto out;
+               goto out;
 
 
 
-  case MCD_S_START:
+       case MCD_S_START:
 #ifdef TEST3
-    printk("MCD_S_START\n");
+               printk("MCD_S_START\n");
 #endif
 
-    outb(MCMD_GET_STATUS, MCDPORT(0));
-    mcd_state = mcd_mode == 1 ? MCD_S_READ : MCD_S_MODE;
-    McdTimeout = 3000;
-    break;
+               outb(MCMD_GET_STATUS, MCDPORT(0));
+               mcd_state = mcd_mode == 1 ? MCD_S_READ : MCD_S_MODE;
+               McdTimeout = 3000;
+               break;
 
 
 
-  case MCD_S_MODE:
+       case MCD_S_MODE:
 #ifdef TEST3
-    printk("MCD_S_MODE\n");
+               printk("MCD_S_MODE\n");
 #endif
 
-    if ((st = mcdStatus()) != -1) {
+               if ((st = mcdStatus()) != -1) {
 
-      if (st & MST_DSK_CHG) {
-       mcdDiskChanged = 1;
-       tocUpToDate = 0;
-       mcd_invalidate_buffers();
-      }
-
-    set_mode_immediately:
+                       if (st & MST_DSK_CHG) {
+                               mcdDiskChanged = 1;
+                               tocUpToDate = 0;
+                               mcd_invalidate_buffers();
+                       }
 
-      if ((st & MST_DOOR_OPEN) || !(st & MST_READY)) {
-       mcdDiskChanged = 1;
-       tocUpToDate = 0;
-       if (mcd_transfer_is_active) {
-         mcd_state = MCD_S_START;
-         goto immediately;
-       }
-       printk((st & MST_DOOR_OPEN) ? "mcd: door open\n" : "mcd: disk removed\n");
-       mcd_state = MCD_S_IDLE;
-       while (CURRENT_VALID)
-         end_request(0);
-       goto out;
-      }
+                     set_mode_immediately:
+
+                       if ((st & MST_DOOR_OPEN) || !(st & MST_READY)) {
+                               mcdDiskChanged = 1;
+                               tocUpToDate = 0;
+                               if (mcd_transfer_is_active) {
+                                       mcd_state = MCD_S_START;
+                                       goto immediately;
+                               }
+                               printk((st & MST_DOOR_OPEN) ?
+                                      "mcd: door open\n" :
+                                      "mcd: disk removed\n");
+                               mcd_state = MCD_S_IDLE;
+                               while (CURRENT_VALID)
+                                       end_request(0);
+                               goto out;
+                       }
 
-      outb(MCMD_SET_MODE, MCDPORT(0));
-      outb(1, MCDPORT(0));
-      mcd_mode = 1;
-      mcd_state = MCD_S_READ;
-      McdTimeout = 3000;
+                       outb(MCMD_SET_MODE, MCDPORT(0));
+                       outb(1, MCDPORT(0));
+                       mcd_mode = 1;
+                       mcd_state = MCD_S_READ;
+                       McdTimeout = 3000;
 
-    }
-    break;
+               }
+               break;
 
 
 
-  case MCD_S_READ:
+       case MCD_S_READ:
 #ifdef TEST3
-    printk("MCD_S_READ\n");
+               printk("MCD_S_READ\n");
 #endif
 
-    if ((st = mcdStatus()) != -1) {
+               if ((st = mcdStatus()) != -1) {
 
-      if (st & MST_DSK_CHG) {
-       mcdDiskChanged = 1;
-       tocUpToDate = 0;
-       mcd_invalidate_buffers();
-      }
+                       if (st & MST_DSK_CHG) {
+                               mcdDiskChanged = 1;
+                               tocUpToDate = 0;
+                               mcd_invalidate_buffers();
+                       }
 
-    read_immediately:
+                     read_immediately:
+
+                       if ((st & MST_DOOR_OPEN) || !(st & MST_READY)) {
+                               mcdDiskChanged = 1;
+                               tocUpToDate = 0;
+                               if (mcd_transfer_is_active) {
+                                       mcd_state = MCD_S_START;
+                                       goto immediately;
+                               }
+                               printk((st & MST_DOOR_OPEN) ?
+                                      "mcd: door open\n" :
+                                      "mcd: disk removed\n");
+                               mcd_state = MCD_S_IDLE;
+                               while (CURRENT_VALID)
+                                       end_request(0);
+                               goto out;
+                       }
 
-      if ((st & MST_DOOR_OPEN) || !(st & MST_READY)) {
-       mcdDiskChanged = 1;
-       tocUpToDate = 0;
-       if (mcd_transfer_is_active) {
-         mcd_state = MCD_S_START;
-         goto immediately;
-       }
-       printk((st & MST_DOOR_OPEN) ? "mcd: door open\n" : "mcd: disk removed\n");
-       mcd_state = MCD_S_IDLE;
-       while (CURRENT_VALID)
-         end_request(0);
-       goto out;
-      }
-
-      if (CURRENT_VALID) {
-       struct mcd_Play_msf msf;
-       mcd_next_bn = CURRENT -> sector / 4;
-       hsg2msf(mcd_next_bn, &msf.start);
-       msf.end.min = ~0;
-       msf.end.sec = ~0;
-       msf.end.frame = ~0;
-       sendMcdCmd(MCMD_DATA_READ, &msf);
-       mcd_state = MCD_S_DATA;
-       McdTimeout = READ_TIMEOUT;
-      } else {
-       mcd_state = MCD_S_STOP;
-       goto immediately;
-      }
-
-    }
-    break;
-
-
-  case MCD_S_DATA:
+                       if (CURRENT_VALID) {
+                               struct mcd_Play_msf msf;
+                               mcd_next_bn = CURRENT->sector / 4;
+                               hsg2msf(mcd_next_bn, &msf.start);
+                               msf.end.min = ~0;
+                               msf.end.sec = ~0;
+                               msf.end.frame = ~0;
+                               sendMcdCmd(MCMD_DATA_READ, &msf);
+                               mcd_state = MCD_S_DATA;
+                               McdTimeout = READ_TIMEOUT;
+                       } else {
+                               mcd_state = MCD_S_STOP;
+                               goto immediately;
+                       }
+
+               }
+               break;
+
+
+       case MCD_S_DATA:
 #ifdef TEST3
-    printk("MCD_S_DATA\n");
+               printk("MCD_S_DATA\n");
 #endif
 
-    st = inb(MCDPORT(1)) & (MFL_STATUSorDATA);
-  data_immediately:
+               st = inb(MCDPORT(1)) & (MFL_STATUSorDATA);
+             data_immediately:
 #ifdef TEST5
-    printk("Status %02x\n",st);
+               printk("Status %02x\n", st);
 #endif
-    switch (st) {
+               switch (st) {
 
-    case MFL_DATA:
+               case MFL_DATA:
 #ifdef WARN_IF_READ_FAILURE
-      if (McdTries == 5)
-       printk("mcd: read of block %d failed\n", mcd_next_bn);
+                       if (McdTries == 5)
+                               printk("mcd: read of block %d failed\n",
+                                      mcd_next_bn);
 #endif
-      if (!McdTries--) {
-       printk("mcd: read of block %d failed, giving up\n", mcd_next_bn);
-       if (mcd_transfer_is_active) {
-         McdTries = 0;
-         break;
-       }
-       if (CURRENT_VALID)
-         end_request(0);
-       McdTries = 5;
-      }
-      mcd_state = MCD_S_START;
-      McdTimeout = READ_TIMEOUT;
-      goto immediately;
-
-    case MFL_STATUSorDATA:
-      break;
-
-    default:
-      McdTries = 5;
-      if (!CURRENT_VALID && mcd_buf_in == mcd_buf_out) {
-       mcd_state = MCD_S_STOP;
-       goto immediately;
-      }
-      mcd_buf_bn[mcd_buf_in] = -1;
-      READ_DATA(MCDPORT(0), mcd_buf + 2048 * mcd_buf_in, 2048);
-      mcd_buf_bn[mcd_buf_in] = mcd_next_bn++;
-      if (mcd_buf_out == -1)
-       mcd_buf_out = mcd_buf_in;
-      mcd_buf_in = mcd_buf_in + 1 == MCD_BUF_SIZ ? 0 : mcd_buf_in + 1;
-      if (!mcd_transfer_is_active) {
-       while (CURRENT_VALID) {
-         mcd_transfer();
-         if (CURRENT -> nr_sectors == 0)
-           end_request(1);
-         else
-           break;
-       }
-      }
-
-      if (CURRENT_VALID
-         && (CURRENT -> sector / 4 < mcd_next_bn || 
-             CURRENT -> sector / 4 > mcd_next_bn + 16)) {
-       mcd_state = MCD_S_STOP;
-       goto immediately;
-      }
-      McdTimeout = READ_TIMEOUT;
+                       if (!McdTries--) {
+                               printk
+                                   ("mcd: read of block %d failed, giving up\n",
+                                    mcd_next_bn);
+                               if (mcd_transfer_is_active) {
+                                       McdTries = 0;
+                                       break;
+                               }
+                               if (CURRENT_VALID)
+                                       end_request(0);
+                               McdTries = 5;
+                       }
+                       mcd_state = MCD_S_START;
+                       McdTimeout = READ_TIMEOUT;
+                       goto immediately;
+
+               case MFL_STATUSorDATA:
+                       break;
+
+               default:
+                       McdTries = 5;
+                       if (!CURRENT_VALID && mcd_buf_in == mcd_buf_out) {
+                               mcd_state = MCD_S_STOP;
+                               goto immediately;
+                       }
+                       mcd_buf_bn[mcd_buf_in] = -1;
+                       READ_DATA(MCDPORT(0), mcd_buf + 2048 * mcd_buf_in,
+                                 2048);
+                       mcd_buf_bn[mcd_buf_in] = mcd_next_bn++;
+                       if (mcd_buf_out == -1)
+                               mcd_buf_out = mcd_buf_in;
+                       mcd_buf_in =
+                           mcd_buf_in + 1 ==
+                           MCD_BUF_SIZ ? 0 : mcd_buf_in + 1;
+                       if (!mcd_transfer_is_active) {
+                               while (CURRENT_VALID) {
+                                       mcd_transfer();
+                                       if (CURRENT->nr_sectors == 0)
+                                               end_request(1);
+                                       else
+                                               break;
+                               }
+                       }
+
+                       if (CURRENT_VALID
+                           && (CURRENT->sector / 4 < mcd_next_bn ||
+                               CURRENT->sector / 4 > mcd_next_bn + 16)) {
+                               mcd_state = MCD_S_STOP;
+                               goto immediately;
+                       }
+                       McdTimeout = READ_TIMEOUT;
 #ifdef DOUBLE_QUICK_ONLY
-      if (MCMD_DATA_READ != MCMD_PLAY_READ)
+                       if (MCMD_DATA_READ != MCMD_PLAY_READ)
 #endif
-      {
-       int count= QUICK_LOOP_COUNT;
-       while (count--) {
-          QUICK_LOOP_DELAY;
-         if ((st = (inb(MCDPORT(1))) & (MFL_STATUSorDATA)) != (MFL_STATUSorDATA)) {
+                       {
+                               int count = QUICK_LOOP_COUNT;
+                               while (count--) {
+                                       QUICK_LOOP_DELAY;
+                                       if ((st =
+                                            (inb(MCDPORT(1))) &
+                                            (MFL_STATUSorDATA)) !=
+                                           (MFL_STATUSorDATA)) {
 #   ifdef TEST4
 /*         printk("Quickloop success at %d\n",QUICK_LOOP_COUNT-count); */
-           printk(" %d ",QUICK_LOOP_COUNT-count);
+                                               printk(" %d ",
+                                                      QUICK_LOOP_COUNT -
+                                                      count);
 #   endif
-           goto data_immediately;
-         }
-       }
+                                               goto data_immediately;
+                                       }
+                               }
 #   ifdef TEST4
 /*      printk("Quickloop ended at %d\n",QUICK_LOOP_COUNT); */
-       printk("ended ");
+                               printk("ended ");
 #   endif
-      }
-      break;
-    }
-    break;
+                       }
+                       break;
+               }
+               break;
 
 
 
-  case MCD_S_STOP:
+       case MCD_S_STOP:
 #ifdef TEST3
-    printk("MCD_S_STOP\n");
+               printk("MCD_S_STOP\n");
 #endif
 
 #ifdef WORK_AROUND_MITSUMI_BUG_93
-    if (!mitsumi_bug_93_wait)
-      goto do_not_work_around_mitsumi_bug_93_1;
+               if (!mitsumi_bug_93_wait)
+                       goto do_not_work_around_mitsumi_bug_93_1;
 
-    McdTimeout = mitsumi_bug_93_wait;
-    mcd_state = 9+3+1;
-    break;
+               McdTimeout = mitsumi_bug_93_wait;
+               mcd_state = 9 + 3 + 1;
+               break;
 
-  case 9+3+1:
-    if (McdTimeout)
-      break;
+       case 9 + 3 + 1:
+               if (McdTimeout)
+                       break;
 
-  do_not_work_around_mitsumi_bug_93_1:
-#endif /* WORK_AROUND_MITSUMI_BUG_93 */
+             do_not_work_around_mitsumi_bug_93_1:
+#endif                         /* WORK_AROUND_MITSUMI_BUG_93 */
 
-    outb(MCMD_STOP, MCDPORT(0));
+               outb(MCMD_STOP, MCDPORT(0));
 
 #ifdef WORK_AROUND_MITSUMI_BUG_92
-    if ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == MFL_STATUS) {
-      int i = 4096;
-      do {
-       inb(MCDPORT(0));
-      } while ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == MFL_STATUS && --i);
-      outb(MCMD_STOP, MCDPORT(0));
-      if ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == MFL_STATUS) {
-       i = 4096;
-       do {
-         inb(MCDPORT(0));
-       } while ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == MFL_STATUS && --i);
-       outb(MCMD_STOP, MCDPORT(0));
-      }
-    }
-#endif /* WORK_AROUND_MITSUMI_BUG_92 */
-
-    mcd_state = MCD_S_STOPPING;
-    McdTimeout = 1000;
-    break;
-
-  case MCD_S_STOPPING:
+               if ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == MFL_STATUS) {
+                       int i = 4096;
+                       do {
+                               inb(MCDPORT(0));
+                       } while ((inb(MCDPORT(1)) & MFL_STATUSorDATA) ==
+                                MFL_STATUS && --i);
+                       outb(MCMD_STOP, MCDPORT(0));
+                       if ((inb(MCDPORT(1)) & MFL_STATUSorDATA) ==
+                           MFL_STATUS) {
+                               i = 4096;
+                               do {
+                                       inb(MCDPORT(0));
+                               } while ((inb(MCDPORT(1)) &
+                                         MFL_STATUSorDATA) == MFL_STATUS
+                                        && --i);
+                               outb(MCMD_STOP, MCDPORT(0));
+                       }
+               }
+#endif                         /* WORK_AROUND_MITSUMI_BUG_92 */
+
+               mcd_state = MCD_S_STOPPING;
+               McdTimeout = 1000;
+               break;
+
+       case MCD_S_STOPPING:
 #ifdef TEST3
-    printk("MCD_S_STOPPING\n");
+               printk("MCD_S_STOPPING\n");
 #endif
 
-    if ((st = mcdStatus()) == -1 && McdTimeout)
-      break;
-
-    if ((st != -1) && (st & MST_DSK_CHG)) {
-      mcdDiskChanged = 1;
-      tocUpToDate = 0;
-      mcd_invalidate_buffers();
-    }
+               if ((st = mcdStatus()) == -1 && McdTimeout)
+                       break;
 
+               if ((st != -1) && (st & MST_DSK_CHG)) {
+                       mcdDiskChanged = 1;
+                       tocUpToDate = 0;
+                       mcd_invalidate_buffers();
+               }
 #ifdef WORK_AROUND_MITSUMI_BUG_93
-    if (!mitsumi_bug_93_wait)
-      goto do_not_work_around_mitsumi_bug_93_2;
+               if (!mitsumi_bug_93_wait)
+                       goto do_not_work_around_mitsumi_bug_93_2;
 
-    McdTimeout = mitsumi_bug_93_wait;
-    mcd_state = 9+3+2;
-    break;
+               McdTimeout = mitsumi_bug_93_wait;
+               mcd_state = 9 + 3 + 2;
+               break;
 
-  case 9+3+2:
-    if (McdTimeout)
-      break;
+       case 9 + 3 + 2:
+               if (McdTimeout)
+                       break;
 
-    st = -1;
+               st = -1;
 
-  do_not_work_around_mitsumi_bug_93_2:
-#endif /* WORK_AROUND_MITSUMI_BUG_93 */
+             do_not_work_around_mitsumi_bug_93_2:
+#endif                         /* WORK_AROUND_MITSUMI_BUG_93 */
 
 #ifdef TEST3
-    printk("CURRENT_VALID %d mcd_mode %d\n",
-          CURRENT_VALID, mcd_mode);
+               printk("CURRENT_VALID %d mcd_mode %d\n",
+                      CURRENT_VALID, mcd_mode);
 #endif
 
-    if (CURRENT_VALID) {
-      if (st != -1) {
-       if (mcd_mode == 1)
-         goto read_immediately;
-       else
-         goto set_mode_immediately;
-      } else {
-       mcd_state = MCD_S_START;
-       McdTimeout = 1;
-      }
-    } else {
-      mcd_state = MCD_S_IDLE;
-      goto out;
-    }
-    break;
-
-  default:
-    printk("mcd: invalid state %d\n", mcd_state);
-    goto out;
-  }
-
- ret:
-  if (!McdTimeout--) {
-    printk("mcd: timeout in state %d\n", mcd_state);
-    mcd_state = MCD_S_STOP;
-  }
-
-  SET_TIMER(mcd_poll, 1);
-out:
-  return;
+               if (CURRENT_VALID) {
+                       if (st != -1) {
+                               if (mcd_mode == 1)
+                                       goto read_immediately;
+                               else
+                                       goto set_mode_immediately;
+                       } else {
+                               mcd_state = MCD_S_START;
+                               McdTimeout = 1;
+                       }
+               } else {
+                       mcd_state = MCD_S_IDLE;
+                       goto out;
+               }
+               break;
+
+       default:
+               printk("mcd: invalid state %d\n", mcd_state);
+               goto out;
+       }
+
     ret:
+       if (!McdTimeout--) {
+               printk("mcd: timeout in state %d\n", mcd_state);
+               mcd_state = MCD_S_STOP;
+       }
+
+       SET_TIMER(mcd_poll, 1);
+      out:
+       return;
 }
 
 
 
-static void
-mcd_invalidate_buffers(void)
+static void mcd_invalidate_buffers(void)
 {
-  int i;
-  for (i = 0; i < MCD_BUF_SIZ; ++i)
-    mcd_buf_bn[i] = -1;
-  mcd_buf_out = -1;
+       int i;
+       for (i = 0; i < MCD_BUF_SIZ; ++i)
+               mcd_buf_bn[i] = -1;
+       mcd_buf_out = -1;
 }
 
 
 /*
  * Open the device special file.  Check that a disk is in.
  */
-static int mcd_open(struct cdrom_device_info * cdi, int purpose)
+static int mcd_open(struct cdrom_device_info *cdi, int purpose)
 {
-       int st, count=0;
+       int st, count = 0;
        if (mcdPresent == 0)
-               return -ENXIO;                  /* no hardware */
+               return -ENXIO;  /* no hardware */
 
-        MOD_INC_USE_COUNT;
+       MOD_INC_USE_COUNT;
 
-        if (mcd_open_count || mcd_state != MCD_S_IDLE)
+       if (mcd_open_count || mcd_state != MCD_S_IDLE)
                goto bump_count;
 
-        mcd_invalidate_buffers();
-        do {
-                st = statusCmd();               /* check drive status */
-                if (st == -1)
-                        goto err_out;            /* drive doesn't respond */
-                if ((st & MST_READY) == 0) {    /* no disk? wait a sec... */
-                        current->state = TASK_INTERRUPTIBLE;
-                        schedule_timeout(HZ);
-                }
-        } while (((st & MST_READY) == 0) && count++ < MCD_RETRY_ATTEMPTS);
-
-        if (updateToc() < 0)
-                       goto err_out;
-
-bump_count:
+       mcd_invalidate_buffers();
+       do {
+               st = statusCmd();       /* check drive status */
+               if (st == -1)
+                       goto err_out;   /* drive doesn't respond */
+               if ((st & MST_READY) == 0) {    /* no disk? wait a sec... */
+                       current->state = TASK_INTERRUPTIBLE;
+                       schedule_timeout(HZ);
+               }
+       } while (((st & MST_READY) == 0) && count++ < MCD_RETRY_ATTEMPTS);
+
+       if (updateToc() < 0)
+               goto err_out;
+
+      bump_count:
        ++mcd_open_count;
        return 0;
 
-err_out:
-        MOD_DEC_USE_COUNT;
+      err_out:
+       MOD_DEC_USE_COUNT;
        return -EIO;
 }
 
@@ -1130,11 +1138,12 @@ err_out:
 /*
  * On close, we flush all mcd blocks from the buffer cache.
  */
-static void mcd_release(struct cdrom_device_info * cdi)
-{ MOD_DEC_USE_COUNT;
-  if (!--mcd_open_count) {
-       mcd_invalidate_buffers();
-  }
+static void mcd_release(struct cdrom_device_info *cdi)
+{
+       MOD_DEC_USE_COUNT;
+       if (!--mcd_open_count) {
+               mcd_invalidate_buffers();
+       }
 }
 
 
@@ -1143,23 +1152,25 @@ static void mcd_release(struct cdrom_device_info * cdi)
  * and is used in mcd_exit as well. */
 static void cleanup(int level)
 {
-  switch (level) {
-  case 3:
-    if (unregister_cdrom(&mcd_info)) {
-      printk(KERN_WARNING "Can't unregister cdrom mcd\n");
-      return;
-    }
-    free_irq(mcd_irq, NULL);
-  case 2:
-    release_region(mcd_port,4);
-  case 1:
-    if (devfs_unregister_blkdev(MAJOR_NR, "mcd")) {
-      printk(KERN_WARNING "Can't unregister major mcd\n");
-      return;
-    }
-    blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-  default:;
-  }
+       switch (level) {
+       case 3:
+               if (unregister_cdrom(&mcd_info)) {
+                       printk(KERN_WARNING
+                              "Can't unregister cdrom mcd\n");
+                       return;
+               }
+               free_irq(mcd_irq, NULL);
+       case 2:
+               release_region(mcd_port, 4);
+       case 1:
+               if (devfs_unregister_blkdev(MAJOR_NR, "mcd")) {
+                       printk(KERN_WARNING
+                              "Can't unregister major mcd\n");
+                       return;
+               }
+               blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+       default:;
+       }
 }
 
 
@@ -1175,21 +1186,20 @@ int __init mcd_init(void)
        char msg[80];
 
        if (mcd_port <= 0 || mcd_irq <= 0) {
-         printk("skip mcd_init\n");
-          return -EIO;
+               printk("skip mcd_init\n");
+               return -EIO;
        }
 
-       if (devfs_register_blkdev(MAJOR_NR, "mcd", &cdrom_fops) != 0)
-       {
+       if (devfs_register_blkdev(MAJOR_NR, "mcd", &cdrom_fops) != 0) {
                printk("Unable to get major %d for Mitsumi CD-ROM\n",
                       MAJOR_NR);
-                return -EIO;
+               return -EIO;
        }
-        if (check_region(mcd_port, 4)) {
-         cleanup(1);
-         printk("Init failed, I/O port (%X) already in use\n",
-                mcd_port);
-          return -EIO;
+       if (check_region(mcd_port, 4)) {
+               cleanup(1);
+               printk("Init failed, I/O port (%X) already in use\n",
+                      mcd_port);
+               return -EIO;
        }
 
        blksize_size[MAJOR_NR] = mcd_blocksizes;
@@ -1198,106 +1208,105 @@ int __init mcd_init(void)
 
        /* check for card */
 
-       outb(0, MCDPORT(1));                    /* send reset */
+       outb(0, MCDPORT(1));    /* send reset */
        for (count = 0; count < 2000000; count++)
-               (void) inb(MCDPORT(1));         /* delay a bit */
+               (void) inb(MCDPORT(1)); /* delay a bit */
 
-       outb(0x40, MCDPORT(0));                 /* send get-stat cmd */
+       outb(0x40, MCDPORT(0)); /* send get-stat cmd */
        for (count = 0; count < 2000000; count++)
                if (!(inb(MCDPORT(1)) & MFL_STATUS))
                        break;
 
        if (count >= 2000000) {
                printk("Init failed. No mcd device at 0x%x irq %d\n",
-                    mcd_port, mcd_irq);
+                      mcd_port, mcd_irq);
                cleanup(1);
-                return -EIO;
+               return -EIO;
        }
-       count = inb(MCDPORT(0));                /* pick up the status */
-       
-       outb(MCMD_GET_VERSION,MCDPORT(0));
-       for(count=0;count<3;count++)
-               if(getValue(result+count)) {
+       count = inb(MCDPORT(0));        /* pick up the status */
+
+       outb(MCMD_GET_VERSION, MCDPORT(0));
+       for (count = 0; count < 3; count++)
+               if (getValue(result + count)) {
                        printk("mitsumi get version failed at 0x%x\n",
                               mcd_port);
-                        cleanup(1);
-                        return -EIO;
-               }       
+                       cleanup(1);
+                       return -EIO;
+               }
 
        if (result[0] == result[1] && result[1] == result[2]) {
                cleanup(1);
-                return -EIO;
+               return -EIO;
        }
 
-       mcdVersion=result[2];
+       mcdVersion = result[2];
 
-       if (mcdVersion >=4)
-               outb(4,MCDPORT(2));     /* magic happens */
+       if (mcdVersion >= 4)
+               outb(4, MCDPORT(2));    /* magic happens */
 
        /* don't get the IRQ until we know for sure the drive is there */
 
-       if (request_irq(mcd_irq, mcd_interrupt, SA_INTERRUPT, "Mitsumi CD", NULL))
-       {
-               printk("Unable to get IRQ%d for Mitsumi CD-ROM\n", mcd_irq);
+       if (request_irq
+           (mcd_irq, mcd_interrupt, SA_INTERRUPT, "Mitsumi CD", NULL)) {
+               printk("Unable to get IRQ%d for Mitsumi CD-ROM\n",
+                      mcd_irq);
                cleanup(1);
-                return -EIO;
+               return -EIO;
        }
 
-        if (result[1] == 'D') 
-       {
+       if (result[1] == 'D') {
                MCMD_DATA_READ = MCMD_2X_READ;
                /* Added flag to drop to 1x speed if too many errors */
                mcdDouble = 1;
-        } else 
+       } else
                mcd_info.speed = 1;
        sprintf(msg, " mcd: Mitsumi %s Speed CD-ROM at port=0x%x,"
-                    " irq=%d\n", mcd_info.speed == 1 ?  "Single" : "Double", mcd_port, mcd_irq);
+               " irq=%d\n", mcd_info.speed == 1 ? "Single" : "Double",
+               mcd_port, mcd_irq);
 
        request_region(mcd_port, 4, "mcd");
 
        outb(MCMD_CONFIG_DRIVE, MCDPORT(0));
-       outb(0x02,MCDPORT(0));
-       outb(0x00,MCDPORT(0));
+       outb(0x02, MCDPORT(0));
+       outb(0x00, MCDPORT(0));
        getValue(result);
 
        outb(MCMD_CONFIG_DRIVE, MCDPORT(0));
-       outb(0x10,MCDPORT(0));
-       outb(0x04,MCDPORT(0));
+       outb(0x10, MCDPORT(0));
+       outb(0x04, MCDPORT(0));
        getValue(result);
 
        mcd_invalidate_buffers();
        mcdPresent = 1;
 
-       mcd_info.dev = MKDEV(MAJOR_NR,0);
+       mcd_info.dev = MKDEV(MAJOR_NR, 0);
 
-        if (register_cdrom(&mcd_info) != 0) {
-              printk("Cannot register Mitsumi CD-ROM!\n");
-              cleanup(3);
-              return -EIO;
-        }
-        printk(msg);
+       if (register_cdrom(&mcd_info) != 0) {
+               printk("Cannot register Mitsumi CD-ROM!\n");
+               cleanup(3);
+               return -EIO;
+       }
+       printk(msg);
 
        return 0;
 }
 
 
-static void
-hsg2msf(long hsg, struct msf *msf)
+static void hsg2msf(long hsg, struct msf *msf)
 {
        hsg += 150;
-       msf -> min = hsg / 4500;
+       msf->min = hsg / 4500;
        hsg %= 4500;
-       msf -> sec = hsg / 75;
-       msf -> frame = hsg % 75;
+       msf->sec = hsg / 75;
+       msf->frame = hsg % 75;
 
-       bin2bcd(&msf -> min);           /* convert to BCD */
-       bin2bcd(&msf -> sec);
-       bin2bcd(&msf -> frame);
+       bin2bcd(&msf->min);     /* convert to BCD */
+       bin2bcd(&msf->sec);
+       bin2bcd(&msf->frame);
 }
 
 
-static void
-bin2bcd(unsigned char *p)
+static void bin2bcd(unsigned char *p)
 {
        int u, t;
 
@@ -1306,8 +1315,7 @@ bin2bcd(unsigned char *p)
        *p = u | (t << 4);
 }
 
-static int
-bcd2bin(unsigned char bcd)
+static int bcd2bin(unsigned char bcd)
 {
        return (bcd >> 4) * 10 + (bcd & 0xF);
 }
@@ -1318,19 +1326,16 @@ bcd2bin(unsigned char bcd)
  * if it is ready.
  */
 
-static int
-mcdStatus(void)
+static int mcdStatus(void)
 {
        int i;
        int st;
 
        st = inb(MCDPORT(1)) & MFL_STATUS;
-       if (!st)
-       {
+       if (!st) {
                i = inb(MCDPORT(0)) & 0xFF;
                return i;
-       }
-       else
+       } else
                return -1;
 }
 
@@ -1339,16 +1344,15 @@ mcdStatus(void)
  * Send a play or read command to the drive
  */
 
-static void
-sendMcdCmd(int cmd, struct mcd_Play_msf *params)
+static void sendMcdCmd(int cmd, struct mcd_Play_msf *params)
 {
        outb(cmd, MCDPORT(0));
-       outb(params -> start.min, MCDPORT(0));
-       outb(params -> start.sec, MCDPORT(0));
-       outb(params -> start.frame, MCDPORT(0));
-       outb(params -> end.min, MCDPORT(0));
-       outb(params -> end.sec, MCDPORT(0));
-       outb(params -> end.frame, MCDPORT(0));
+       outb(params->start.min, MCDPORT(0));
+       outb(params->start.sec, MCDPORT(0));
+       outb(params->start.frame, MCDPORT(0));
+       outb(params->end.min, MCDPORT(0));
+       outb(params->end.sec, MCDPORT(0));
+       outb(params->end.frame, MCDPORT(0));
 }
 
 
@@ -1357,18 +1361,15 @@ sendMcdCmd(int cmd, struct mcd_Play_msf *params)
  * (see the next routine)
  */
 
-static void
-mcdStatTimer(unsigned long dummy)
+static void mcdStatTimer(unsigned long dummy)
 {
-       if (!(inb(MCDPORT(1)) & MFL_STATUS))
-       {
+       if (!(inb(MCDPORT(1)) & MFL_STATUS)) {
                wake_up(&mcd_waitq);
                return;
        }
 
        McdTimeout--;
-       if (McdTimeout <= 0)
-       {
+       if (McdTimeout <= 0) {
                wake_up(&mcd_waitq);
                return;
        }
@@ -1383,8 +1384,7 @@ mcdStatTimer(unsigned long dummy)
  * excessive rescheduling.
  */
 
-static int
-getMcdStatus(int timeout)
+static int getMcdStatus(int timeout)
 {
        int st;
 
@@ -1402,8 +1402,7 @@ getMcdStatus(int timeout)
                /* XXX might be an error? look at q-channel? */
                audioStatus = CDROM_AUDIO_COMPLETED;
 
-       if (st & MST_DSK_CHG)
-       {
+       if (st & MST_DSK_CHG) {
                mcdDiskChanged = 1;
                tocUpToDate = 0;
                audioStatus = CDROM_AUDIO_NO_STATUS;
@@ -1415,18 +1414,22 @@ getMcdStatus(int timeout)
 
 /* gives current state of the drive This function is quite unreliable, 
    and should probably be rewritten by someone, eventually... */
-int mcd_drive_status(struct cdrom_device_info * cdi, int slot_nr)
+int mcd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
 {
-  int st;
-
-  st = statusCmd();               /* check drive status */
-  if (st == -1)
-      return -EIO;            /* drive doesn't respond */
-  if ((st & MST_READY)) return CDS_DISC_OK;
-  if ((st & MST_DOOR_OPEN)) return CDS_TRAY_OPEN;
-  if ((st & MST_DSK_CHG)) return CDS_NO_DISC;
-  if ((st & MST_BUSY)) return CDS_DRIVE_NOT_READY;
-  return -EIO;
+       int st;
+
+       st = statusCmd();       /* check drive status */
+       if (st == -1)
+               return -EIO;    /* drive doesn't respond */
+       if ((st & MST_READY))
+               return CDS_DISC_OK;
+       if ((st & MST_DOOR_OPEN))
+               return CDS_TRAY_OPEN;
+       if ((st & MST_DSK_CHG))
+               return CDS_NO_DISC;
+       if ((st & MST_BUSY))
+               return CDS_DRIVE_NOT_READY;
+       return -EIO;
 }
 
 
@@ -1434,18 +1437,16 @@ int mcd_drive_status(struct cdrom_device_info * cdi, int slot_nr)
  * Read a value from the drive.
  */
 
-static int
-getValue(unsigned char *result)
+static int getValue(unsigned char *result)
 {
-        int count;
+       int count;
        int s;
 
        for (count = 0; count < 2000; count++)
                if (!(inb(MCDPORT(1)) & MFL_STATUS))
                        break;
 
-       if (count >= 2000)
-       {
+       if (count >= 2000) {
                printk("mcd: getValue timeout\n");
                return -1;
        }
@@ -1461,14 +1462,12 @@ getValue(unsigned char *result)
  * table of contents.
  */
 
-int
-GetQChannelInfo(struct mcd_Toc *qp)
+int GetQChannelInfo(struct mcd_Toc *qp)
 {
        unsigned char notUsed;
        int retry;
 
-       for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
-       {
+       for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
                outb(MCMD_GET_Q_CHANNEL, MCDPORT(0));
                if (getMcdStatus(MCD_STATUS_DELAY) != -1)
                        break;
@@ -1477,16 +1476,26 @@ GetQChannelInfo(struct mcd_Toc *qp)
        if (retry >= MCD_RETRY_ATTEMPTS)
                return -1;
 
-       if (getValue(&qp -> ctrl_addr) < 0) return -1;
-       if (getValue(&qp -> track) < 0) return -1;
-       if (getValue(&qp -> pointIndex) < 0) return -1;
-       if (getValue(&qp -> trackTime.min) < 0) return -1;
-       if (getValue(&qp -> trackTime.sec) < 0) return -1;
-       if (getValue(&qp -> trackTime.frame) < 0) return -1;
-       if (getValue(&notUsed) < 0) return -1;
-       if (getValue(&qp -> diskTime.min) < 0) return -1;
-       if (getValue(&qp -> diskTime.sec) < 0) return -1;
-       if (getValue(&qp -> diskTime.frame) < 0) return -1;
+       if (getValue(&qp->ctrl_addr) < 0)
+               return -1;
+       if (getValue(&qp->track) < 0)
+               return -1;
+       if (getValue(&qp->pointIndex) < 0)
+               return -1;
+       if (getValue(&qp->trackTime.min) < 0)
+               return -1;
+       if (getValue(&qp->trackTime.sec) < 0)
+               return -1;
+       if (getValue(&qp->trackTime.frame) < 0)
+               return -1;
+       if (getValue(&notUsed) < 0)
+               return -1;
+       if (getValue(&qp->diskTime.min) < 0)
+               return -1;
+       if (getValue(&qp->diskTime.sec) < 0)
+               return -1;
+       if (getValue(&qp->diskTime.frame) < 0)
+               return -1;
 
        return 0;
 }
@@ -1496,8 +1505,7 @@ GetQChannelInfo(struct mcd_Toc *qp)
  * Read the table of contents (TOC) and TOC header if necessary
  */
 
-static int
-updateToc()
+static int updateToc()
 {
        if (tocUpToDate)
                return 0;
@@ -1517,13 +1525,11 @@ updateToc()
  * Read the table of contents header
  */
 
-static int
-GetDiskInfo()
+static int GetDiskInfo()
 {
        int retry;
 
-       for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
-       {
+       for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
                outb(MCMD_GET_DISK_INFO, MCDPORT(0));
                if (getMcdStatus(MCD_STATUS_DELAY) != -1)
                        break;
@@ -1532,30 +1538,35 @@ GetDiskInfo()
        if (retry >= MCD_RETRY_ATTEMPTS)
                return -1;
 
-       if (getValue(&DiskInfo.first) < 0) return -1;
-       if (getValue(&DiskInfo.last) < 0) return -1;
+       if (getValue(&DiskInfo.first) < 0)
+               return -1;
+       if (getValue(&DiskInfo.last) < 0)
+               return -1;
 
        DiskInfo.first = bcd2bin(DiskInfo.first);
        DiskInfo.last = bcd2bin(DiskInfo.last);
 
 #ifdef MCD_DEBUG
-printk("Disk Info: first %d last %d length %02x:%02x.%02x first %02x:%02x.%02x\n",
-       DiskInfo.first,
-       DiskInfo.last,
-       DiskInfo.diskLength.min,
-       DiskInfo.diskLength.sec,
-       DiskInfo.diskLength.frame,
-       DiskInfo.firstTrack.min,
-       DiskInfo.firstTrack.sec,
-       DiskInfo.firstTrack.frame);
+       printk
+           ("Disk Info: first %d last %d length %02x:%02x.%02x first %02x:%02x.%02x\n",
+            DiskInfo.first, DiskInfo.last, DiskInfo.diskLength.min,
+            DiskInfo.diskLength.sec, DiskInfo.diskLength.frame,
+            DiskInfo.firstTrack.min, DiskInfo.firstTrack.sec,
+            DiskInfo.firstTrack.frame);
 #endif
 
-       if (getValue(&DiskInfo.diskLength.min) < 0) return -1;
-       if (getValue(&DiskInfo.diskLength.sec) < 0) return -1;
-       if (getValue(&DiskInfo.diskLength.frame) < 0) return -1;
-       if (getValue(&DiskInfo.firstTrack.min) < 0) return -1;
-       if (getValue(&DiskInfo.firstTrack.sec) < 0) return -1;
-       if (getValue(&DiskInfo.firstTrack.frame) < 0) return -1;
+       if (getValue(&DiskInfo.diskLength.min) < 0)
+               return -1;
+       if (getValue(&DiskInfo.diskLength.sec) < 0)
+               return -1;
+       if (getValue(&DiskInfo.diskLength.frame) < 0)
+               return -1;
+       if (getValue(&DiskInfo.firstTrack.min) < 0)
+               return -1;
+       if (getValue(&DiskInfo.firstTrack.sec) < 0)
+               return -1;
+       if (getValue(&DiskInfo.firstTrack.frame) < 0)
+               return -1;
 
        return 0;
 }
@@ -1565,8 +1576,7 @@ printk("Disk Info: first %d last %d length %02x:%02x.%02x first %02x:%02x.%02x\n
  * Read the table of contents (TOC)
  */
 
-static int
-GetToc()
+static int GetToc()
 {
        int i, px;
        int limit;
@@ -1578,8 +1588,7 @@ GetToc()
 
        i = DiskInfo.last + 3;
 
-       for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
-       {
+       for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
                outb(MCMD_STOP, MCDPORT(0));
                if (getMcdStatus(MCD_STATUS_DELAY) != -1)
                        break;
@@ -1588,10 +1597,9 @@ GetToc()
        if (retry >= MCD_RETRY_ATTEMPTS)
                return -1;
 
-       for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
-       {
+       for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
                outb(MCMD_SET_MODE, MCDPORT(0));
-               outb(0x05, MCDPORT(0));                 /* mode: toc */
+               outb(0x05, MCDPORT(0)); /* mode: toc */
                mcd_mode = 0x05;
                if (getMcdStatus(MCD_STATUS_DELAY) != -1)
                        break;
@@ -1600,15 +1608,13 @@ GetToc()
        if (retry >= MCD_RETRY_ATTEMPTS)
                return -1;
 
-       for (limit = 300; limit > 0; limit--)
-       {
+       for (limit = 300; limit > 0; limit--) {
                if (GetQChannelInfo(&qInfo) < 0)
                        break;
 
                px = bcd2bin(qInfo.pointIndex);
                if (px > 0 && px < MAX_TRACKS && qInfo.track == 0)
-                       if (Toc[px].pointIndex == 0)
-                       {
+                       if (Toc[px].pointIndex == 0) {
                                Toc[px] = qInfo;
                                i--;
                        }
@@ -1619,26 +1625,29 @@ GetToc()
 
        Toc[DiskInfo.last + 1].diskTime = DiskInfo.diskLength;
 
-       for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
-       {
-                outb(MCMD_SET_MODE, MCDPORT(0));
-                outb(0x01, MCDPORT(0));
+       for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
+               outb(MCMD_SET_MODE, MCDPORT(0));
+               outb(0x01, MCDPORT(0));
                mcd_mode = 1;
-                if (getMcdStatus(MCD_STATUS_DELAY) != -1)
-                        break;
+               if (getMcdStatus(MCD_STATUS_DELAY) != -1)
+                       break;
        }
 
 #ifdef MCD_DEBUG
-for (i = 1; i <= DiskInfo.last; i++)
-printk("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X    %02X:%02X.%02X\n",
-i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
-Toc[i].trackTime.min, Toc[i].trackTime.sec, Toc[i].trackTime.frame,
-Toc[i].diskTime.min, Toc[i].diskTime.sec, Toc[i].diskTime.frame);
-for (i = 100; i < 103; i++)
-printk("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X    %02X:%02X.%02X\n",
-i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
-Toc[i].trackTime.min, Toc[i].trackTime.sec, Toc[i].trackTime.frame,
-Toc[i].diskTime.min, Toc[i].diskTime.sec, Toc[i].diskTime.frame);
+       for (i = 1; i <= DiskInfo.last; i++)
+               printk
+                   ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X    %02X:%02X.%02X\n",
+                    i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
+                    Toc[i].trackTime.min, Toc[i].trackTime.sec,
+                    Toc[i].trackTime.frame, Toc[i].diskTime.min,
+                    Toc[i].diskTime.sec, Toc[i].diskTime.frame);
+       for (i = 100; i < 103; i++)
+               printk
+                   ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X    %02X:%02X.%02X\n",
+                    i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
+                    Toc[i].trackTime.min, Toc[i].trackTime.sec,
+                    Toc[i].trackTime.frame, Toc[i].diskTime.min,
+                    Toc[i].diskTime.sec, Toc[i].diskTime.frame);
 #endif
 
        return limit > 0 ? 0 : -1;
@@ -1647,13 +1656,14 @@ Toc[i].diskTime.min, Toc[i].diskTime.sec, Toc[i].diskTime.frame);
 
 void __exit mcd_exit(void)
 {
-  cleanup(3);
-  del_timer_sync(&mcd_timer);
+       cleanup(3);
+       del_timer_sync(&mcd_timer);
 }
 
 #ifdef MODULE
 module_init(mcd_init);
-#endif 
+#endif
 module_exit(mcd_exit);
 
-
+MODULE_AUTHOR("Martin Harriss");
+MODULE_LICENSE("GPL");
index feb6ce8c243fbb6c3419814c1873d9884bd6bbc6..b4994239947a87201ed632af14dfb06edec4fd8f 100644 (file)
@@ -53,7 +53,7 @@
 
 #if RCS
 static const char *mcdx_c_version
-               = "$Id: mcdx.c,v 1.21 1997/01/26 07:12:59 davem Exp $";
+    = "$Id: mcdx.c,v 1.21 1997/01/26 07:12:59 davem Exp $";
 #endif
 
 #include <linux/version.h>
@@ -120,10 +120,10 @@ enum drivemodes { TOC, DATA, RAW, COOKED };
 enum datamodes { MODE0, MODE1, MODE2 };
 enum resetmodes { SOFT, HARD };
 
-const int SINGLE = 0x01;               /* single speed drive (FX001S, LU) */
-const int DOUBLE = 0x02;               /* double speed drive (FX001D, ..? */
-const int DOOR   = 0x04;               /* door locking capability */
-const int MULTI  = 0x08;               /* multi session capability */
+const int SINGLE = 0x01;       /* single speed drive (FX001S, LU) */
+const int DOUBLE = 0x02;       /* double speed drive (FX001D, ..? */
+const int DOOR = 0x04;         /* door locking capability */
+const int MULTI = 0x08;                /* multi session capability */
 
 const unsigned char READ1X = 0xc0;
 const unsigned char READ2X = 0xc1;
@@ -159,53 +159,53 @@ struct s_version {
 
 struct s_drive_stuff {
        /* waitqueues */
-    wait_queue_head_t busyq;
-    wait_queue_head_t lockq;
-    wait_queue_head_t sleepq;
+       wait_queue_head_t busyq;
+       wait_queue_head_t lockq;
+       wait_queue_head_t sleepq;
 
-       /* flags */
-    volatile int introk;       /* status of last irq operation */
-    volatile int busy;         /* drive performs an operation */
-    volatile int lock;         /* exclusive usage */
+       /* flags */
+       volatile int introk;    /* status of last irq operation */
+       volatile int busy;      /* drive performs an operation */
+       volatile int lock;      /* exclusive usage */
 
        /* cd infos */
        struct s_diskinfo di;
        struct s_multi multi;
-       struct s_subqcodetoc; /* first entry of the toc array */
+       struct s_subqcode *toc; /* first entry of the toc array */
        struct s_subqcode start;
-    struct s_subqcode stop;
-       int xa;                                 /* 1 if xa disk */
-       int audio;                              /* 1 if audio disk */
+       struct s_subqcode stop;
+       int xa;                 /* 1 if xa disk */
+       int audio;              /* 1 if audio disk */
        int audiostatus;
 
        /* `buffer' control */
-    volatile int valid;                        /* pending, ..., values are valid */
-    volatile int pending;              /* next sector to be read */
-    volatile int low_border;   /* first sector not to be skipped direct */
-    volatile int high_border; /* first sector `out of area' */
+       volatile int valid;     /* pending, ..., values are valid */
+       volatile int pending;   /* next sector to be read */
+       volatile int low_border;        /* first sector not to be skipped direct */
+       volatile int high_border;       /* first sector `out of area' */
 #ifdef AK2
-    volatile int int_err;
-#endif /* AK2 */
+       volatile int int_err;
+#endif                         /* AK2 */
 
        /* adds and odds */
-       voidwreg_data;        /* w data */
-       voidwreg_reset;       /* w hardware reset */
-       voidwreg_hcon;        /* w hardware conf */
-       voidwreg_chn;         /* w channel */
-       voidrreg_data;        /* r data */
-       voidrreg_status;      /* r status */
-
-    int irq;                   /* irq used by this drive */
-    int minor;                 /* minor number of this drive */
-    int present;           /* drive present and its capabilities */
-    unsigned char readcmd;     /* read cmd depends on single/double speed */
-    unsigned char playcmd;  /* play should always be single speed */
-    unsigned int xxx;      /* set if changed, reset while open */
-    unsigned int yyy;      /* set if changed, reset by media_changed */
-    int users;                         /* keeps track of open/close */
-    int lastsector;                    /* last block accessible */
-    int status;                                /* last operation's error / status */
-       int readerrs;                   /* # of blocks read w/o error */
+       void *wreg_data;        /* w data */
+       void *wreg_reset;       /* w hardware reset */
+       void *wreg_hcon;        /* w hardware conf */
+       void *wreg_chn;         /* w channel */
+       void *rreg_data;        /* r data */
+       void *rreg_status;      /* r status */
+
+       int irq;                /* irq used by this drive */
+       int minor;              /* minor number of this drive */
+       int present;            /* drive present and its capabilities */
+       unsigned char readcmd;  /* read cmd depends on single/double speed */
+       unsigned char playcmd;  /* play should always be single speed */
+       unsigned int xxx;       /* set if changed, reset while open */
+       unsigned int yyy;       /* set if changed, reset by media_changed */
+       int users;              /* keeps track of open/close */
+       int lastsector;         /* last block accessible */
+       int status;             /* last operation's error / status */
+       int readerrs;           /* # of blocks read w/o error */
 };
 
 
@@ -225,299 +225,333 @@ void do_mcdx_request(request_queue_t * q);
        structure mcdx_dops. */
 
 /* ???  exported by the mcdx_sigaction struct */
-static void mcdx_intr(int, void *, struct pt_regs*);
+static void mcdx_intr(int, void *, struct pt_regs *);
 
 /* exported by file_ops */
-static int mcdx_open(struct cdrom_device_info * cdi, int purpose);
-static void mcdx_close(struct cdrom_device_info * cdi);
-static int mcdx_media_changed(struct cdrom_device_info * cdi, int disc_nr);
-static int mcdx_tray_move(struct cdrom_device_info * cdi, int position);
-static int mcdx_lockdoor(struct cdrom_device_info * cdi, int lock);
-static int mcdx_audio_ioctl(struct cdrom_device_info * cdi, unsigned int cmd,
-                      void * arg);
+static int mcdx_open(struct cdrom_device_info *cdi, int purpose);
+static void mcdx_close(struct cdrom_device_info *cdi);
+static int mcdx_media_changed(struct cdrom_device_info *cdi, int disc_nr);
+static int mcdx_tray_move(struct cdrom_device_info *cdi, int position);
+static int mcdx_lockdoor(struct cdrom_device_info *cdi, int lock);
+static int mcdx_audio_ioctl(struct cdrom_device_info *cdi,
+                           unsigned int cmd, void *arg);
 
 /* misc internal support functions */
-static void log2msf(unsigned int, struct cdrom_msf0*);
-static unsigned int msf2log(const struct cdrom_msf0*);
+static void log2msf(unsigned int, struct cdrom_msf0 *);
+static unsigned int msf2log(const struct cdrom_msf0 *);
 static unsigned int uint2bcd(unsigned int);
 static unsigned int bcd2uint(unsigned char);
-static char *port(int*);
-static int irq(int*);
-static void mcdx_delay(struct s_drive_stuff*, long jifs);
-static int mcdx_transfer(struct s_drive_stuff*, char* buf, int sector, int nr_sectors);
-static int mcdx_xfer(struct s_drive_stuff*, char* buf, int sector, int nr_sectors);
-
-static int mcdx_config(struct s_drive_stuff*, int);
-static int mcdx_requestversion(struct s_drive_stuff*, struct s_version*, int);
-static int mcdx_stop(struct s_drive_stuff*, int);
-static int mcdx_hold(struct s_drive_stuff*, int);
-static int mcdx_reset(struct s_drive_stuff*, enum resetmodes, int);
-static int mcdx_setdrivemode(struct s_drive_stuff*, enum drivemodes, int);
-static int mcdx_setdatamode(struct s_drive_stuff*, enum datamodes, int);
-static int mcdx_requestsubqcode(struct s_drive_stuff*, struct s_subqcode*, int);
-static int mcdx_requestmultidiskinfo(struct s_drive_stuff*, struct s_multi*, int);
-static int mcdx_requesttocdata(struct s_drive_stuff*, struct s_diskinfo*, int);
-static int mcdx_getstatus(struct s_drive_stuff*, int);
-static int mcdx_getval(struct s_drive_stuff*, int to, int delay, char*);
-static int mcdx_talk(struct s_drive_stuff*,
-               const unsigned char* cmd, size_t,
-        void *buffer, size_t size,
-        unsigned int timeout, int);
-static int mcdx_readtoc(struct s_drive_stuff*);
-static int mcdx_playtrk(struct s_drive_stuff*, const struct cdrom_ti*);
-static int mcdx_playmsf(struct s_drive_stuff*, const struct cdrom_msf*);
-static int mcdx_setattentuator(struct s_drive_stuff*, struct cdrom_volctrl*, int);
+static char *port(int *);
+static int irq(int *);
+static void mcdx_delay(struct s_drive_stuff *, long jifs);
+static int mcdx_transfer(struct s_drive_stuff *, char *buf, int sector,
+                        int nr_sectors);
+static int mcdx_xfer(struct s_drive_stuff *, char *buf, int sector,
+                    int nr_sectors);
+
+static int mcdx_config(struct s_drive_stuff *, int);
+static int mcdx_requestversion(struct s_drive_stuff *, struct s_version *,
+                              int);
+static int mcdx_stop(struct s_drive_stuff *, int);
+static int mcdx_hold(struct s_drive_stuff *, int);
+static int mcdx_reset(struct s_drive_stuff *, enum resetmodes, int);
+static int mcdx_setdrivemode(struct s_drive_stuff *, enum drivemodes, int);
+static int mcdx_setdatamode(struct s_drive_stuff *, enum datamodes, int);
+static int mcdx_requestsubqcode(struct s_drive_stuff *,
+                               struct s_subqcode *, int);
+static int mcdx_requestmultidiskinfo(struct s_drive_stuff *,
+                                    struct s_multi *, int);
+static int mcdx_requesttocdata(struct s_drive_stuff *, struct s_diskinfo *,
+                              int);
+static int mcdx_getstatus(struct s_drive_stuff *, int);
+static int mcdx_getval(struct s_drive_stuff *, int to, int delay, char *);
+static int mcdx_talk(struct s_drive_stuff *,
+                    const unsigned char *cmd, size_t,
+                    void *buffer, size_t size, unsigned int timeout, int);
+static int mcdx_readtoc(struct s_drive_stuff *);
+static int mcdx_playtrk(struct s_drive_stuff *, const struct cdrom_ti *);
+static int mcdx_playmsf(struct s_drive_stuff *, const struct cdrom_msf *);
+static int mcdx_setattentuator(struct s_drive_stuff *,
+                              struct cdrom_volctrl *, int);
 
 /* static variables ************************************************/
 
 static int mcdx_blocksizes[MCDX_NDRIVES];
 static int mcdx_drive_map[][2] = MCDX_DRIVEMAP;
-static struct s_drive_stuffmcdx_stuffp[MCDX_NDRIVES];
-static struct s_drive_stuff* mcdx_irq_map[16] =
-               {0, 0, 0, 0, 0, 0, 0, 0,
-               0, 0, 0, 0, 0, 0, 0, 0};
+static struct s_drive_stuff *mcdx_stuffp[MCDX_NDRIVES];
+static struct s_drive_stuff *mcdx_irq_map[16] = { 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0
+};
 MODULE_PARM(mcdx, "1-4i");
 
 static struct cdrom_device_ops mcdx_dops = {
-               open:                   mcdx_open,
-               release:                mcdx_close,
-               media_changed:  mcdx_media_changed,
-               tray_move:              mcdx_tray_move,
-               lock_door:              mcdx_lockdoor,
-               audio_ioctl:    mcdx_audio_ioctl,
-               capability:             CDC_OPEN_TRAY | CDC_LOCK | CDC_MEDIA_CHANGED |
-                                               CDC_PLAY_AUDIO | CDC_DRIVE_STATUS,
+       open:mcdx_open,
+       release:mcdx_close,
+       media_changed:mcdx_media_changed,
+       tray_move:mcdx_tray_move,
+       lock_door:mcdx_lockdoor,
+       audio_ioctl:mcdx_audio_ioctl,
+       capability:CDC_OPEN_TRAY | CDC_LOCK | CDC_MEDIA_CHANGED |
+           CDC_PLAY_AUDIO | CDC_DRIVE_STATUS,
 };
 
 static struct cdrom_device_info mcdx_info = {
-       ops:                            &mcdx_dops,
-       speed:                          2,
-       capacity:                       1,
-       name:                           "mcdx",
+       ops:&mcdx_dops,
+       speed:2,
+       capacity:1,
+       name:"mcdx",
 };
 
 
 /* KERNEL INTERFACE FUNCTIONS **************************************/
 
 
-static int mcdx_audio_ioctl(struct cdrom_device_info * cdi, unsigned int cmd,
-                      void * arg)
+static int mcdx_audio_ioctl(struct cdrom_device_info *cdi,
+                           unsigned int cmd, void *arg)
 {
        struct s_drive_stuff *stuffp = mcdx_stuffp[MINOR(cdi->dev)];
 
-       if (!stuffp->present) return -ENXIO;
+       if (!stuffp->present)
+               return -ENXIO;
 
-       if (stuffp->xxx)
-       {
-               if(-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1))
-               {
+       if (stuffp->xxx) {
+               if (-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1)) {
                        stuffp->lastsector = -1;
-               }
-               else
-               {
+               } else {
                        stuffp->lastsector = (CD_FRAMESIZE / 512)
-                                       * msf2log(&stuffp->di.msf_leadout) - 1;
+                           * msf2log(&stuffp->di.msf_leadout) - 1;
                }
 
-               if (stuffp->toc)
-               {
+               if (stuffp->toc) {
                        kfree(stuffp->toc);
                        stuffp->toc = NULL;
-                       if (-1 == mcdx_readtoc(stuffp)) return -1;
+                       if (-1 == mcdx_readtoc(stuffp))
+                               return -1;
                }
 
-               stuffp->xxx=0;
+               stuffp->xxx = 0;
        }
 
        switch (cmd) {
-               case CDROMSTART: {       
-                            xtrace(IOCTL, "ioctl() START\n");
-                       /* Spin up the drive.  Don't think we can do this.
-                 * For now, ignore it.
-                 */
+       case CDROMSTART:{
+                       xtrace(IOCTL, "ioctl() START\n");
+                       /* Spin up the drive.  Don't think we can do this.
+                          * For now, ignore it.
+                        */
                        return 0;
                }
 
-               case CDROMSTOP: {
+       case CDROMSTOP:{
                        xtrace(IOCTL, "ioctl() STOP\n");
-            stuffp->audiostatus = CDROM_AUDIO_INVALID;
+                       stuffp->audiostatus = CDROM_AUDIO_INVALID;
                        if (-1 == mcdx_stop(stuffp, 1))
                                return -EIO;
                        return 0;
                }
 
-               case CDROMPLAYTRKIND: {
-                       struct cdrom_ti *ti=(struct cdrom_ti *) arg;
+       case CDROMPLAYTRKIND:{
+                       struct cdrom_ti *ti = (struct cdrom_ti *) arg;
 
                        xtrace(IOCTL, "ioctl() PLAYTRKIND\n");
                        if ((ti->cdti_trk0 < stuffp->di.n_first)
-                                       || (ti->cdti_trk0 > stuffp->di.n_last)
-                                       || (ti->cdti_trk1 < stuffp->di.n_first))
-                       return -EINVAL;
+                           || (ti->cdti_trk0 > stuffp->di.n_last)
+                           || (ti->cdti_trk1 < stuffp->di.n_first))
+                               return -EINVAL;
                        if (ti->cdti_trk1 > stuffp->di.n_last)
-                                       ti->cdti_trk1 = stuffp->di.n_last;
-            xtrace(PLAYTRK, "ioctl() track %d to %d\n", ti->cdti_trk0, ti->cdti_trk1);
-            return mcdx_playtrk(stuffp, ti);
-        }
+                               ti->cdti_trk1 = stuffp->di.n_last;
+                       xtrace(PLAYTRK, "ioctl() track %d to %d\n",
+                              ti->cdti_trk0, ti->cdti_trk1);
+                       return mcdx_playtrk(stuffp, ti);
+               }
 
-        case CDROMPLAYMSF: {
-            struct cdrom_msf *msf=(struct cdrom_msf *) arg;
+       case CDROMPLAYMSF:{
+                       struct cdrom_msf *msf = (struct cdrom_msf *) arg;
 
-            xtrace(IOCTL, "ioctl() PLAYMSF\n");
+                       xtrace(IOCTL, "ioctl() PLAYMSF\n");
 
-            if ((stuffp->audiostatus == CDROM_AUDIO_PLAY)
-                && (-1 == mcdx_hold(stuffp, 1))) return -EIO;
+                       if ((stuffp->audiostatus == CDROM_AUDIO_PLAY)
+                           && (-1 == mcdx_hold(stuffp, 1)))
+                               return -EIO;
 
-            msf->cdmsf_min0 = uint2bcd(msf->cdmsf_min0);
-            msf->cdmsf_sec0 = uint2bcd(msf->cdmsf_sec0);
-            msf->cdmsf_frame0 = uint2bcd(msf->cdmsf_frame0);
+                       msf->cdmsf_min0 = uint2bcd(msf->cdmsf_min0);
+                       msf->cdmsf_sec0 = uint2bcd(msf->cdmsf_sec0);
+                       msf->cdmsf_frame0 = uint2bcd(msf->cdmsf_frame0);
 
-            msf->cdmsf_min1 = uint2bcd(msf->cdmsf_min1);
-            msf->cdmsf_sec1 = uint2bcd(msf->cdmsf_sec1);
-            msf->cdmsf_frame1 = uint2bcd(msf->cdmsf_frame1);
+                       msf->cdmsf_min1 = uint2bcd(msf->cdmsf_min1);
+                       msf->cdmsf_sec1 = uint2bcd(msf->cdmsf_sec1);
+                       msf->cdmsf_frame1 = uint2bcd(msf->cdmsf_frame1);
 
-            stuffp->stop.dt.minute = msf->cdmsf_min1;
-            stuffp->stop.dt.second = msf->cdmsf_sec1;
-            stuffp->stop.dt.frame = msf->cdmsf_frame1;
+                       stuffp->stop.dt.minute = msf->cdmsf_min1;
+                       stuffp->stop.dt.second = msf->cdmsf_sec1;
+                       stuffp->stop.dt.frame = msf->cdmsf_frame1;
 
-            return mcdx_playmsf(stuffp, msf);
-        }
+                       return mcdx_playmsf(stuffp, msf);
+               }
 
-        case CDROMRESUME: {
-            xtrace(IOCTL, "ioctl() RESUME\n");
-            return mcdx_playtrk(stuffp, NULL);
-        }
+       case CDROMRESUME:{
+                       xtrace(IOCTL, "ioctl() RESUME\n");
+                       return mcdx_playtrk(stuffp, NULL);
+               }
 
-               case CDROMREADTOCENTRY: {
-                       struct cdrom_tocentry *entry=(struct cdrom_tocentry *) arg;
+       case CDROMREADTOCENTRY:{
+                       struct cdrom_tocentry *entry =
+                           (struct cdrom_tocentry *) arg;
                        struct s_subqcode *tp = NULL;
                        xtrace(IOCTL, "ioctl() READTOCENTRY\n");
 
-            if (-1 == mcdx_readtoc(stuffp)) return -1;
+                       if (-1 == mcdx_readtoc(stuffp))
+                               return -1;
                        if (entry->cdte_track == CDROM_LEADOUT)
-                               tp = &stuffp->toc[stuffp->di.n_last - stuffp->di.n_first + 1];
+                               tp = &stuffp->toc[stuffp->di.n_last -
+                                                 stuffp->di.n_first + 1];
                        else if (entry->cdte_track > stuffp->di.n_last
-                                       || entry->cdte_track < stuffp->di.n_first) return -EINVAL;
-                       else tp = &stuffp->toc[entry->cdte_track - stuffp->di.n_first];
+                                || entry->cdte_track < stuffp->di.n_first)
+                               return -EINVAL;
+                       else
+                               tp = &stuffp->toc[entry->cdte_track -
+                                                 stuffp->di.n_first];
 
-                       if (NULL == tp) 
+                       if (NULL == tp)
                                return -EIO;
                        entry->cdte_adr = tp->control;
                        entry->cdte_ctrl = tp->control >> 4;
-            /* Always return stuff in MSF, and let the Uniform cdrom driver
-                worry about what the user actually wants */
-                       entry->cdte_addr.msf.minute = bcd2uint(tp->dt.minute);
-                       entry->cdte_addr.msf.second = bcd2uint(tp->dt.second);
-                       entry->cdte_addr.msf.frame = bcd2uint(tp->dt.frame);
+                       /* Always return stuff in MSF, and let the Uniform cdrom driver
+                          worry about what the user actually wants */
+                       entry->cdte_addr.msf.minute =
+                           bcd2uint(tp->dt.minute);
+                       entry->cdte_addr.msf.second =
+                           bcd2uint(tp->dt.second);
+                       entry->cdte_addr.msf.frame =
+                           bcd2uint(tp->dt.frame);
                        return 0;
                }
 
-               case CDROMSUBCHNL: {
-                       struct cdrom_subchnl *sub= (struct cdrom_subchnl *)arg;
+       case CDROMSUBCHNL:{
+                       struct cdrom_subchnl *sub =
+                           (struct cdrom_subchnl *) arg;
                        struct s_subqcode q;
 
                        xtrace(IOCTL, "ioctl() SUBCHNL\n");
 
-                       if (-1 == mcdx_requestsubqcode(stuffp, &q, 2)) 
+                       if (-1 == mcdx_requestsubqcode(stuffp, &q, 2))
                                return -EIO;
 
-            xtrace(SUBCHNL, "audiostatus: %x\n", stuffp->audiostatus);
+                       xtrace(SUBCHNL, "audiostatus: %x\n",
+                              stuffp->audiostatus);
                        sub->cdsc_audiostatus = stuffp->audiostatus;
                        sub->cdsc_adr = q.control;
                        sub->cdsc_ctrl = q.control >> 4;
                        sub->cdsc_trk = bcd2uint(q.tno);
                        sub->cdsc_ind = bcd2uint(q.index);
 
-            xtrace(SUBCHNL, "trk %d, ind %d\n",
-                    sub->cdsc_trk, sub->cdsc_ind);
-            /* Always return stuff in MSF, and let the Uniform cdrom driver
-                worry about what the user actually wants */
-                       sub->cdsc_absaddr.msf.minute = bcd2uint(q.dt.minute);
-                       sub->cdsc_absaddr.msf.second = bcd2uint(q.dt.second);
+                       xtrace(SUBCHNL, "trk %d, ind %d\n",
+                              sub->cdsc_trk, sub->cdsc_ind);
+                       /* Always return stuff in MSF, and let the Uniform cdrom driver
+                          worry about what the user actually wants */
+                       sub->cdsc_absaddr.msf.minute =
+                           bcd2uint(q.dt.minute);
+                       sub->cdsc_absaddr.msf.second =
+                           bcd2uint(q.dt.second);
                        sub->cdsc_absaddr.msf.frame = bcd2uint(q.dt.frame);
-                       sub->cdsc_reladdr.msf.minute = bcd2uint(q.tt.minute);
-                       sub->cdsc_reladdr.msf.second = bcd2uint(q.tt.second);
+                       sub->cdsc_reladdr.msf.minute =
+                           bcd2uint(q.tt.minute);
+                       sub->cdsc_reladdr.msf.second =
+                           bcd2uint(q.tt.second);
                        sub->cdsc_reladdr.msf.frame = bcd2uint(q.tt.frame);
                        xtrace(SUBCHNL,
-                                       "msf: abs %02d:%02d:%02d, rel %02d:%02d:%02d\n",
-                                       sub->cdsc_absaddr.msf.minute, sub->cdsc_absaddr.msf.second,
-                                       sub->cdsc_absaddr.msf.frame, sub->cdsc_reladdr.msf.minute,
-                                       sub->cdsc_reladdr.msf.second, sub->cdsc_reladdr.msf.frame);
+                              "msf: abs %02d:%02d:%02d, rel %02d:%02d:%02d\n",
+                              sub->cdsc_absaddr.msf.minute,
+                              sub->cdsc_absaddr.msf.second,
+                              sub->cdsc_absaddr.msf.frame,
+                              sub->cdsc_reladdr.msf.minute,
+                              sub->cdsc_reladdr.msf.second,
+                              sub->cdsc_reladdr.msf.frame);
 
                        return 0;
                }
 
-               case CDROMREADTOCHDR: {
-                       struct cdrom_tochdr *toc=(struct cdrom_tochdr *) arg;
+       case CDROMREADTOCHDR:{
+                       struct cdrom_tochdr *toc =
+                           (struct cdrom_tochdr *) arg;
 
                        xtrace(IOCTL, "ioctl() READTOCHDR\n");
                        toc->cdth_trk0 = stuffp->di.n_first;
                        toc->cdth_trk1 = stuffp->di.n_last;
-                       xtrace(TOCHDR, "ioctl() track0 = %d, track1 = %d\n",
-                                       stuffp->di.n_first, stuffp->di.n_last);
+                       xtrace(TOCHDR,
+                              "ioctl() track0 = %d, track1 = %d\n",
+                              stuffp->di.n_first, stuffp->di.n_last);
                        return 0;
                }
 
-               case CDROMPAUSE: {
+       case CDROMPAUSE:{
                        xtrace(IOCTL, "ioctl() PAUSE\n");
-                       if (stuffp->audiostatus != CDROM_AUDIO_PLAY) return -EINVAL;
-                       if (-1 == mcdx_stop(stuffp, 1)) return -EIO;
-            stuffp->audiostatus = CDROM_AUDIO_PAUSED;
-                       if (-1 == mcdx_requestsubqcode(stuffp, &stuffp->start, 1))
+                       if (stuffp->audiostatus != CDROM_AUDIO_PLAY)
+                               return -EINVAL;
+                       if (-1 == mcdx_stop(stuffp, 1))
+                               return -EIO;
+                       stuffp->audiostatus = CDROM_AUDIO_PAUSED;
+                       if (-1 ==
+                           mcdx_requestsubqcode(stuffp, &stuffp->start,
+                                                1))
                                return -EIO;
                        return 0;
                }
 
-               case CDROMMULTISESSION: {
-                       struct cdrom_multisession *ms=(struct cdrom_multisession *) arg;
+       case CDROMMULTISESSION:{
+                       struct cdrom_multisession *ms =
+                           (struct cdrom_multisession *) arg;
                        xtrace(IOCTL, "ioctl() MULTISESSION\n");
                        /* Always return stuff in LBA, and let the Uniform cdrom driver
-                               worry about what the user actually wants */
+                          worry about what the user actually wants */
                        ms->addr.lba = msf2log(&stuffp->multi.msf_last);
                        ms->xa_flag = !!stuffp->multi.multi;
-                       xtrace(MS, "ioctl() (%d, 0x%08x [%02x:%02x.%02x])\n",
-                               ms->xa_flag, ms->addr.lba, stuffp->multi.msf_last.minute,
-                    stuffp->multi.msf_last.second,stuffp->multi.msf_last.frame);
+                       xtrace(MS,
+                              "ioctl() (%d, 0x%08x [%02x:%02x.%02x])\n",
+                              ms->xa_flag, ms->addr.lba,
+                              stuffp->multi.msf_last.minute,
+                              stuffp->multi.msf_last.second,
+                              stuffp->multi.msf_last.frame);
+
                        return 0;
                }
 
-               case CDROMEJECT: {
+       case CDROMEJECT:{
                        xtrace(IOCTL, "ioctl() EJECT\n");
-                       if (stuffp->users > 1) return -EBUSY;
-                       return(mcdx_tray_move(cdi, 1));
+                       if (stuffp->users > 1)
+                               return -EBUSY;
+                       return (mcdx_tray_move(cdi, 1));
                }
 
-        case CDROMCLOSETRAY: {
-            xtrace(IOCTL, "ioctl() CDROMCLOSETRAY\n");
-            return(mcdx_tray_move(cdi, 0));
-        }
+       case CDROMCLOSETRAY:{
+                       xtrace(IOCTL, "ioctl() CDROMCLOSETRAY\n");
+                       return (mcdx_tray_move(cdi, 0));
+               }
 
-        case CDROMVOLCTRL: {
-                       struct cdrom_volctrl *volctrl=(struct cdrom_volctrl *)arg;
-            xtrace(IOCTL, "ioctl() VOLCTRL\n");
+       case CDROMVOLCTRL:{
+                       struct cdrom_volctrl *volctrl =
+                           (struct cdrom_volctrl *) arg;
+                       xtrace(IOCTL, "ioctl() VOLCTRL\n");
 
-#if 0          /* not tested! */
+#if 0                          /* not tested! */
                        /* adjust for the weirdness of workman (md) */
                        /* can't test it (hs) */
                        volctrl.channel2 = volctrl.channel1;
                        volctrl.channel1 = volctrl.channel3 = 0x00;
 #endif
-            return mcdx_setattentuator(stuffp, volctrl, 2);
-        }
+                       return mcdx_setattentuator(stuffp, volctrl, 2);
+               }
 
-               default:
-                       xwarn("ioctl(): unknown request 0x%04x\n", cmd);
-               return -EINVAL;
+       default:
+               return -EINVAL;
        }
 }
 
 void do_mcdx_request(request_queue_t * q)
 {
-    int dev;
-    struct s_drive_stuff *stuffp;
+       int dev;
+       struct s_drive_stuff *stuffp;
 
-  again:
+      again:
 
        if (QUEUE_EMPTY) {
                xtrace(REQUEST, "end_request(0): CURRENT == NULL\n");
@@ -525,237 +559,257 @@ void do_mcdx_request(request_queue_t * q)
        }
 
        if (CURRENT->rq_status == RQ_INACTIVE) {
-               xtrace(REQUEST, "end_request(0): rq_status == RQ_INACTIVE\n");
+               xtrace(REQUEST,
+                      "end_request(0): rq_status == RQ_INACTIVE\n");
                return;
        }
 
-    INIT_REQUEST;
+       INIT_REQUEST;
 
-    dev = MINOR(CURRENT->rq_dev);
-    stuffp = mcdx_stuffp[dev];
+       dev = MINOR(CURRENT->rq_dev);
+       stuffp = mcdx_stuffp[dev];
 
        if ((dev < 0)
-               || (dev >= MCDX_NDRIVES)
-               || !stuffp
-               || (!stuffp->present)) {
+           || (dev >= MCDX_NDRIVES)
+           || !stuffp || (!stuffp->present)) {
                xwarn("do_request(): bad device: %s\n",
-                               kdevname(CURRENT->rq_dev));
+                     kdevname(CURRENT->rq_dev));
                xtrace(REQUEST, "end_request(0): bad device\n");
-               end_request(0); return;
-    }
+               end_request(0);
+               return;
+       }
 
        if (stuffp->audio) {
                xwarn("do_request() attempt to read from audio cd\n");
                xtrace(REQUEST, "end_request(0): read from audio\n");
-               end_request(0); return;
+               end_request(0);
+               return;
        }
 
        xtrace(REQUEST, "do_request() (%lu + %lu)\n",
-                       CURRENT->sector, CURRENT->nr_sectors);
-
-    switch (CURRENT->cmd) {
-      case WRITE:
-         xwarn("do_request(): attempt to write to cd!!\n");
-         xtrace(REQUEST, "end_request(0): write\n");
-         end_request(0); return;
-
-      case READ:
-         stuffp->status = 0;
-         while (CURRENT->nr_sectors) {
-             int i;
-
-             i = mcdx_transfer(stuffp,
-                                 CURRENT->buffer,
-                                 CURRENT->sector,
-                                 CURRENT->nr_sectors);
-
-                 if (i == -1) {
-                         end_request(0);
-                         goto again;
-                 }
-                 CURRENT->sector += i;
-                 CURRENT->nr_sectors -= i;
-                 CURRENT->buffer += (i * 512);
-         }
-         end_request(1);
-         goto again;
-
-         xtrace(REQUEST, "end_request(1)\n");
-         end_request(1);
-         break;
-
-      default:
-         panic(MCDX "do_request: unknown command.\n");
-         break;
-    }
-
-    goto again;
+              CURRENT->sector, CURRENT->nr_sectors);
+
+       switch (CURRENT->cmd) {
+       case WRITE:
+               xwarn("do_request(): attempt to write to cd!!\n");
+               xtrace(REQUEST, "end_request(0): write\n");
+               end_request(0);
+               return;
+
+       case READ:
+               stuffp->status = 0;
+               while (CURRENT->nr_sectors) {
+                       int i;
+
+                       i = mcdx_transfer(stuffp,
+                                         CURRENT->buffer,
+                                         CURRENT->sector,
+                                         CURRENT->nr_sectors);
+
+                       if (i == -1) {
+                               end_request(0);
+                               goto again;
+                       }
+                       CURRENT->sector += i;
+                       CURRENT->nr_sectors -= i;
+                       CURRENT->buffer += (i * 512);
+               }
+               end_request(1);
+               goto again;
+
+               xtrace(REQUEST, "end_request(1)\n");
+               end_request(1);
+               break;
+
+       default:
+               panic(MCDX "do_request: unknown command.\n");
+               break;
+       }
+
+       goto again;
 }
 
-static int 
-mcdx_open(struct cdrom_device_info * cdi, int purpose)
+static int mcdx_open(struct cdrom_device_info *cdi, int purpose)
 {
-    struct s_drive_stuff *stuffp;
+       struct s_drive_stuff *stuffp;
        xtrace(OPENCLOSE, "open()\n");
-    stuffp = mcdx_stuffp[MINOR(cdi->dev)];
-    if (!stuffp->present) return -ENXIO;
+       stuffp = mcdx_stuffp[MINOR(cdi->dev)];
+       if (!stuffp->present)
+               return -ENXIO;
 
        /* Make the modules looking used ... (thanx bjorn).
         * But we shouldn't forget to decrement the module counter
         * on error return */
        MOD_INC_USE_COUNT;
 
-    /* this is only done to test if the drive talks with us */
-    if (-1 == mcdx_getstatus(stuffp, 1)) {
+       /* this is only done to test if the drive talks with us */
+       if (-1 == mcdx_getstatus(stuffp, 1)) {
                MOD_DEC_USE_COUNT;
                return -EIO;
        }
 
-    if (stuffp->xxx) {
+       if (stuffp->xxx) {
+
+               xtrace(OPENCLOSE, "open() media changed\n");
+               stuffp->audiostatus = CDROM_AUDIO_INVALID;
+               stuffp->readcmd = 0;
+               xtrace(OPENCLOSE, "open() Request multisession info\n");
+               if (-1 ==
+                   mcdx_requestmultidiskinfo(stuffp, &stuffp->multi, 6))
+                       xinfo("No multidiskinfo\n");
+       } else {
+               /* multisession ? */
+               if (!stuffp->multi.multi)
+                       stuffp->multi.msf_last.second = 2;
+
+               xtrace(OPENCLOSE, "open() MS: %d, last @ %02x:%02x.%02x\n",
+                      stuffp->multi.multi,
+                      stuffp->multi.msf_last.minute,
+                      stuffp->multi.msf_last.second,
+                      stuffp->multi.msf_last.frame);
+
+               {;
+               }               /* got multisession information */
+               /* request the disks table of contents (aka diskinfo) */
+               if (-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1)) {
+
+                       stuffp->lastsector = -1;
 
-        xtrace(OPENCLOSE, "open() media changed\n");
-        stuffp->audiostatus = CDROM_AUDIO_INVALID;
-        stuffp->readcmd = 0;
-        xtrace(OPENCLOSE, "open() Request multisession info\n");
-        if (-1 == mcdx_requestmultidiskinfo( stuffp, &stuffp->multi, 6))
-               xinfo("No multidiskinfo\n");
                } else {
-            /* multisession ? */
-            if (!stuffp->multi.multi)
-                stuffp->multi.msf_last.second = 2;
-
-            xtrace(OPENCLOSE, "open() MS: %d, last @ %02x:%02x.%02x\n",
-                    stuffp->multi.multi,
-                    stuffp->multi.msf_last.minute,
-                    stuffp->multi.msf_last.second,
-                    stuffp->multi.msf_last.frame);
-
-        { ; } /* got multisession information */
-        /* request the disks table of contents (aka diskinfo) */
-        if (-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1)) {
-
-            stuffp->lastsector = -1;
-
-        } else {
-
-            stuffp->lastsector = (CD_FRAMESIZE / 512)
-                    * msf2log(&stuffp->di.msf_leadout) - 1;
-
-            xtrace(OPENCLOSE, "open() start %d (%02x:%02x.%02x) %d\n",
-                    stuffp->di.n_first,
-                    stuffp->di.msf_first.minute,
-                    stuffp->di.msf_first.second,
-                    stuffp->di.msf_first.frame,
-                    msf2log(&stuffp->di.msf_first));
-            xtrace(OPENCLOSE, "open() last %d (%02x:%02x.%02x) %d\n",
-                    stuffp->di.n_last,
-                    stuffp->di.msf_leadout.minute,
-                    stuffp->di.msf_leadout.second,
-                    stuffp->di.msf_leadout.frame,
-                    msf2log(&stuffp->di.msf_leadout));
-        }
-      
-        if (stuffp->toc) {
-            xtrace(MALLOC, "open() free old toc @ %p\n", stuffp->toc);
-            kfree(stuffp->toc);
-
-            stuffp->toc = NULL;
-        }
-
-        xtrace(OPENCLOSE, "open() init irq generation\n");
-        if (-1 == mcdx_config(stuffp, 1)) {
-            MOD_DEC_USE_COUNT;
-            return -EIO;
-        }
 
+                       stuffp->lastsector = (CD_FRAMESIZE / 512)
+                           * msf2log(&stuffp->di.msf_leadout) - 1;
+
+                       xtrace(OPENCLOSE,
+                              "open() start %d (%02x:%02x.%02x) %d\n",
+                              stuffp->di.n_first,
+                              stuffp->di.msf_first.minute,
+                              stuffp->di.msf_first.second,
+                              stuffp->di.msf_first.frame,
+                              msf2log(&stuffp->di.msf_first));
+                       xtrace(OPENCLOSE,
+                              "open() last %d (%02x:%02x.%02x) %d\n",
+                              stuffp->di.n_last,
+                              stuffp->di.msf_leadout.minute,
+                              stuffp->di.msf_leadout.second,
+                              stuffp->di.msf_leadout.frame,
+                              msf2log(&stuffp->di.msf_leadout));
+               }
+
+               if (stuffp->toc) {
+                       xtrace(MALLOC, "open() free old toc @ %p\n",
+                              stuffp->toc);
+                       kfree(stuffp->toc);
+
+                       stuffp->toc = NULL;
+               }
+
+               xtrace(OPENCLOSE, "open() init irq generation\n");
+               if (-1 == mcdx_config(stuffp, 1)) {
+                       MOD_DEC_USE_COUNT;
+                       return -EIO;
+               }
 #if FALLBACK
-        /* Set the read speed */
-        xwarn("AAA %x AAA\n", stuffp->readcmd);
-        if (stuffp->readerrs) stuffp->readcmd = READ1X;
-        else stuffp->readcmd =
-                stuffp->present | SINGLE ? READ1X : READ2X;
-        xwarn("XXX %x XXX\n", stuffp->readcmd);
+               /* Set the read speed */
+               xwarn("AAA %x AAA\n", stuffp->readcmd);
+               if (stuffp->readerrs)
+                       stuffp->readcmd = READ1X;
+               else
+                       stuffp->readcmd =
+                           stuffp->present | SINGLE ? READ1X : READ2X;
+               xwarn("XXX %x XXX\n", stuffp->readcmd);
 #else
-        stuffp->readcmd = stuffp->present | SINGLE ? READ1X : READ2X;
+               stuffp->readcmd =
+                   stuffp->present | SINGLE ? READ1X : READ2X;
 #endif
 
-        /* try to get the first sector, iff any ... */
-        if (stuffp->lastsector >= 0) {
-            char buf[512];
-            int ans;
-            int tries;
-
-            stuffp->xa = 0;
-            stuffp->audio = 0;
-
-            for (tries = 6; tries; tries--) {
-
-                stuffp->introk = 1;
-
-                xtrace(OPENCLOSE, "open() try as %s\n",
-                    stuffp->xa ? "XA" : "normal");
-                /* set data mode */
-                if (-1 == (ans = mcdx_setdatamode(stuffp,
-                        stuffp->xa ? MODE2 : MODE1, 1))) {
-                    /* MOD_DEC_USE_COUNT, return -EIO; */
-                    stuffp->xa = 0;
-                    break;
-                }
-
-                if ((stuffp->audio = e_audio(ans))) break;
-
-                while (0 == (ans = mcdx_transfer(stuffp, buf, 0, 1)))
-                    ;
-
-                if (ans == 1) break;
-                stuffp->xa = !stuffp->xa;
-            }
-        }
-        /* xa disks will be read in raw mode, others not */
-        if (-1 == mcdx_setdrivemode(stuffp,
-                stuffp->xa ? RAW : COOKED, 1)) {
-            MOD_DEC_USE_COUNT;
-            return -EIO;
-        }
-        if (stuffp->audio) {
-            xinfo("open() audio disk found\n");
-        } else if (stuffp->lastsector >= 0) {
-            xinfo("open() %s%s disk found\n",
-                    stuffp->xa ? "XA / " : "",
-                    stuffp->multi.multi ? "Multi Session" : "Single Session");
-        }
-    }
+               /* try to get the first sector, iff any ... */
+               if (stuffp->lastsector >= 0) {
+                       char buf[512];
+                       int ans;
+                       int tries;
+
+                       stuffp->xa = 0;
+                       stuffp->audio = 0;
+
+                       for (tries = 6; tries; tries--) {
+
+                               stuffp->introk = 1;
+
+                               xtrace(OPENCLOSE, "open() try as %s\n",
+                                      stuffp->xa ? "XA" : "normal");
+                               /* set data mode */
+                               if (-1 == (ans = mcdx_setdatamode(stuffp,
+                                                                 stuffp->
+                                                                 xa ?
+                                                                 MODE2 :
+                                                                 MODE1,
+                                                                 1))) {
+                                       /* MOD_DEC_USE_COUNT, return -EIO; */
+                                       stuffp->xa = 0;
+                                       break;
+                               }
+
+                               if ((stuffp->audio = e_audio(ans)))
+                                       break;
+
+                               while (0 ==
+                                      (ans =
+                                       mcdx_transfer(stuffp, buf, 0, 1)));
+
+                               if (ans == 1)
+                                       break;
+                               stuffp->xa = !stuffp->xa;
+                       }
+               }
+               /* xa disks will be read in raw mode, others not */
+               if (-1 == mcdx_setdrivemode(stuffp,
+                                           stuffp->xa ? RAW : COOKED,
+                                           1)) {
+                       MOD_DEC_USE_COUNT;
+                       return -EIO;
+               }
+               if (stuffp->audio) {
+                       xinfo("open() audio disk found\n");
+               } else if (stuffp->lastsector >= 0) {
+                       xinfo("open() %s%s disk found\n",
+                             stuffp->xa ? "XA / " : "",
+                             stuffp->multi.
+                             multi ? "Multi Session" : "Single Session");
+               }
+       }
        stuffp->xxx = 0;
-    stuffp->users++;
-    return 0;
+       stuffp->users++;
+       return 0;
 }
 
-static void mcdx_close(struct cdrom_device_info * cdi)
+static void mcdx_close(struct cdrom_device_info *cdi)
 {
-    struct s_drive_stuff *stuffp;
+       struct s_drive_stuff *stuffp;
 
-    xtrace(OPENCLOSE, "close()\n");
+       xtrace(OPENCLOSE, "close()\n");
 
-    stuffp = mcdx_stuffp[MINOR(cdi->dev)];
+       stuffp = mcdx_stuffp[MINOR(cdi->dev)];
 
-    --stuffp->users;
+       --stuffp->users;
 
-    MOD_DEC_USE_COUNT;
+       MOD_DEC_USE_COUNT;
 }
 
-static int mcdx_media_changed(struct cdrom_device_info * cdi, int disc_nr) 
+static int mcdx_media_changed(struct cdrom_device_info *cdi, int disc_nr)
 /*     Return: 1 if media changed since last call to this function
                        0 otherwise */
 {
-    struct s_drive_stuff *stuffp;
+       struct s_drive_stuff *stuffp;
 
-    xinfo("mcdx_media_changed called for device %s\n",
-         kdevname(cdi->dev));
+       xinfo("mcdx_media_changed called for device %s\n",
+             kdevname(cdi->dev));
 
        stuffp = mcdx_stuffp[MINOR(cdi->dev)];
        mcdx_getstatus(stuffp, 1);
 
-       if (stuffp->yyy == 0) return 0;
+       if (stuffp->yyy == 0)
+               return 0;
 
        stuffp->yyy = 0;
        return 1;
@@ -765,10 +819,12 @@ static int mcdx_media_changed(struct cdrom_device_info * cdi, int disc_nr)
 static int __init mcdx_setup(char *str)
 {
        int pi[4];
-       (void)get_options(str, ARRAY_SIZE(pi), pi);
-       
-       if (pi[0] > 0) mcdx_drive_map[0][0] = pi[1];
-       if (pi[0] > 1) mcdx_drive_map[0][1] = pi[2];
+       (void) get_options(str, ARRAY_SIZE(pi), pi);
+
+       if (pi[0] > 0)
+               mcdx_drive_map[0][0] = pi[1];
+       if (pi[0] > 1)
+               mcdx_drive_map[0][1] = pi[2];
        return 1;
 }
 
@@ -787,7 +843,8 @@ static void mcdx_delay(struct s_drive_stuff *stuff, long jifs)
  *     May be we could use a simple count loop w/ jumps to itself, but
  *     I wanna make this independent of cpu speed. [1 jiffy is 1/HZ] sec */
 {
-       if (jifs < 0) return;
+       if (jifs < 0)
+               return;
 
        xtrace(SLEEP, "*** delay: sleepq\n");
        interruptible_sleep_on_timeout(&stuff->sleepq, jifs);
@@ -797,24 +854,22 @@ static void mcdx_delay(struct s_drive_stuff *stuff, long jifs)
        }
 }
 
-static void
-mcdx_intr(int irq, void *dev_id, struct pt_regs* regs)
+static void mcdx_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
-    struct s_drive_stuff *stuffp;
+       struct s_drive_stuff *stuffp;
        unsigned char b;
 
-    stuffp = mcdx_irq_map[irq];
+       stuffp = mcdx_irq_map[irq];
 
-    if (stuffp == NULL ) {
+       if (stuffp == NULL) {
                xwarn("mcdx: no device for intr %d\n", irq);
                return;
-    }
-
+       }
 #ifdef AK2
-       if ( !stuffp->busy && stuffp->pending )
+       if (!stuffp->busy && stuffp->pending)
                stuffp->int_err = 1;
 
-#endif /* AK2 */
+#endif                         /* AK2 */
        /* get the interrupt status */
        b = inb((unsigned int) stuffp->rreg_status);
        stuffp->introk = ~b & MCDX_RBIT_DTEN;
@@ -829,26 +884,23 @@ mcdx_intr(int irq, void *dev_id, struct pt_regs* regs)
        if (!stuffp->introk) {
                xtrace(IRQ, "intr() irq %d hw status 0x%02x\n", irq, b);
                if (~b & MCDX_RBIT_STEN) {
-                       xinfo(  "intr() irq %d    status 0x%02x\n",
-                                       irq, inb((unsigned int) stuffp->rreg_data));
+                       xinfo("intr() irq %d    status 0x%02x\n",
+                             irq, inb((unsigned int) stuffp->rreg_data));
                } else {
-                       xinfo(  "intr() irq %d ambiguous hw status\n", irq);
+                       xinfo("intr() irq %d ambiguous hw status\n", irq);
                }
        } else {
                xtrace(IRQ, "irq() irq %d ok, status %02x\n", irq, b);
-    }
+       }
 
-    stuffp->busy = 0;
-    wake_up_interruptible(&stuffp->busyq);
+       stuffp->busy = 0;
+       wake_up_interruptible(&stuffp->busyq);
 }
 
 
-static int
-mcdx_talk (
-               struct s_drive_stuff *stuffp,
-               const unsigned char *cmd, size_t cmdlen,
-               void *buffer, size_t size,
-               unsigned int timeout, int tries)
+static int mcdx_talk(struct s_drive_stuff *stuffp,
+         const unsigned char *cmd, size_t cmdlen,
+         void *buffer, size_t size, unsigned int timeout, int tries)
 /* Send a command to the drive, wait for the result.
  * returns -1 on timeout, drive status otherwise
  * If buffer is not zero, the result (length size) is stored there.
@@ -857,99 +909,108 @@ mcdx_talk (
  */
 {
        int st;
-    char c;
-    int discard;
+       char c;
+       int discard;
 
        /* Somebody wants the data read? */
-    if ((discard = (buffer == NULL))) buffer = &c;
+       if ((discard = (buffer == NULL)))
+               buffer = &c;
 
-    while (stuffp->lock) {
+       while (stuffp->lock) {
                xtrace(SLEEP, "*** talk: lockq\n");
                interruptible_sleep_on(&stuffp->lockq);
                xtrace(SLEEP, "talk: awoken\n");
        }
 
-    stuffp->lock = 1;
+       stuffp->lock = 1;
 
        /* An operation other then reading data destroys the
-     * data already requested and remembered in stuffp->request, ... */
-    stuffp->valid = 0;
+          * data already requested and remembered in stuffp->request, ... */
+       stuffp->valid = 0;
 
 #if MCDX_DEBUG & TALK
        {
                unsigned char i;
-               xtrace(TALK, "talk() %d / %d tries, res.size %d, command 0x%02x",
-                               tries, timeout, size, (unsigned char) cmd[0]);
-               for (i = 1; i < cmdlen; i++) xtrace(TALK, " 0x%02x", cmd[i]);
+               xtrace(TALK,
+                      "talk() %d / %d tries, res.size %d, command 0x%02x",
+                      tries, timeout, size, (unsigned char) cmd[0]);
+               for (i = 1; i < cmdlen; i++)
+                       xtrace(TALK, " 0x%02x", cmd[i]);
                xtrace(TALK, "\n");
        }
 #endif
 
-    /*  give up if all tries are done (bad) or if the status
-     *  st != -1 (good) */
+       /*  give up if all tries are done (bad) or if the status
+        *  st != -1 (good) */
        for (st = -1; st == -1 && tries; tries--) {
 
-               char *bp = (char*) buffer;
+               char *bp = (char *) buffer;
                size_t sz = size;
 
                outsb((unsigned int) stuffp->wreg_data, cmd, cmdlen);
-        xtrace(TALK, "talk() command sent\n");
-
-        /* get the status byte */
-        if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
-            xinfo("talk() %02x timed out (status), %d tr%s left\n",
-                    cmd[0], tries - 1, tries == 2 ? "y" : "ies");
-                continue;
-        }
-        st = *bp;
-        sz--;
-        if (!discard) bp++;
-
-        xtrace(TALK, "talk() got status 0x%02x\n", st);
-
-        /* command error? */
-        if (e_cmderr(st)) {
-            xwarn("command error cmd = %02x %s \n",
-                    cmd[0], cmdlen > 1 ? "..." : "");
-            st = -1;
-            continue;
+               xtrace(TALK, "talk() command sent\n");
+
+               /* get the status byte */
+               if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
+                       xinfo("talk() %02x timed out (status), %d tr%s left\n",
+                            cmd[0], tries - 1, tries == 2 ? "y" : "ies");
+                       continue;
+               }
+               st = *bp;
+               sz--;
+               if (!discard)
+                       bp++;
+
+               xtrace(TALK, "talk() got status 0x%02x\n", st);
+
+               /* command error? */
+               if (e_cmderr(st)) {
+                       xwarn("command error cmd = %02x %s \n",
+                             cmd[0], cmdlen > 1 ? "..." : "");
+                       st = -1;
+                       continue;
                }
 
-        /* audio status? */
-        if (stuffp->audiostatus == CDROM_AUDIO_INVALID)
-            stuffp->audiostatus =
-                    e_audiobusy(st) ? CDROM_AUDIO_PLAY : CDROM_AUDIO_NO_STATUS;
-        else if (stuffp->audiostatus == CDROM_AUDIO_PLAY
-                && e_audiobusy(st) == 0)
-            stuffp->audiostatus = CDROM_AUDIO_COMPLETED;
-
-        /* media change? */
-        if (e_changed(st)) {
-            xinfo("talk() media changed\n");
-            stuffp->xxx = stuffp->yyy = 1;
-        }
-
-        /* now actually get the data */
-        while (sz--) {
-            if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
-                xinfo("talk() %02x timed out (data), %d tr%s left\n",
-                        cmd[0], tries - 1, tries == 2 ? "y" : "ies");
-                st = -1; break;
-            }
-            if (!discard) bp++;
-            xtrace(TALK, "talk() got 0x%02x\n", *(bp - 1));
-        }
-    }
+               /* audio status? */
+               if (stuffp->audiostatus == CDROM_AUDIO_INVALID)
+                       stuffp->audiostatus =
+                           e_audiobusy(st) ? CDROM_AUDIO_PLAY :
+                           CDROM_AUDIO_NO_STATUS;
+               else if (stuffp->audiostatus == CDROM_AUDIO_PLAY
+                        && e_audiobusy(st) == 0)
+                       stuffp->audiostatus = CDROM_AUDIO_COMPLETED;
+
+               /* media change? */
+               if (e_changed(st)) {
+                       xinfo("talk() media changed\n");
+                       stuffp->xxx = stuffp->yyy = 1;
+               }
+
+               /* now actually get the data */
+               while (sz--) {
+                       if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
+                               xinfo("talk() %02x timed out (data), %d tr%s left\n",
+                                    cmd[0], tries - 1,
+                                    tries == 2 ? "y" : "ies");
+                               st = -1;
+                               break;
+                       }
+                       if (!discard)
+                               bp++;
+                       xtrace(TALK, "talk() got 0x%02x\n", *(bp - 1));
+               }
+       }
 
 #if !MCDX_QUIET
-    if (!tries && st == -1) xinfo("talk() giving up\n");
+       if (!tries && st == -1)
+               xinfo("talk() giving up\n");
 #endif
 
-    stuffp->lock = 0;
-    wake_up_interruptible(&stuffp->lockq);
+       stuffp->lock = 0;
+       wake_up_interruptible(&stuffp->lockq);
 
        xtrace(TALK, "talk() done with 0x%02x\n", st);
-    return st;
+       return st;
 }
 
 /* MODULE STUFF ***********************************************************/
@@ -962,51 +1023,56 @@ int __mcdx_init(void)
        int drives = 0;
 
        mcdx_init();
-       for (i = 0; i < MCDX_NDRIVES; i++)  {
+       for (i = 0; i < MCDX_NDRIVES; i++) {
                if (mcdx_stuffp[i]) {
-               xtrace(INIT, "init_module() drive %d stuff @ %p\n",
-                               i, mcdx_stuffp[i]);
+                       xtrace(INIT, "init_module() drive %d stuff @ %p\n",
+                              i, mcdx_stuffp[i]);
                        drives++;
                }
        }
 
-    if (!drives)
+       if (!drives)
                return -EIO;
 
-    return 0;
+       return 0;
 }
 
 void __exit mcdx_exit(void)
 {
-    int i;
+       int i;
 
        xinfo("cleanup_module called\n");
 
-    for (i = 0; i < MCDX_NDRIVES; i++) {
+       for (i = 0; i < MCDX_NDRIVES; i++) {
                struct s_drive_stuff *stuffp;
-               if (unregister_cdrom(&mcdx_info)) {
+               if (unregister_cdrom(&mcdx_info)) {
                        printk(KERN_WARNING "Can't unregister cdrom mcdx\n");
                        return;
                }
                stuffp = mcdx_stuffp[i];
-               if (!stuffp) continue;
-               release_region((unsigned long) stuffp->wreg_data, MCDX_IO_SIZE);
+               if (!stuffp)
+                       continue;
+               release_region((unsigned long) stuffp->wreg_data,
+                              MCDX_IO_SIZE);
                free_irq(stuffp->irq, NULL);
                if (stuffp->toc) {
-                       xtrace(MALLOC, "cleanup_module() free toc @ %p\n", stuffp->toc);
+                       xtrace(MALLOC, "cleanup_module() free toc @ %p\n",
+                              stuffp->toc);
                        kfree(stuffp->toc);
                }
-               xtrace(MALLOC, "cleanup_module() free stuffp @ %p\n", stuffp);
+               xtrace(MALLOC, "cleanup_module() free stuffp @ %p\n",
+                      stuffp);
                mcdx_stuffp[i] = NULL;
                kfree(stuffp);
-    }
+       }
 
-    if (devfs_unregister_blkdev(MAJOR_NR, "mcdx") != 0) {
-        xwarn("cleanup() unregister_blkdev() failed\n");
-    }
+       if (devfs_unregister_blkdev(MAJOR_NR, "mcdx") != 0) {
+               xwarn("cleanup() unregister_blkdev() failed\n");
+       }
        blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
 #if !MCDX_QUIET
-       else xinfo("cleanup() succeeded\n");
+       else
+       xinfo("cleanup() succeeded\n");
 #endif
 }
 
@@ -1021,7 +1087,7 @@ module_exit(mcdx_exit);
 int __init mcdx_init_drive(int drive)
 {
        struct s_version version;
-       struct s_drive_stuffstuffp;
+       struct s_drive_stuff *stuffp;
        int size = sizeof(*stuffp);
        char msg[80];
 
@@ -1047,11 +1113,12 @@ int __init mcdx_init_drive(int drive)
 
        /* setup our irq and i/o addresses */
        stuffp->irq = irq(mcdx_drive_map[drive]);
-       stuffp->wreg_data = stuffp->rreg_data = port(mcdx_drive_map[drive]);
+       stuffp->wreg_data = stuffp->rreg_data =
+           port(mcdx_drive_map[drive]);
        stuffp->wreg_reset = stuffp->rreg_status = stuffp->wreg_data + 1;
        stuffp->wreg_hcon = stuffp->wreg_reset + 1;
        stuffp->wreg_chn = stuffp->wreg_hcon + 1;
-       
+
        init_waitqueue_head(&stuffp->busyq);
        init_waitqueue_head(&stuffp->lockq);
        init_waitqueue_head(&stuffp->sleepq);
@@ -1066,7 +1133,7 @@ int __init mcdx_init_drive(int drive)
                xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp);
                kfree(stuffp);
                xtrace(INIT, "init() continue at next drive\n");
-               return 0; /* next drive */
+               return 0;       /* next drive */
        }
 
        xtrace(INIT, "init() i/o port is available at 0x%3p\n",
@@ -1078,8 +1145,7 @@ int __init mcdx_init_drive(int drive)
        if (-1 == mcdx_requestversion(stuffp, &version, 4)) {
                /* failed, next drive */
                xwarn("%s=0x%3p,%d: Init failed. Can't get version.\n",
-                     MCDX,
-                     stuffp->wreg_data, stuffp->irq);
+                     MCDX, stuffp->wreg_data, stuffp->irq);
                xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp);
                kfree(stuffp);
                xtrace(INIT, "init() continue at next drive\n");
@@ -1088,35 +1154,35 @@ int __init mcdx_init_drive(int drive)
 
        switch (version.code) {
        case 'D':
-                stuffp->readcmd = READ2X;
-                stuffp->present = DOUBLE | DOOR | MULTI;
-                break;
+               stuffp->readcmd = READ2X;
+               stuffp->present = DOUBLE | DOOR | MULTI;
+               break;
        case 'F':
-                stuffp->readcmd = READ1X;
-                stuffp->present = SINGLE | DOOR | MULTI;
-                break;
+               stuffp->readcmd = READ1X;
+               stuffp->present = SINGLE | DOOR | MULTI;
+               break;
        case 'M':
-                stuffp->readcmd = READ1X;
-                stuffp->present = SINGLE;
-                break;
+               stuffp->readcmd = READ1X;
+               stuffp->present = SINGLE;
+               break;
        default:
-                stuffp->present = 0; break;
+               stuffp->present = 0;
+               break;
        }
 
-        stuffp->playcmd = READ1X;
+       stuffp->playcmd = READ1X;
 
        if (!stuffp->present) {
                xwarn("%s=0x%3p,%d: Init failed. No Mitsumi CD-ROM?.\n",
                      MCDX, stuffp->wreg_data, stuffp->irq);
                kfree(stuffp);
-               return 0; /* next drive */
+               return 0;       /* next drive */
        }
 
        xtrace(INIT, "init() register blkdev\n");
        if (devfs_register_blkdev(MAJOR_NR, "mcdx", &cdrom_fops) != 0) {
                xwarn("%s=0x%3p,%d: Init failed. Can't get major %d.\n",
-                     MCDX,
-                     stuffp->wreg_data, stuffp->irq, MAJOR_NR);
+                     MCDX, stuffp->wreg_data, stuffp->irq, MAJOR_NR);
                kfree(stuffp);
                return 1;
        }
@@ -1129,21 +1195,19 @@ int __init mcdx_init_drive(int drive)
        mcdx_irq_map[stuffp->irq] = stuffp;
        if (request_irq(stuffp->irq, mcdx_intr, SA_INTERRUPT, "mcdx", NULL)) {
                xwarn("%s=0x%3p,%d: Init failed. Can't get irq (%d).\n",
-                     MCDX,
-                     stuffp->wreg_data, stuffp->irq, stuffp->irq);
+                     MCDX, stuffp->wreg_data, stuffp->irq, stuffp->irq);
                stuffp->irq = 0;
                blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
                kfree(stuffp);
                return 0;
        }
        request_region((unsigned int) stuffp->wreg_data,
-                      MCDX_IO_SIZE,
-                      "mcdx");
+                      MCDX_IO_SIZE, "mcdx");
 
        xtrace(INIT, "init() get garbage\n");
        {
                int i;
-               mcdx_delay(stuffp, HZ/2);
+               mcdx_delay(stuffp, HZ / 2);
                for (i = 100; i; i--)
                        (void) inb((unsigned int) stuffp->rreg_status);
        }
@@ -1160,24 +1224,23 @@ int __init mcdx_init_drive(int drive)
        stuffp->minor = drive;
 
        sprintf(msg, " mcdx: Mitsumi CD-ROM installed at 0x%3p, irq %d."
-               " (Firmware version %c %x)\n", 
-               stuffp->wreg_data, stuffp->irq, version.code,
-               version.ver);
+               " (Firmware version %c %x)\n",
+               stuffp->wreg_data, stuffp->irq, version.code, version.ver);
        mcdx_stuffp[drive] = stuffp;
        xtrace(INIT, "init() mcdx_stuffp[%d] = %p\n", drive, stuffp);
-       mcdx_info.dev = MKDEV(MAJOR_NR,0);
-        if (register_cdrom(&mcdx_info) != 0) {
+       mcdx_info.dev = MKDEV(MAJOR_NR, 0);
+       if (register_cdrom(&mcdx_info) != 0) {
                printk("Cannot register Mitsumi CD-ROM!\n");
                release_region((unsigned long) stuffp->wreg_data,
                               MCDX_IO_SIZE);
                free_irq(stuffp->irq, NULL);
                kfree(stuffp);
                if (devfs_unregister_blkdev(MAJOR_NR, "mcdx") != 0)
-                       xwarn("cleanup() unregister_blkdev() failed\n");
+                       xwarn("cleanup() unregister_blkdev() failed\n");
                blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
                return 2;
-        }
-        printk(msg);
+       }
+       printk(msg);
        return 0;
 }
 
@@ -1198,7 +1261,7 @@ int __init mcdx_init(void)
 
        /* do the initialisation */
        for (drive = 0; drive < MCDX_NDRIVES; drive++) {
-               switch(mcdx_init_drive(drive)) {
+               switch (mcdx_init_drive(drive)) {
                case 2:
                        return -EIO;
                case 1:
@@ -1208,9 +1271,8 @@ int __init mcdx_init(void)
        return 0;
 }
 
-static int
-mcdx_transfer(struct s_drive_stuff *stuffp,
-               char *p, int sector, int nr_sectors)
+static int mcdx_transfer(struct s_drive_stuff *stuffp,
+             char *p, int sector, int nr_sectors)
 /*     This seems to do the actually transfer.  But it does more.  It
        keeps track of errors occurred and will (if possible) fall back
        to single speed on error.
@@ -1222,8 +1284,10 @@ mcdx_transfer(struct s_drive_stuff *stuffp,
        ans = mcdx_xfer(stuffp, p, sector, nr_sectors);
        return ans;
 #if FALLBACK
-       if (-1 == ans) stuffp->readerrs++;
-       else return ans;
+       if (-1 == ans)
+               stuffp->readerrs++;
+       else
+               return ans;
 
        if (stuffp->readerrs && stuffp->readcmd == READ1X) {
                xwarn("XXX Already reading 1x -- no chance\n");
@@ -1240,99 +1304,109 @@ mcdx_transfer(struct s_drive_stuff *stuffp,
 
 
 static int mcdx_xfer(struct s_drive_stuff *stuffp,
-               char *p, int sector, int nr_sectors)
+                    char *p, int sector, int nr_sectors)
 /*     This does actually the transfer from the drive.
        Return: -1 on timeout or other error
                        else status byte (as in stuff->st) */
 {
-    int border;
-    int done = 0;
+       int border;
+       int done = 0;
        long timeout;
 
        if (stuffp->audio) {
-                       xwarn("Attempt to read from audio CD.\n");
-                       return -1;
+               xwarn("Attempt to read from audio CD.\n");
+               return -1;
        }
 
        if (!stuffp->readcmd) {
-                       xinfo("Can't transfer from missing disk.\n");
-                       return -1;
+               xinfo("Can't transfer from missing disk.\n");
+               return -1;
        }
 
-    while (stuffp->lock) {
+       while (stuffp->lock) {
                interruptible_sleep_on(&stuffp->lockq);
        }
 
-    if (stuffp->valid
-                       && (sector >= stuffp->pending)
-                       && (sector < stuffp->low_border)) {
+       if (stuffp->valid && (sector >= stuffp->pending)
+           && (sector < stuffp->low_border)) {
 
                /* All (or at least a part of the sectors requested) seems
-         * to be already requested, so we don't need to bother the
-                * drive with new requests ...
-                * Wait for the drive become idle, but first
-                * check for possible occurred errors --- the drive
-                * seems to report them asynchronously */
+                  * to be already requested, so we don't need to bother the
+                  * drive with new requests ...
+                  * Wait for the drive become idle, but first
+                  * check for possible occurred errors --- the drive
+                  * seems to report them asynchronously */
 
 
-       border = stuffp->high_border < (border = sector + nr_sectors)
-                       ? stuffp->high_border : border;
+               border = stuffp->high_border < (border =
+                                               sector + nr_sectors)
+                   ? stuffp->high_border : border;
 
-       stuffp->lock = current->pid;
+               stuffp->lock = current->pid;
 
-       do {
+               do {
 
-           while (stuffp->busy) {
+                       while (stuffp->busy) {
 
-                       timeout = interruptible_sleep_on_timeout(&stuffp->busyq, 5*HZ);
+                               timeout =
+                                   interruptible_sleep_on_timeout
+                                   (&stuffp->busyq, 5 * HZ);
 
-                       if (!stuffp->introk) { xtrace(XFER, "error via interrupt\n"); }
-                       else if (!timeout) { xtrace(XFER, "timeout\n"); }
-                       else if (signal_pending(current)) {
-                               xtrace(XFER, "signal\n");
-                       } else continue;
+                               if (!stuffp->introk) {
+                                       xtrace(XFER,
+                                              "error via interrupt\n");
+                               } else if (!timeout) {
+                                       xtrace(XFER, "timeout\n");
+                               } else if (signal_pending(current)) {
+                                       xtrace(XFER, "signal\n");
+                               } else
+                                       continue;
 
-                       stuffp->lock = 0;
-                       stuffp->busy = 0;
-                       stuffp->valid = 0;
-
-                       wake_up_interruptible(&stuffp->lockq);
-                       xtrace(XFER, "transfer() done (-1)\n");
-                       return -1;
-           }
+                               stuffp->lock = 0;
+                               stuffp->busy = 0;
+                               stuffp->valid = 0;
 
-               /* check if we need to set the busy flag (as we
-                * expect an interrupt */
-               stuffp->busy = (3 == (stuffp->pending & 3));
+                               wake_up_interruptible(&stuffp->lockq);
+                               xtrace(XFER, "transfer() done (-1)\n");
+                               return -1;
+                       }
 
-               /* Test if it's the first sector of a block,
-                * there we have to skip some bytes as we read raw data */
-               if (stuffp->xa && (0 == (stuffp->pending & 3))) {
-                       const int HEAD = CD_FRAMESIZE_RAW - CD_XA_TAIL - CD_FRAMESIZE;
-                       insb((unsigned int) stuffp->rreg_data, p, HEAD);
-               }
+                       /* check if we need to set the busy flag (as we
+                        * expect an interrupt */
+                       stuffp->busy = (3 == (stuffp->pending & 3));
+
+                       /* Test if it's the first sector of a block,
+                        * there we have to skip some bytes as we read raw data */
+                       if (stuffp->xa && (0 == (stuffp->pending & 3))) {
+                               const int HEAD =
+                                   CD_FRAMESIZE_RAW - CD_XA_TAIL -
+                                   CD_FRAMESIZE;
+                               insb((unsigned int) stuffp->rreg_data, p,
+                                    HEAD);
+                       }
 
-               /* now actually read the data */
-           insb((unsigned int) stuffp->rreg_data, p, 512);
+                       /* now actually read the data */
+                       insb((unsigned int) stuffp->rreg_data, p, 512);
 
-               /* test if it's the last sector of a block,
-                * if so, we have to handle XA special */
-               if ((3 == (stuffp->pending & 3)) && stuffp->xa) {
-                       char dummy[CD_XA_TAIL];
-                       insb((unsigned int) stuffp->rreg_data, &dummy[0], CD_XA_TAIL);
-               }
+                       /* test if it's the last sector of a block,
+                        * if so, we have to handle XA special */
+                       if ((3 == (stuffp->pending & 3)) && stuffp->xa) {
+                               char dummy[CD_XA_TAIL];
+                               insb((unsigned int) stuffp->rreg_data,
+                                    &dummy[0], CD_XA_TAIL);
+                       }
 
-           if (stuffp->pending == sector) {
-                       p += 512;
-                       done++;
-                       sector++;
-           }
-       } while (++(stuffp->pending) < border);
+                       if (stuffp->pending == sector) {
+                               p += 512;
+                               done++;
+                               sector++;
+                       }
+               } while (++(stuffp->pending) < border);
 
-       stuffp->lock = 0;
-       wake_up_interruptible(&stuffp->lockq);
+               stuffp->lock = 0;
+               wake_up_interruptible(&stuffp->lockq);
 
-    } else {
+       } else {
 
                /* The requested sector(s) is/are out of the
                 * already requested range, so we have to bother the drive
@@ -1352,8 +1426,9 @@ static int mcdx_xfer(struct s_drive_stuff *stuffp,
 
                /* do some sanity checks */
                if (stuffp->pending > stuffp->lastsector) {
-                       xwarn("transfer() sector %d from nirvana requested.\n",
-                               stuffp->pending);
+                       xwarn
+                           ("transfer() sector %d from nirvana requested.\n",
+                            stuffp->pending);
                        stuffp->status = MCDX_ST_EOM;
                        stuffp->valid = 0;
                        xtrace(XFER, "transfer() done (-1)\n");
@@ -1361,17 +1436,17 @@ static int mcdx_xfer(struct s_drive_stuff *stuffp,
                }
 
                if ((stuffp->low_border = stuffp->pending + DIRECT_SIZE)
-                               > stuffp->lastsector + 1) {
+                   > stuffp->lastsector + 1) {
                        xtrace(XFER, "cut low_border\n");
                        stuffp->low_border = stuffp->lastsector + 1;
                }
                if ((stuffp->high_border = stuffp->pending + REQUEST_SIZE)
-                               > stuffp->lastsector + 1) {
-                       xtrace(XFER,  "cut high_border\n");
+                   > stuffp->lastsector + 1) {
+                       xtrace(XFER, "cut high_border\n");
                        stuffp->high_border = stuffp->lastsector + 1;
                }
 
-               {       /* Convert the sector to be requested to MSF format */
+               {               /* Convert the sector to be requested to MSF format */
                        struct cdrom_msf0 pending;
                        log2msf(stuffp->pending / 4, &pending);
                        cmd[1] = pending.minute;
@@ -1379,59 +1454,71 @@ static int mcdx_xfer(struct s_drive_stuff *stuffp,
                        cmd[3] = pending.frame;
                }
 
-               cmd[6] = (unsigned char) ((stuffp->high_border - stuffp->pending) / 4);
+               cmd[6] =
+                   (unsigned
+                    char) ((stuffp->high_border - stuffp->pending) / 4);
                xtrace(XFER, "[%2d]\n", cmd[6]);
 
                stuffp->busy = 1;
                /* Now really issue the request command */
                outsb((unsigned int) stuffp->wreg_data, cmd, sizeof cmd);
 
-    }
+       }
 #ifdef AK2
-       if ( stuffp->int_err ) {
+       if (stuffp->int_err) {
                stuffp->valid = 0;
                stuffp->int_err = 0;
                return -1;
        }
-#endif /* AK2 */
+#endif                         /* AK2 */
 
-    stuffp->low_border = (stuffp->low_border += done) < stuffp->high_border
-           ? stuffp->low_border : stuffp->high_border;
+       stuffp->low_border = (stuffp->low_border +=
+                             done) <
+           stuffp->high_border ? stuffp->low_border : stuffp->high_border;
 
-    return done;
+       return done;
 }
 
 
 /*     Access to elements of the mcdx_drive_map members */
 
-static char* port(int *ip) { return (char*) ip[0]; }
-static int irq(int *ip) { return ip[1]; }
+static char *port(int *ip)
+{
+       return (char *) ip[0];
+}
+static int irq(int *ip)
+{
+       return ip[1];
+}
 
 /*     Misc number converters */
 
 static unsigned int bcd2uint(unsigned char c)
-{ return (c >> 4) * 10 + (c & 0x0f); }
+{
+       return (c >> 4) * 10 + (c & 0x0f);
+}
 
 static unsigned int uint2bcd(unsigned int ival)
-{ return ((ival / 10) << 4) | (ival % 10); }
+{
+       return ((ival / 10) << 4) | (ival % 10);
+}
 
-static void log2msf(unsigned int l, struct cdrom_msf0pmsf)
+static void log2msf(unsigned int l, struct cdrom_msf0 *pmsf)
 {
-    l += CD_MSF_OFFSET;
-    pmsf->minute = uint2bcd(l / 4500), l %= 4500;
-    pmsf->second = uint2bcd(l / 75);
-    pmsf->frame = uint2bcd(l % 75);
+       l += CD_MSF_OFFSET;
+       pmsf->minute = uint2bcd(l / 4500), l %= 4500;
+       pmsf->second = uint2bcd(l / 75);
+       pmsf->frame = uint2bcd(l % 75);
 }
 
-static unsigned int msf2log(const struct cdrom_msf0pmsf)
+static unsigned int msf2log(const struct cdrom_msf0 *pmsf)
 {
-    return bcd2uint(pmsf->frame)
-    + bcd2uint(pmsf->second) * 75
-    + bcd2uint(pmsf->minute) * 4500
-    - CD_MSF_OFFSET;
+       return bcd2uint(pmsf->frame)
+           + bcd2uint(pmsf->second) * 75
+           + bcd2uint(pmsf->minute) * 4500 - CD_MSF_OFFSET;
 }
 
-int mcdx_readtoc(struct s_drive_stuffstuffp)
+int mcdx_readtoc(struct s_drive_stuff *stuffp)
 /*  Read the toc entries from the CD,
  *  Return: -1 on failure, else 0 */
 {
@@ -1442,17 +1529,21 @@ int mcdx_readtoc(struct s_drive_stuff* stuffp)
        }
 
        xtrace(READTOC, "ioctl() readtoc for %d tracks\n",
-                       stuffp->di.n_last - stuffp->di.n_first + 1);
+              stuffp->di.n_last - stuffp->di.n_first + 1);
 
-    if (-1 == mcdx_hold(stuffp, 1)) return -1;
+       if (-1 == mcdx_hold(stuffp, 1))
+               return -1;
 
        xtrace(READTOC, "ioctl() tocmode\n");
-       if (-1 == mcdx_setdrivemode(stuffp, TOC, 1)) return -EIO;
+       if (-1 == mcdx_setdrivemode(stuffp, TOC, 1))
+               return -EIO;
 
        /* all seems to be ok so far ... malloc */
        {
                int size;
-               size = sizeof(struct s_subqcode) * (stuffp->di.n_last - stuffp->di.n_first + 2);
+               size =
+                   sizeof(struct s_subqcode) * (stuffp->di.n_last -
+                                                stuffp->di.n_first + 2);
 
                xtrace(MALLOC, "ioctl() malloc %d bytes\n", size);
                stuffp->toc = kmalloc(size, GFP_KERNEL);
@@ -1469,11 +1560,11 @@ int mcdx_readtoc(struct s_drive_stuff* stuffp)
                int retries;
 
                for (trk = 0;
-                               trk < (stuffp->di.n_last - stuffp->di.n_first + 1);
-                               trk++)
+                    trk < (stuffp->di.n_last - stuffp->di.n_first + 1);
+                    trk++)
                        stuffp->toc[trk].index = 0;
 
-               for (retries = 300; retries; retries--) { /* why 300? */
+               for (retries = 300; retries; retries--) {       /* why 300? */
                        struct s_subqcode q;
                        unsigned int idx;
 
@@ -1485,19 +1576,24 @@ int mcdx_readtoc(struct s_drive_stuff* stuffp)
                        idx = bcd2uint(q.index);
 
                        if ((idx > 0)
-                                       && (idx <= stuffp->di.n_last)
-                                       && (q.tno == 0)
-                                       && (stuffp->toc[idx - stuffp->di.n_first].index == 0)) {
+                           && (idx <= stuffp->di.n_last)
+                           && (q.tno == 0)
+                           && (stuffp->toc[idx - stuffp->di.n_first].
+                               index == 0)) {
                                stuffp->toc[idx - stuffp->di.n_first] = q;
-                               xtrace(READTOC, "ioctl() toc idx %d (trk %d)\n", idx, trk);
+                               xtrace(READTOC,
+                                      "ioctl() toc idx %d (trk %d)\n",
+                                      idx, trk);
                                trk--;
                        }
-                       if (trk == 0) break;
+                       if (trk == 0)
+                               break;
                }
-               memset(&stuffp->toc[stuffp->di.n_last - stuffp->di.n_first + 1],
-                               0, sizeof(stuffp->toc[0]));
-               stuffp->toc[stuffp->di.n_last - stuffp->di.n_first + 1].dt
-                               = stuffp->di.msf_leadout;
+               memset(&stuffp->
+                      toc[stuffp->di.n_last - stuffp->di.n_first + 1], 0,
+                      sizeof(stuffp->toc[0]));
+               stuffp->toc[stuffp->di.n_last - stuffp->di.n_first +
+                           1].dt = stuffp->di.msf_leadout;
        }
 
        /* unset toc mode */
@@ -1506,16 +1602,23 @@ int mcdx_readtoc(struct s_drive_stuff* stuffp)
                return -EIO;
 
 #if MCDX_DEBUG && READTOC
-       { int trk;
-       for (trk = 0;
-                       trk < (stuffp->di.n_last - stuffp->di.n_first + 2);
-                       trk++)
-               xtrace(READTOC, "ioctl() %d readtoc %02x %02x %02x"
-                               "  %02x:%02x.%02x  %02x:%02x.%02x\n",
-                               trk + stuffp->di.n_first,
-                               stuffp->toc[trk].control, stuffp->toc[trk].tno, stuffp->toc[trk].index,
-                               stuffp->toc[trk].tt.minute, stuffp->toc[trk].tt.second, stuffp->toc[trk].tt.frame,
-                               stuffp->toc[trk].dt.minute, stuffp->toc[trk].dt.second, stuffp->toc[trk].dt.frame);
+       {
+               int trk;
+               for (trk = 0;
+                    trk < (stuffp->di.n_last - stuffp->di.n_first + 2);
+                    trk++)
+                       xtrace(READTOC, "ioctl() %d readtoc %02x %02x %02x"
+                              "  %02x:%02x.%02x  %02x:%02x.%02x\n",
+                              trk + stuffp->di.n_first,
+                              stuffp->toc[trk].control,
+                              stuffp->toc[trk].tno,
+                              stuffp->toc[trk].index,
+                              stuffp->toc[trk].tt.minute,
+                              stuffp->toc[trk].tt.second,
+                              stuffp->toc[trk].tt.frame,
+                              stuffp->toc[trk].dt.minute,
+                              stuffp->toc[trk].dt.second,
+                              stuffp->toc[trk].dt.frame);
        }
 #endif
 
@@ -1523,109 +1626,110 @@ int mcdx_readtoc(struct s_drive_stuff* stuffp)
 }
 
 static int
-mcdx_playmsf(struct s_drive_stuff* stuffp, const struct cdrom_msf* msf)
+mcdx_playmsf(struct s_drive_stuff *stuffp, const struct cdrom_msf *msf)
 {
-    unsigned char cmd[7] = {
-        0, 0, 0, 0, 0, 0, 0
-    };
+       unsigned char cmd[7] = {
+               0, 0, 0, 0, 0, 0, 0
+       };
 
        if (!stuffp->readcmd) {
                xinfo("Can't play from missing disk.\n");
                return -1;
        }
 
-    cmd[0] = stuffp->playcmd;
+       cmd[0] = stuffp->playcmd;
 
-    cmd[1] = msf->cdmsf_min0;
-    cmd[2] = msf->cdmsf_sec0;
-    cmd[3] = msf->cdmsf_frame0;
-    cmd[4] = msf->cdmsf_min1;
-    cmd[5] = msf->cdmsf_sec1;
-    cmd[6] = msf->cdmsf_frame1;
+       cmd[1] = msf->cdmsf_min0;
+       cmd[2] = msf->cdmsf_sec0;
+       cmd[3] = msf->cdmsf_frame0;
+       cmd[4] = msf->cdmsf_min1;
+       cmd[5] = msf->cdmsf_sec1;
+       cmd[6] = msf->cdmsf_frame1;
 
-    xtrace(PLAYMSF, "ioctl(): play %x "
-            "%02x:%02x:%02x -- %02x:%02x:%02x\n",
-            cmd[0], cmd[1], cmd[2], cmd[3],
-            cmd[4], cmd[5], cmd[6]);
+       xtrace(PLAYMSF, "ioctl(): play %x "
+              "%02x:%02x:%02x -- %02x:%02x:%02x\n",
+              cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6]);
 
-    outsb((unsigned int) stuffp->wreg_data, cmd, sizeof cmd);
+       outsb((unsigned int) stuffp->wreg_data, cmd, sizeof cmd);
 
-    if (-1 == mcdx_getval(stuffp, 3 * HZ, 0, NULL)) {
-        xwarn("playmsf() timeout\n");
-        return -1;
-    }
+       if (-1 == mcdx_getval(stuffp, 3 * HZ, 0, NULL)) {
+               xwarn("playmsf() timeout\n");
+               return -1;
+       }
 
-    stuffp->audiostatus = CDROM_AUDIO_PLAY;
-    return 0;
+       stuffp->audiostatus = CDROM_AUDIO_PLAY;
+       return 0;
 }
 
 static int
-mcdx_playtrk(struct s_drive_stuff* stuffp, const struct cdrom_ti* ti)
+mcdx_playtrk(struct s_drive_stuff *stuffp, const struct cdrom_ti *ti)
 {
-    struct s_subqcode* p;
-    struct cdrom_msf msf;
+       struct s_subqcode *p;
+       struct cdrom_msf msf;
 
-    if (-1 == mcdx_readtoc(stuffp)) return -1;
+       if (-1 == mcdx_readtoc(stuffp))
+               return -1;
 
-    if (ti) p = &stuffp->toc[ti->cdti_trk0 - stuffp->di.n_first];
-    else p = &stuffp->start;
+       if (ti)
+               p = &stuffp->toc[ti->cdti_trk0 - stuffp->di.n_first];
+       else
+               p = &stuffp->start;
 
-    msf.cdmsf_min0 = p->dt.minute;
-    msf.cdmsf_sec0 = p->dt.second;
-    msf.cdmsf_frame0 = p->dt.frame;
+       msf.cdmsf_min0 = p->dt.minute;
+       msf.cdmsf_sec0 = p->dt.second;
+       msf.cdmsf_frame0 = p->dt.frame;
 
-    if (ti) {
-        p = &stuffp->toc[ti->cdti_trk1 - stuffp->di.n_first + 1];
-        stuffp->stop = *p;
-    } else p = &stuffp->stop;
+       if (ti) {
+               p = &stuffp->toc[ti->cdti_trk1 - stuffp->di.n_first + 1];
+               stuffp->stop = *p;
+       } else
+               p = &stuffp->stop;
 
-    msf.cdmsf_min1 = p->dt.minute;
-    msf.cdmsf_sec1 = p->dt.second;
-    msf.cdmsf_frame1 = p->dt.frame;
+       msf.cdmsf_min1 = p->dt.minute;
+       msf.cdmsf_sec1 = p->dt.second;
+       msf.cdmsf_frame1 = p->dt.frame;
 
-    return mcdx_playmsf(stuffp, &msf);
+       return mcdx_playmsf(stuffp, &msf);
 }
 
 
 /* Drive functions ************************************************/
 
-static int
-mcdx_tray_move(struct cdrom_device_info * cdi, int position)
+static int mcdx_tray_move(struct cdrom_device_info *cdi, int position)
 {
-    struct s_drive_stuff *stuffp = mcdx_stuffp[MINOR(cdi->dev)];
+       struct s_drive_stuff *stuffp = mcdx_stuffp[MINOR(cdi->dev)];
 
-    if (!stuffp->present) 
+       if (!stuffp->present)
                return -ENXIO;
        if (!(stuffp->present & DOOR))
-               return -ENOSYS; 
+               return -ENOSYS;
 
-       if (position)                /* 1: eject */
-               return mcdx_talk(stuffp, "\xf6", 1, NULL, 1, 5 * HZ, 3);
-       else /* 0: close */
-                       return mcdx_talk(stuffp, "\xf8", 1, NULL, 1, 5 * HZ, 3);
-    return 1;
+       if (position)           /* 1: eject */
+               return mcdx_talk(stuffp, "\xf6", 1, NULL, 1, 5 * HZ, 3);
+       else                    /* 0: close */
+               return mcdx_talk(stuffp, "\xf8", 1, NULL, 1, 5 * HZ, 3);
+       return 1;
 }
 
-static int
-mcdx_stop(struct s_drive_stuff *stuffp, int tries)
-{ return mcdx_talk(stuffp, "\xf0", 1, NULL, 1, 2 * HZ, tries); }
+static int mcdx_stop(struct s_drive_stuff *stuffp, int tries)
+{
+       return mcdx_talk(stuffp, "\xf0", 1, NULL, 1, 2 * HZ, tries);
+}
 
-static int
-mcdx_hold(struct s_drive_stuff *stuffp, int tries)
-{ return mcdx_talk(stuffp, "\x70", 1, NULL, 1, 2 * HZ, tries); }
+static int mcdx_hold(struct s_drive_stuff *stuffp, int tries)
+{
+       return mcdx_talk(stuffp, "\x70", 1, NULL, 1, 2 * HZ, tries);
+}
 
-static int
-mcdx_requestsubqcode(struct s_drive_stuff *stuffp,
-        struct s_subqcode *sub,
-        int tries)
+static int mcdx_requestsubqcode(struct s_drive_stuff *stuffp,
+                    struct s_subqcode *sub, int tries)
 {
        char buf[11];
        int ans;
 
-       if (-1 == (ans = mcdx_talk(
-            stuffp, "\x20", 1, buf, sizeof(buf),
-            2 * HZ, tries)))
-        return -1;
+       if (-1 == (ans = mcdx_talk(stuffp, "\x20", 1, buf, sizeof(buf),
+                                  2 * HZ, tries)))
+               return -1;
        sub->control = buf[1];
        sub->tno = buf[2];
        sub->index = buf[3];
@@ -1639,31 +1743,34 @@ mcdx_requestsubqcode(struct s_drive_stuff *stuffp,
        return ans;
 }
 
-static int
-mcdx_requestmultidiskinfo(struct s_drive_stuff *stuffp, struct s_multi *multi, int tries)
+static int mcdx_requestmultidiskinfo(struct s_drive_stuff *stuffp,
+                         struct s_multi *multi, int tries)
 {
        char buf[5];
        int ans;
 
-    if (stuffp->present & MULTI) {
-               ans = mcdx_talk(stuffp, "\x11", 1, buf, sizeof(buf), 2 * HZ, tries);
+       if (stuffp->present & MULTI) {
+               ans =
+                   mcdx_talk(stuffp, "\x11", 1, buf, sizeof(buf), 2 * HZ,
+                             tries);
                multi->multi = buf[1];
-        multi->msf_last.minute = buf[2];
-        multi->msf_last.second = buf[3];
-        multi->msf_last.frame = buf[4];
-        return ans;
-    } else {
-        multi->multi = 0;
-        return 0;
-    }
+               multi->msf_last.minute = buf[2];
+               multi->msf_last.second = buf[3];
+               multi->msf_last.frame = buf[4];
+               return ans;
+       } else {
+               multi->multi = 0;
+               return 0;
+       }
 }
 
-static int
-mcdx_requesttocdata(struct s_drive_stuff *stuffp, struct s_diskinfo *info, int tries)
+static int mcdx_requesttocdata(struct s_drive_stuff *stuffp, struct s_diskinfo *info,
+                   int tries)
 {
        char buf[9];
        int ans;
-       ans = mcdx_talk(stuffp, "\x10", 1, buf, sizeof(buf), 2 * HZ, tries);
+       ans =
+           mcdx_talk(stuffp, "\x10", 1, buf, sizeof(buf), 2 * HZ, tries);
        if (ans == -1) {
                info->n_first = 0;
                info->n_last = 0;
@@ -1680,8 +1787,8 @@ mcdx_requesttocdata(struct s_drive_stuff *stuffp, struct s_diskinfo *info, int t
        return ans;
 }
 
-static int
-mcdx_setdrivemode(struct s_drive_stuff *stuffp, enum drivemodes mode, int tries)
+static int mcdx_setdrivemode(struct s_drive_stuff *stuffp, enum drivemodes mode,
+                 int tries)
 {
        char cmd[2];
        int ans;
@@ -1692,32 +1799,47 @@ mcdx_setdrivemode(struct s_drive_stuff *stuffp, enum drivemodes mode, int tries)
                return -1;
 
        switch (mode) {
-         case TOC: cmd[1] |= 0x04; break;
-         case DATA: cmd[1] &= ~0x04; break;
-         case RAW: cmd[1] |= 0x40; break;
-         case COOKED: cmd[1] &= ~0x40; break;
-         default: break;
+       case TOC:
+               cmd[1] |= 0x04;
+               break;
+       case DATA:
+               cmd[1] &= ~0x04;
+               break;
+       case RAW:
+               cmd[1] |= 0x40;
+               break;
+       case COOKED:
+               cmd[1] &= ~0x40;
+               break;
+       default:
+               break;
        }
        cmd[0] = 0x50;
        return mcdx_talk(stuffp, cmd, 2, NULL, 1, 5 * HZ, tries);
 }
 
-static int
-mcdx_setdatamode(struct s_drive_stuff *stuffp, enum datamodes mode, int tries)
+static int mcdx_setdatamode(struct s_drive_stuff *stuffp, enum datamodes mode,
+                int tries)
 {
        unsigned char cmd[2] = { 0xa0 };
        xtrace(HW, "setdatamode() %d\n", mode);
        switch (mode) {
-         case MODE0: cmd[1] = 0x00; break;
-         case MODE1: cmd[1] = 0x01; break;
-         case MODE2: cmd[1] = 0x02; break;
-         default: return -EINVAL;
+       case MODE0:
+               cmd[1] = 0x00;
+               break;
+       case MODE1:
+               cmd[1] = 0x01;
+               break;
+       case MODE2:
+               cmd[1] = 0x02;
+               break;
+       default:
+               return -EINVAL;
        }
        return mcdx_talk(stuffp, cmd, 2, NULL, 1, 5 * HZ, tries);
 }
 
-static int
-mcdx_config(struct s_drive_stuff *stuffp, int tries)
+static int mcdx_config(struct s_drive_stuff *stuffp, int tries)
 {
        char cmd[4];
 
@@ -1737,14 +1859,14 @@ mcdx_config(struct s_drive_stuff *stuffp, int tries)
        return mcdx_talk(stuffp, cmd, 3, NULL, 1, 1 * HZ, tries);
 }
 
-static int
-mcdx_requestversion(struct s_drive_stuff *stuffp, struct s_version *ver, int tries)
+static int mcdx_requestversion(struct s_drive_stuff *stuffp, struct s_version *ver,
+                   int tries)
 {
        char buf[3];
        int ans;
 
        if (-1 == (ans = mcdx_talk(stuffp, "\xdc",
-                       1, buf, sizeof(buf), 2 * HZ, tries)))
+                                  1, buf, sizeof(buf), 2 * HZ, tries)))
                return ans;
 
        ver->code = buf[1];
@@ -1753,65 +1875,66 @@ mcdx_requestversion(struct s_drive_stuff *stuffp, struct s_version *ver, int tri
        return ans;
 }
 
-static int
-mcdx_reset(struct s_drive_stuff *stuffp, enum resetmodes mode, int tries)
+static int mcdx_reset(struct s_drive_stuff *stuffp, enum resetmodes mode, int tries)
 {
        if (mode == HARD) {
-               outb(0, (unsigned int) stuffp->wreg_chn);               /* no dma, no irq -> hardware */
-               outb(0, (unsigned int) stuffp->wreg_reset);             /* hw reset */
+               outb(0, (unsigned int) stuffp->wreg_chn);       /* no dma, no irq -> hardware */
+               outb(0, (unsigned int) stuffp->wreg_reset);     /* hw reset */
                return 0;
-       } else return mcdx_talk(stuffp, "\x60", 1, NULL, 1, 5 * HZ, tries);
+       } else
+               return mcdx_talk(stuffp, "\x60", 1, NULL, 1, 5 * HZ, tries);
 }
 
-static int mcdx_lockdoor(struct cdrom_device_info * cdi, int lock)
+static int mcdx_lockdoor(struct cdrom_device_info *cdi, int lock)
 {
-    struct s_drive_stuff *stuffp = mcdx_stuffp[MINOR(cdi->dev)];
+       struct s_drive_stuff *stuffp = mcdx_stuffp[MINOR(cdi->dev)];
        char cmd[2] = { 0xfe };
 
-    if (!(stuffp->present & DOOR))
+       if (!(stuffp->present & DOOR))
                return -ENOSYS;
-    if (stuffp->present & DOOR) {
-        cmd[1] = lock ? 0x01 : 0x00;
-        return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 1, 5 * HZ, 3);
-    } else return 0;
+       if (stuffp->present & DOOR) {
+               cmd[1] = lock ? 0x01 : 0x00;
+               return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 1, 5 * HZ, 3);
+       } else
+               return 0;
 }
 
-static int
-mcdx_getstatus(struct s_drive_stuff *stuffp, int tries)
-{ return mcdx_talk(stuffp, "\x40", 1, NULL, 1, 5 * HZ, tries); }
+static int mcdx_getstatus(struct s_drive_stuff *stuffp, int tries)
+{
+       return mcdx_talk(stuffp, "\x40", 1, NULL, 1, 5 * HZ, tries);
+}
 
 static int
-mcdx_getval(struct s_drive_stuff *stuffp, int to, int delay, charbuf)
+mcdx_getval(struct s_drive_stuff *stuffp, int to, int delay, char *buf)
 {
-    unsigned long timeout = to + jiffies;
-    char c;
+       unsigned long timeout = to + jiffies;
+       char c;
 
-    if (!buf) buf = &c;
+       if (!buf)
+               buf = &c;
 
-    while (inb((unsigned int) stuffp->rreg_status) & MCDX_RBIT_STEN) {
-        if (time_after(jiffies, timeout)) return -1;
-        mcdx_delay(stuffp, delay);
-    }
+       while (inb((unsigned int) stuffp->rreg_status) & MCDX_RBIT_STEN) {
+               if (time_after(jiffies, timeout))
+                       return -1;
+               mcdx_delay(stuffp, delay);
+       }
 
-    *buf = (unsigned char) inb((unsigned int) stuffp->rreg_data) & 0xff;
+       *buf = (unsigned char) inb((unsigned int) stuffp->rreg_data) & 0xff;
 
-    return 0;
+       return 0;
 }
 
-static int
-mcdx_setattentuator(
-        struct s_drive_stuff* stuffp,
-        struct cdrom_volctrl* vol,
-        int tries)
+static int mcdx_setattentuator(struct s_drive_stuff *stuffp,
+                   struct cdrom_volctrl *vol, int tries)
 {
-    char cmd[5];
-    cmd[0] = 0xae;
-    cmd[1] = vol->channel0;
-    cmd[2] = 0;
-    cmd[3] = vol->channel1;
-    cmd[4] = 0;
-
-    return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 5, 200, tries);
+       char cmd[5];
+       cmd[0] = 0xae;
+       cmd[1] = vol->channel0;
+       cmd[2] = 0;
+       cmd[3] = vol->channel1;
+       cmd[4] = 0;
+
+       return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 5, 200, tries);
 }
 
-/* ex:set ts=4 sw=4 ai si: */
+MODULE_LICENSE("GPL");
index eb102a4a7fca1f1c36b5e4a4816fe89d8fc8b064..1bacf58859b892bb37a1b5ab3c7fcfecd285f1bc 100644 (file)
 
 static int sjcd_present = 0;
 
-#define SJCD_BUF_SIZ 32 /* cdr-h94a has internal 64K buffer */
+#define SJCD_BUF_SIZ 32                /* cdr-h94a has internal 64K buffer */
 
 /*
  * buffer for block size conversion
  */
-static char sjcd_buf[ 2048 * SJCD_BUF_SIZ ];
-static volatile int sjcd_buf_bn[ SJCD_BUF_SIZ ], sjcd_next_bn;
+static char sjcd_buf[2048 * SJCD_BUF_SIZ];
+static volatile int sjcd_buf_bn[SJCD_BUF_SIZ], sjcd_next_bn;
 static volatile int sjcd_buf_in, sjcd_buf_out = -1;
 
 /*
@@ -113,9 +113,7 @@ static struct sjcd_play_msf sjcd_playing;
 
 static int sjcd_base = SJCD_BASE_ADDR;
 
-#ifdef MODULE
 MODULE_PARM(sjcd_base, "i");
-#endif
 
 static DECLARE_WAIT_QUEUE_HEAD(sjcd_waitq);
 
@@ -125,13 +123,13 @@ static DECLARE_WAIT_QUEUE_HEAD(sjcd_waitq);
 static volatile unsigned short sjcd_transfer_is_active = 0;
 
 enum sjcd_transfer_state {
-  SJCD_S_IDLE     = 0,
-  SJCD_S_START    = 1,
-  SJCD_S_MODE     = 2,
-  SJCD_S_READ     = 3,
-  SJCD_S_DATA     = 4,
-  SJCD_S_STOP     = 5,
-  SJCD_S_STOPPING = 6
+       SJCD_S_IDLE = 0,
+       SJCD_S_START = 1,
+       SJCD_S_MODE = 2,
+       SJCD_S_READ = 3,
+       SJCD_S_DATA = 4,
+       SJCD_S_STOP = 5,
+       SJCD_S_STOPPING = 6
 };
 static enum sjcd_transfer_state sjcd_transfer_state = SJCD_S_IDLE;
 static long sjcd_transfer_timeout = 0;
@@ -166,14 +164,14 @@ static int sjcd_cleanup(void);
  * base address.
  */
 #ifndef MODULE
-static int __init sjcd_setup( char *str)
+static int __init sjcd_setup(char *str)
 {
-   int ints[2];
-   (void)get_options(str, ARRAY_SIZE(ints), ints);
-   if (ints[0] > 0)
-      sjcd_base = ints[1];
+       int ints[2];
+       (void) get_options(str, ARRAY_SIZE(ints), ints);
+       if (ints[0] > 0)
+               sjcd_base = ints[1];
 
-   return 1;
+       return 1;
 }
 
 __setup("sjcd=", sjcd_setup);
@@ -183,168 +181,191 @@ __setup("sjcd=", sjcd_setup);
 /*
  * Special converters.
  */
-static unsigned char bin2bcd( int bin ){
-  int u, v;
+static unsigned char bin2bcd(int bin)
+{
+       int u, v;
 
-  u = bin % 10; v = bin / 10;
-  return( u | ( v << 4 ) );
+       u = bin % 10;
+       v = bin / 10;
+       return (u | (v << 4));
 }
 
-static int bcd2bin( unsigned char bcd ){
-    return( ( bcd >> 4 ) * 10 + ( bcd & 0x0F ) );
+static int bcd2bin(unsigned char bcd)
+{
+       return ((bcd >> 4) * 10 + (bcd & 0x0F));
 }
 
-static long msf2hsg( struct msf *mp ){
-  return( bcd2bin( mp->frame ) + bcd2bin( mp->sec ) * 75
-        + bcd2bin( mp->min ) * 4500 - 150 );
+static long msf2hsg(struct msf *mp)
+{
+       return (bcd2bin(mp->frame) + bcd2bin(mp->sec) * 75
+               + bcd2bin(mp->min) * 4500 - 150);
 }
 
-static void hsg2msf( long hsg, struct msf *msf ){
-  hsg += 150; msf->min = hsg / 4500;
-  hsg %= 4500; msf->sec = hsg / 75; msf->frame = hsg % 75;
-  msf->min = bin2bcd( msf->min );       /* convert to BCD */
-  msf->sec = bin2bcd( msf->sec );
-  msf->frame = bin2bcd( msf->frame );
+static void hsg2msf(long hsg, struct msf *msf)
+{
+       hsg += 150;
+       msf->min = hsg / 4500;
+       hsg %= 4500;
+       msf->sec = hsg / 75;
+       msf->frame = hsg % 75;
+       msf->min = bin2bcd(msf->min);   /* convert to BCD */
+       msf->sec = bin2bcd(msf->sec);
+       msf->frame = bin2bcd(msf->frame);
 }
 
 /*
  * Send a command to cdrom. Invalidate status.
  */
-static void sjcd_send_cmd( unsigned char cmd ){
+static void sjcd_send_cmd(unsigned char cmd)
+{
 #if defined( SJCD_TRACE )
-  printk( "SJCD: send_cmd( 0x%x )\n", cmd );
+       printk("SJCD: send_cmd( 0x%x )\n", cmd);
 #endif
-  outb( cmd, SJCDPORT( 0 ) );
-  sjcd_command_is_in_progress = 1;
-  sjcd_status_valid = 0;
-  sjcd_command_failed = 0;
+       outb(cmd, SJCDPORT(0));
+       sjcd_command_is_in_progress = 1;
+       sjcd_status_valid = 0;
+       sjcd_command_failed = 0;
 }
 
 /*
  * Send a command with one arg to cdrom. Invalidate status.
  */
-static void sjcd_send_1_cmd( unsigned char cmd, unsigned char a ){
+static void sjcd_send_1_cmd(unsigned char cmd, unsigned char a)
+{
 #if defined( SJCD_TRACE )
-  printk( "SJCD: send_1_cmd( 0x%x, 0x%x )\n", cmd, a );
+       printk("SJCD: send_1_cmd( 0x%x, 0x%x )\n", cmd, a);
 #endif
-  outb( cmd, SJCDPORT( 0 ) );
-  outb( a, SJCDPORT( 0 ) );
-  sjcd_command_is_in_progress = 1;
-  sjcd_status_valid = 0;
-  sjcd_command_failed = 0;
+       outb(cmd, SJCDPORT(0));
+       outb(a, SJCDPORT(0));
+       sjcd_command_is_in_progress = 1;
+       sjcd_status_valid = 0;
+       sjcd_command_failed = 0;
 }
 
 /*
  * Send a command with four args to cdrom. Invalidate status.
  */
-static void sjcd_send_4_cmd( unsigned char cmd, unsigned char a,
-           unsigned char b, unsigned char c, unsigned char d ){
+static void sjcd_send_4_cmd(unsigned char cmd, unsigned char a,
+                           unsigned char b, unsigned char c,
+                           unsigned char d)
+{
 #if defined( SJCD_TRACE )
-  printk( "SJCD: send_4_cmd( 0x%x )\n", cmd );
-#endif
-  outb( cmd, SJCDPORT( 0 ) );
-  outb( a, SJCDPORT( 0 ) );
-  outb( b, SJCDPORT( 0 ) );
-  outb( c, SJCDPORT( 0 ) );
-  outb( d, SJCDPORT( 0 ) );
-  sjcd_command_is_in_progress = 1;
-  sjcd_status_valid = 0;
-  sjcd_command_failed = 0;
+       printk("SJCD: send_4_cmd( 0x%x )\n", cmd);
+#endif
+       outb(cmd, SJCDPORT(0));
+       outb(a, SJCDPORT(0));
+       outb(b, SJCDPORT(0));
+       outb(c, SJCDPORT(0));
+       outb(d, SJCDPORT(0));
+       sjcd_command_is_in_progress = 1;
+       sjcd_status_valid = 0;
+       sjcd_command_failed = 0;
 }
 
 /*
  * Send a play or read command to cdrom. Invalidate Status.
  */
-static void sjcd_send_6_cmd( unsigned char cmd, struct sjcd_play_msf *pms ){
+static void sjcd_send_6_cmd(unsigned char cmd, struct sjcd_play_msf *pms)
+{
 #if defined( SJCD_TRACE )
-  printk( "SJCD: send_long_cmd( 0x%x )\n", cmd );
-#endif
-  outb( cmd, SJCDPORT( 0 ) );
-  outb( pms->start.min,   SJCDPORT( 0 ) );
-  outb( pms->start.sec,   SJCDPORT( 0 ) );
-  outb( pms->start.frame, SJCDPORT( 0 ) );
-  outb( pms->end.min,     SJCDPORT( 0 ) );
-  outb( pms->end.sec,     SJCDPORT( 0 ) );
-  outb( pms->end.frame,   SJCDPORT( 0 ) );
-  sjcd_command_is_in_progress = 1;
-  sjcd_status_valid = 0;
-  sjcd_command_failed = 0;
+       printk("SJCD: send_long_cmd( 0x%x )\n", cmd);
+#endif
+       outb(cmd, SJCDPORT(0));
+       outb(pms->start.min, SJCDPORT(0));
+       outb(pms->start.sec, SJCDPORT(0));
+       outb(pms->start.frame, SJCDPORT(0));
+       outb(pms->end.min, SJCDPORT(0));
+       outb(pms->end.sec, SJCDPORT(0));
+       outb(pms->end.frame, SJCDPORT(0));
+       sjcd_command_is_in_progress = 1;
+       sjcd_status_valid = 0;
+       sjcd_command_failed = 0;
 }
 
 /*
  * Get a value from the data port. Should not block, so we use a little
  * wait for a while. Returns 0 if OK.
  */
-static int sjcd_load_response( void *buf, int len ){
-  unsigned char *resp = ( unsigned char * )buf;
-
-  for( ; len; --len ){ 
-    int i;
-    for( i = 200; i-- && !SJCD_STATUS_AVAILABLE( inb( SJCDPORT( 1 ) ) ); );
-    if( i > 0 ) *resp++ = ( unsigned char )inb( SJCDPORT( 0 ) );
-    else break;
-  }
-  return( len );
+static int sjcd_load_response(void *buf, int len)
+{
+       unsigned char *resp = (unsigned char *) buf;
+
+       for (; len; --len) {
+               int i;
+               for (i = 200;
+                    i-- && !SJCD_STATUS_AVAILABLE(inb(SJCDPORT(1))););
+               if (i > 0)
+                       *resp++ = (unsigned char) inb(SJCDPORT(0));
+               else
+                       break;
+       }
+       return (len);
 }
 
 /*
  * Load and parse command completion status (drive info byte and maybe error).
  * Sorry, no error classification yet.
  */
-static void sjcd_load_status( void ){
-  sjcd_media_is_changed = 0;
-  sjcd_completion_error = 0;
-  sjcd_completion_status = inb( SJCDPORT( 0 ) );
-  if( sjcd_completion_status & SST_DOOR_OPENED ){
-    sjcd_door_closed = sjcd_media_is_available = 0;
-  } else {
-    sjcd_door_closed = 1;
-    if( sjcd_completion_status & SST_MEDIA_CHANGED )
-      sjcd_media_is_available = sjcd_media_is_changed = 1;
-    else if( sjcd_completion_status & 0x0F ){
-      /*
-       * OK, we seem to catch an error ...
-       */
-      while( !SJCD_STATUS_AVAILABLE( inb( SJCDPORT( 1 ) ) ) );
-      sjcd_completion_error = inb( SJCDPORT( 0 ) );
-      if( ( sjcd_completion_status & 0x08 ) &&
-        ( sjcd_completion_error & 0x40 ) )
-       sjcd_media_is_available = 0;
-      else sjcd_command_failed = 1;
-    } else sjcd_media_is_available = 1;
-  }
-  /*
-   * Ok, status loaded successfully.
-   */
-  sjcd_status_valid = 1, sjcd_error_reported = 0;
-  sjcd_command_is_in_progress = 0;
-
-  /*
-   * If the disk is changed, the TOC is not valid.
-   */
-  if( sjcd_media_is_changed ) sjcd_toc_uptodate = 0;
+static void sjcd_load_status(void)
+{
+       sjcd_media_is_changed = 0;
+       sjcd_completion_error = 0;
+       sjcd_completion_status = inb(SJCDPORT(0));
+       if (sjcd_completion_status & SST_DOOR_OPENED) {
+               sjcd_door_closed = sjcd_media_is_available = 0;
+       } else {
+               sjcd_door_closed = 1;
+               if (sjcd_completion_status & SST_MEDIA_CHANGED)
+                       sjcd_media_is_available = sjcd_media_is_changed =
+                           1;
+               else if (sjcd_completion_status & 0x0F) {
+                       /*
+                        * OK, we seem to catch an error ...
+                        */
+                       while (!SJCD_STATUS_AVAILABLE(inb(SJCDPORT(1))));
+                       sjcd_completion_error = inb(SJCDPORT(0));
+                       if ((sjcd_completion_status & 0x08) &&
+                           (sjcd_completion_error & 0x40))
+                               sjcd_media_is_available = 0;
+                       else
+                               sjcd_command_failed = 1;
+               } else
+                       sjcd_media_is_available = 1;
+       }
+       /*
+        * Ok, status loaded successfully.
+        */
+       sjcd_status_valid = 1, sjcd_error_reported = 0;
+       sjcd_command_is_in_progress = 0;
+
+       /*
+        * If the disk is changed, the TOC is not valid.
+        */
+       if (sjcd_media_is_changed)
+               sjcd_toc_uptodate = 0;
 #if defined( SJCD_TRACE )
-  printk( "SJCD: status %02x.%02x loaded.\n",
-        ( int )sjcd_completion_status, ( int )sjcd_completion_error );
+       printk("SJCD: status %02x.%02x loaded.\n",
+              (int) sjcd_completion_status, (int) sjcd_completion_error);
 #endif
 }
 
 /*
  * Read status from cdrom. Check to see if the status is available.
  */
-static int sjcd_check_status( void ){
-  /*
-   * Try to load the response from cdrom into buffer.
-   */
-  if( SJCD_STATUS_AVAILABLE( inb( SJCDPORT( 1 ) ) ) ){
-    sjcd_load_status();
-    return( 1 );
-  } else {
-    /*
-     * No status is available.
-     */
-    return( 0 );
-  }
+static int sjcd_check_status(void)
+{
+       /*
+        * Try to load the response from cdrom into buffer.
+        */
+       if (SJCD_STATUS_AVAILABLE(inb(SJCDPORT(1)))) {
+               sjcd_load_status();
+               return (1);
+       } else {
+               /*
+                * No status is available.
+                */
+               return (0);
+       }
 }
 
 /*
@@ -359,575 +380,692 @@ static volatile long sjcd_status_timeout;
  */
 #define SJCD_WAIT_FOR_STATUS_TIMEOUT 1000
 
-static void sjcd_status_timer( void ){
-  if( sjcd_check_status() ){
-    /*
-     * The command completed and status is loaded, stop waiting.
-     */
-    wake_up( &sjcd_waitq );
-  } else if( --sjcd_status_timeout <= 0 ){
-    /*
-     * We are timed out. 
-     */
-    wake_up( &sjcd_waitq );
-  } else {
-    /*
-     * We have still some time to wait. Try again.
-     */
-    SJCD_SET_TIMER( sjcd_status_timer, 1 );
-  }
+static void sjcd_status_timer(void)
+{
+       if (sjcd_check_status()) {
+               /*
+                * The command completed and status is loaded, stop waiting.
+                */
+               wake_up(&sjcd_waitq);
+       } else if (--sjcd_status_timeout <= 0) {
+               /*
+                * We are timed out. 
+                */
+               wake_up(&sjcd_waitq);
+       } else {
+               /*
+                * We have still some time to wait. Try again.
+                */
+               SJCD_SET_TIMER(sjcd_status_timer, 1);
+       }
 }
 
 /*
  * Wait for status for 10 sec approx. Returns non-positive when timed out.
  * Should not be used while reading data CDs.
  */
-static int sjcd_wait_for_status( void ){
-  sjcd_status_timeout = SJCD_WAIT_FOR_STATUS_TIMEOUT;
-  SJCD_SET_TIMER( sjcd_status_timer, 1 ); 
-  sleep_on( &sjcd_waitq );    
+static int sjcd_wait_for_status(void)
+{
+       sjcd_status_timeout = SJCD_WAIT_FOR_STATUS_TIMEOUT;
+       SJCD_SET_TIMER(sjcd_status_timer, 1);
+       sleep_on(&sjcd_waitq);
 #if defined( SJCD_DIAGNOSTIC ) || defined ( SJCD_TRACE )
-  if( sjcd_status_timeout <= 0 )
-    printk( "SJCD: Error Wait For Status.\n" );
+       if (sjcd_status_timeout <= 0)
+               printk("SJCD: Error Wait For Status.\n");
 #endif
-  return( sjcd_status_timeout );
+       return (sjcd_status_timeout);
 }
 
-static int sjcd_receive_status( void ){
-  int i;
+static int sjcd_receive_status(void)
+{
+       int i;
 #if defined( SJCD_TRACE )
-  printk( "SJCD: receive_status\n" );
+       printk("SJCD: receive_status\n");
 #endif
-  /*
-   * Wait a bit for status available.
-   */
-  for( i = 200; i-- && ( sjcd_check_status() == 0 ); );
-  if( i < 0 ){
+       /*
+        * Wait a bit for status available.
+        */
+       for (i = 200; i-- && (sjcd_check_status() == 0););
+       if (i < 0) {
 #if defined( SJCD_TRACE )
-    printk( "SJCD: long wait for status\n" );
+               printk("SJCD: long wait for status\n");
 #endif
-    if( sjcd_wait_for_status() <= 0 )
-      printk( "SJCD: Timeout when read status.\n" );
-    else i = 0;
-  }
-  return( i );
+               if (sjcd_wait_for_status() <= 0)
+                       printk("SJCD: Timeout when read status.\n");
+               else
+                       i = 0;
+       }
+       return (i);
 }
 
 /*
  * Load the status. Issue get status command and wait for status available.
  */
-static void sjcd_get_status( void ){
+static void sjcd_get_status(void)
+{
 #if defined( SJCD_TRACE )
-  printk( "SJCD: get_status\n" );
+       printk("SJCD: get_status\n");
 #endif
-  sjcd_send_cmd( SCMD_GET_STATUS );
-  sjcd_receive_status();
+       sjcd_send_cmd(SCMD_GET_STATUS);
+       sjcd_receive_status();
 }
 
 /*
  * Check the drive if the disk is changed. Should be revised.
  */
-static int sjcd_disk_change( kdev_t full_dev ){
+static int sjcd_disk_change(kdev_t full_dev)
+{
 #if 0
-  printk( "SJCD: sjcd_disk_change( 0x%x )\n", full_dev );
-#endif
-  if( MINOR( full_dev ) > 0 ){
-    printk( "SJCD: request error: invalid device minor.\n" );
-    return 0;
-  }
-  if( !sjcd_command_is_in_progress )
-    sjcd_get_status();
-  return( sjcd_status_valid ? sjcd_media_is_changed : 0 );
+       printk("SJCD: sjcd_disk_change( 0x%x )\n", full_dev);
+#endif
+       if (MINOR(full_dev) > 0) {
+               printk("SJCD: request error: invalid device minor.\n");
+               return 0;
+       }
+       if (!sjcd_command_is_in_progress)
+               sjcd_get_status();
+       return (sjcd_status_valid ? sjcd_media_is_changed : 0);
 }
 
 /*
  * Read the table of contents (TOC) and TOC header if necessary.
  * We assume that the drive contains no more than 99 toc entries.
  */
-static struct sjcd_hw_disk_info sjcd_table_of_contents[ SJCD_MAX_TRACKS ];
+static struct sjcd_hw_disk_info sjcd_table_of_contents[SJCD_MAX_TRACKS];
 static unsigned char sjcd_first_track_no, sjcd_last_track_no;
 #define sjcd_disk_length  sjcd_table_of_contents[0].un.track_msf
 
-static int sjcd_update_toc( void ){
-  struct sjcd_hw_disk_info info;
-  int i;
+static int sjcd_update_toc(void)
+{
+       struct sjcd_hw_disk_info info;
+       int i;
 #if defined( SJCD_TRACE )
-  printk( "SJCD: update toc:\n" );
-#endif
-  /*
-   * check to see if we need to do anything
-   */
-  if( sjcd_toc_uptodate ) return( 0 );
-
-  /*
-   * Get the TOC start information.
-   */
-  sjcd_send_1_cmd( SCMD_GET_DISK_INFO, SCMD_GET_1_TRACK );
-  sjcd_receive_status();
-
-  if( !sjcd_status_valid ){
-    printk( "SJCD: cannot load status.\n" );
-    return( -1 );
-  }
-
-  if( !sjcd_media_is_available ){
-    printk( "SJCD: no disk in drive\n" );
-    return( -1 );
-  }
-
-  if( !sjcd_command_failed ){
-    if( sjcd_load_response( &info, sizeof( info ) ) != 0 ){
-      printk( "SJCD: cannot load response about TOC start.\n" );
-      return( -1 );
-    }
-    sjcd_first_track_no = bcd2bin( info.un.track_no );
-  } else {
-    printk( "SJCD: get first failed\n" );
-    return( -1 );
-  }
+       printk("SJCD: update toc:\n");
+#endif
+       /*
+        * check to see if we need to do anything
+        */
+       if (sjcd_toc_uptodate)
+               return (0);
+
+       /*
+        * Get the TOC start information.
+        */
+       sjcd_send_1_cmd(SCMD_GET_DISK_INFO, SCMD_GET_1_TRACK);
+       sjcd_receive_status();
+
+       if (!sjcd_status_valid) {
+               printk("SJCD: cannot load status.\n");
+               return (-1);
+       }
+
+       if (!sjcd_media_is_available) {
+               printk("SJCD: no disk in drive\n");
+               return (-1);
+       }
+
+       if (!sjcd_command_failed) {
+               if (sjcd_load_response(&info, sizeof(info)) != 0) {
+                       printk
+                           ("SJCD: cannot load response about TOC start.\n");
+                       return (-1);
+               }
+               sjcd_first_track_no = bcd2bin(info.un.track_no);
+       } else {
+               printk("SJCD: get first failed\n");
+               return (-1);
+       }
 #if defined( SJCD_TRACE )
-  printk( "SJCD: TOC start 0x%02x ", sjcd_first_track_no );
-#endif
-  /*
-   * Get the TOC finish information.
-   */
-  sjcd_send_1_cmd( SCMD_GET_DISK_INFO, SCMD_GET_L_TRACK );
-  sjcd_receive_status();
-
-  if( !sjcd_status_valid ){
-    printk( "SJCD: cannot load status.\n" );
-    return( -1 );
-  }
-
-  if( !sjcd_media_is_available ){
-    printk( "SJCD: no disk in drive\n" );
-    return( -1 );
-  }
-
-  if( !sjcd_command_failed ){
-    if( sjcd_load_response( &info, sizeof( info ) ) != 0 ){
-      printk( "SJCD: cannot load response about TOC finish.\n" );
-      return( -1 );
-    }
-    sjcd_last_track_no = bcd2bin( info.un.track_no );
-  } else {
-    printk( "SJCD: get last failed\n" );
-    return( -1 );
-  }
+       printk("SJCD: TOC start 0x%02x ", sjcd_first_track_no);
+#endif
+       /*
+        * Get the TOC finish information.
+        */
+       sjcd_send_1_cmd(SCMD_GET_DISK_INFO, SCMD_GET_L_TRACK);
+       sjcd_receive_status();
+
+       if (!sjcd_status_valid) {
+               printk("SJCD: cannot load status.\n");
+               return (-1);
+       }
+
+       if (!sjcd_media_is_available) {
+               printk("SJCD: no disk in drive\n");
+               return (-1);
+       }
+
+       if (!sjcd_command_failed) {
+               if (sjcd_load_response(&info, sizeof(info)) != 0) {
+                       printk
+                           ("SJCD: cannot load response about TOC finish.\n");
+                       return (-1);
+               }
+               sjcd_last_track_no = bcd2bin(info.un.track_no);
+       } else {
+               printk("SJCD: get last failed\n");
+               return (-1);
+       }
 #if defined( SJCD_TRACE )
-  printk( "SJCD: TOC finish 0x%02x ", sjcd_last_track_no );
-#endif
-  for( i = sjcd_first_track_no; i <= sjcd_last_track_no; i++ ){
-    /*
-     * Get the first track information.
-     */
-    sjcd_send_1_cmd( SCMD_GET_DISK_INFO, bin2bcd( i ) );
-    sjcd_receive_status();
-
-    if( !sjcd_status_valid ){
-      printk( "SJCD: cannot load status.\n" );
-      return( -1 );
-    }
-
-    if( !sjcd_media_is_available ){
-      printk( "SJCD: no disk in drive\n" );
-      return( -1 );
-    }
-
-    if( !sjcd_command_failed ){
-      if( sjcd_load_response( &sjcd_table_of_contents[ i ],
-                            sizeof( struct sjcd_hw_disk_info ) ) != 0 ){
-       printk( "SJCD: cannot load info for %d track\n", i );
-       return( -1 );
-      }
-    } else {
-      printk( "SJCD: get info %d failed\n", i );
-      return( -1 );
-    }
-  }
-
-  /*
-   * Get the disk length info.
-   */
-  sjcd_send_1_cmd( SCMD_GET_DISK_INFO, SCMD_GET_D_SIZE );
-  sjcd_receive_status();
-
-  if( !sjcd_status_valid ){
-    printk( "SJCD: cannot load status.\n" );
-    return( -1 );
-  }
-
-  if( !sjcd_media_is_available ){
-    printk( "SJCD: no disk in drive\n" );
-    return( -1 );
-  }
-
-  if( !sjcd_command_failed ){
-    if( sjcd_load_response( &info, sizeof( info ) ) != 0 ){
-      printk( "SJCD: cannot load response about disk size.\n" );
-      return( -1 );
-    }
-    sjcd_disk_length.min = info.un.track_msf.min;
-    sjcd_disk_length.sec = info.un.track_msf.sec;
-    sjcd_disk_length.frame = info.un.track_msf.frame;
-  } else {
-    printk( "SJCD: get size failed\n" );
-    return( 1 );
-  }
+       printk("SJCD: TOC finish 0x%02x ", sjcd_last_track_no);
+#endif
+       for (i = sjcd_first_track_no; i <= sjcd_last_track_no; i++) {
+               /*
+                * Get the first track information.
+                */
+               sjcd_send_1_cmd(SCMD_GET_DISK_INFO, bin2bcd(i));
+               sjcd_receive_status();
+
+               if (!sjcd_status_valid) {
+                       printk("SJCD: cannot load status.\n");
+                       return (-1);
+               }
+
+               if (!sjcd_media_is_available) {
+                       printk("SJCD: no disk in drive\n");
+                       return (-1);
+               }
+
+               if (!sjcd_command_failed) {
+                       if (sjcd_load_response(&sjcd_table_of_contents[i],
+                                              sizeof(struct
+                                                     sjcd_hw_disk_info))
+                           != 0) {
+                               printk
+                                   ("SJCD: cannot load info for %d track\n",
+                                    i);
+                               return (-1);
+                       }
+               } else {
+                       printk("SJCD: get info %d failed\n", i);
+                       return (-1);
+               }
+       }
+
+       /*
+        * Get the disk length info.
+        */
+       sjcd_send_1_cmd(SCMD_GET_DISK_INFO, SCMD_GET_D_SIZE);
+       sjcd_receive_status();
+
+       if (!sjcd_status_valid) {
+               printk("SJCD: cannot load status.\n");
+               return (-1);
+       }
+
+       if (!sjcd_media_is_available) {
+               printk("SJCD: no disk in drive\n");
+               return (-1);
+       }
+
+       if (!sjcd_command_failed) {
+               if (sjcd_load_response(&info, sizeof(info)) != 0) {
+                       printk
+                           ("SJCD: cannot load response about disk size.\n");
+                       return (-1);
+               }
+               sjcd_disk_length.min = info.un.track_msf.min;
+               sjcd_disk_length.sec = info.un.track_msf.sec;
+               sjcd_disk_length.frame = info.un.track_msf.frame;
+       } else {
+               printk("SJCD: get size failed\n");
+               return (1);
+       }
 #if defined( SJCD_TRACE )
-  printk( "SJCD: (%02x:%02x.%02x)\n", sjcd_disk_length.min,
-        sjcd_disk_length.sec, sjcd_disk_length.frame );
+       printk("SJCD: (%02x:%02x.%02x)\n", sjcd_disk_length.min,
+              sjcd_disk_length.sec, sjcd_disk_length.frame);
 #endif
-  return( 0 );
+       return (0);
 }
 
 /*
  * Load subchannel information.
  */
-static int sjcd_get_q_info( struct sjcd_hw_qinfo *qp ){
-  int s;
+static int sjcd_get_q_info(struct sjcd_hw_qinfo *qp)
+{
+       int s;
 #if defined( SJCD_TRACE )
-  printk( "SJCD: load sub q\n" );
-#endif
-  sjcd_send_cmd( SCMD_GET_QINFO );
-  s = sjcd_receive_status();
-  if( s < 0 || sjcd_command_failed || !sjcd_status_valid ){
-    sjcd_send_cmd( 0xF2 );
-    s = sjcd_receive_status();
-    if( s < 0 || sjcd_command_failed || !sjcd_status_valid ) return( -1 );
-    sjcd_send_cmd( SCMD_GET_QINFO );
-    s = sjcd_receive_status();
-    if( s < 0 || sjcd_command_failed || !sjcd_status_valid ) return( -1 );
-  }
-  if( sjcd_media_is_available )
-    if( sjcd_load_response( qp, sizeof( *qp ) ) == 0 ) return( 0 );
-  return( -1 );
+       printk("SJCD: load sub q\n");
+#endif
+       sjcd_send_cmd(SCMD_GET_QINFO);
+       s = sjcd_receive_status();
+       if (s < 0 || sjcd_command_failed || !sjcd_status_valid) {
+               sjcd_send_cmd(0xF2);
+               s = sjcd_receive_status();
+               if (s < 0 || sjcd_command_failed || !sjcd_status_valid)
+                       return (-1);
+               sjcd_send_cmd(SCMD_GET_QINFO);
+               s = sjcd_receive_status();
+               if (s < 0 || sjcd_command_failed || !sjcd_status_valid)
+                       return (-1);
+       }
+       if (sjcd_media_is_available)
+               if (sjcd_load_response(qp, sizeof(*qp)) == 0)
+                       return (0);
+       return (-1);
 }
 
 /*
  * Start playing from the specified position.
  */
-static int sjcd_play( struct sjcd_play_msf *mp ){
-  struct sjcd_play_msf msf;
-
-  /*
-   * Turn the device to play mode.
-   */
-  sjcd_send_1_cmd( SCMD_SET_MODE, SCMD_MODE_PLAY );
-  if( sjcd_receive_status() < 0 ) return( -1 );
-
-  /*
-   * Seek to the starting point.
-   */
-  msf.start = mp->start;
-  msf.end.min = msf.end.sec = msf.end.frame = 0x00;
-  sjcd_send_6_cmd( SCMD_SEEK, &msf );
-  if( sjcd_receive_status() < 0 ) return( -1 );
-
-  /*
-   * Start playing.
-   */
-  sjcd_send_6_cmd( SCMD_PLAY, mp );
-  return( sjcd_receive_status() );
+static int sjcd_play(struct sjcd_play_msf *mp)
+{
+       struct sjcd_play_msf msf;
+
+       /*
+        * Turn the device to play mode.
+        */
+       sjcd_send_1_cmd(SCMD_SET_MODE, SCMD_MODE_PLAY);
+       if (sjcd_receive_status() < 0)
+               return (-1);
+
+       /*
+        * Seek to the starting point.
+        */
+       msf.start = mp->start;
+       msf.end.min = msf.end.sec = msf.end.frame = 0x00;
+       sjcd_send_6_cmd(SCMD_SEEK, &msf);
+       if (sjcd_receive_status() < 0)
+               return (-1);
+
+       /*
+        * Start playing.
+        */
+       sjcd_send_6_cmd(SCMD_PLAY, mp);
+       return (sjcd_receive_status());
 }
 
 /*
  * Tray control functions.
  */
-static int sjcd_tray_close( void ){
+static int sjcd_tray_close(void)
+{
 #if defined( SJCD_TRACE )
-  printk( "SJCD: tray_close\n" );
+       printk("SJCD: tray_close\n");
 #endif
-  sjcd_send_cmd( SCMD_CLOSE_TRAY );
-  return( sjcd_receive_status() );
+       sjcd_send_cmd(SCMD_CLOSE_TRAY);
+       return (sjcd_receive_status());
 }
 
-static int sjcd_tray_lock( void ){
+static int sjcd_tray_lock(void)
+{
 #if defined( SJCD_TRACE )
-  printk( "SJCD: tray_lock\n" );
+       printk("SJCD: tray_lock\n");
 #endif
-  sjcd_send_cmd( SCMD_LOCK_TRAY );
-  return( sjcd_receive_status() );
+       sjcd_send_cmd(SCMD_LOCK_TRAY);
+       return (sjcd_receive_status());
 }
 
-static int sjcd_tray_unlock( void ){
+static int sjcd_tray_unlock(void)
+{
 #if defined( SJCD_TRACE )
-  printk( "SJCD: tray_unlock\n" );
+       printk("SJCD: tray_unlock\n");
 #endif
-  sjcd_send_cmd( SCMD_UNLOCK_TRAY );
-  return( sjcd_receive_status() );
+       sjcd_send_cmd(SCMD_UNLOCK_TRAY);
+       return (sjcd_receive_status());
 }
 
-static int sjcd_tray_open( void ){
+static int sjcd_tray_open(void)
+{
 #if defined( SJCD_TRACE )
-  printk( "SJCD: tray_open\n" );
+       printk("SJCD: tray_open\n");
 #endif
-  sjcd_send_cmd( SCMD_EJECT_TRAY );
-  return( sjcd_receive_status() );
+       sjcd_send_cmd(SCMD_EJECT_TRAY);
+       return (sjcd_receive_status());
 }
 
 /*
  * Do some user commands.
  */
-static int sjcd_ioctl( struct inode *ip, struct file *fp,
-                      unsigned int cmd, unsigned long arg ){
+static int sjcd_ioctl(struct inode *ip, struct file *fp,
+                     unsigned int cmd, unsigned long arg)
+{
 #if defined( SJCD_TRACE )
-  printk( "SJCD:ioctl\n" );
+       printk("SJCD:ioctl\n");
 #endif
 
-  if( ip == NULL ) return( -EINVAL );
+       if (ip == NULL)
+               return (-EINVAL);
 
-  sjcd_get_status();
-  if( !sjcd_status_valid ) return( -EIO );
-  if( sjcd_update_toc() < 0 ) return( -EIO );
+       sjcd_get_status();
+       if (!sjcd_status_valid)
+               return (-EIO);
+       if (sjcd_update_toc() < 0)
+               return (-EIO);
 
-  switch( cmd ){
-  case CDROMSTART:{
+       switch (cmd) {
+       case CDROMSTART:{
 #if defined( SJCD_TRACE )
-    printk( "SJCD: ioctl: start\n" );
+                       printk("SJCD: ioctl: start\n");
 #endif
-    return( 0 );
-  }
+                       return (0);
+               }
 
-  case CDROMSTOP:{
+       case CDROMSTOP:{
 #if defined( SJCD_TRACE )
-    printk( "SJCD: ioctl: stop\n" );
+                       printk("SJCD: ioctl: stop\n");
 #endif
-    sjcd_send_cmd( SCMD_PAUSE );
-    ( void )sjcd_receive_status();
-    sjcd_audio_status = CDROM_AUDIO_NO_STATUS;
-    return( 0 );
-  }
+                       sjcd_send_cmd(SCMD_PAUSE);
+                       (void) sjcd_receive_status();
+                       sjcd_audio_status = CDROM_AUDIO_NO_STATUS;
+                       return (0);
+               }
 
-  case CDROMPAUSE:{
-    struct sjcd_hw_qinfo q_info;
+       case CDROMPAUSE:{
+                       struct sjcd_hw_qinfo q_info;
 #if defined( SJCD_TRACE )
-    printk( "SJCD: ioctl: pause\n" );
-#endif
-    if( sjcd_audio_status == CDROM_AUDIO_PLAY ){
-      sjcd_send_cmd( SCMD_PAUSE );
-      ( void )sjcd_receive_status();
-      if( sjcd_get_q_info( &q_info ) < 0 ){
-       sjcd_audio_status = CDROM_AUDIO_NO_STATUS;
-      } else {
-       sjcd_audio_status = CDROM_AUDIO_PAUSED;
-       sjcd_playing.start = q_info.abs;
-      }
-      return( 0 );
-    } else return( -EINVAL );
-  }
-
-  case CDROMRESUME:{
+                       printk("SJCD: ioctl: pause\n");
+#endif
+                       if (sjcd_audio_status == CDROM_AUDIO_PLAY) {
+                               sjcd_send_cmd(SCMD_PAUSE);
+                               (void) sjcd_receive_status();
+                               if (sjcd_get_q_info(&q_info) < 0) {
+                                       sjcd_audio_status =
+                                           CDROM_AUDIO_NO_STATUS;
+                               } else {
+                                       sjcd_audio_status =
+                                           CDROM_AUDIO_PAUSED;
+                                       sjcd_playing.start = q_info.abs;
+                               }
+                               return (0);
+                       } else
+                               return (-EINVAL);
+               }
+
+       case CDROMRESUME:{
 #if defined( SJCD_TRACE )
-    printk( "SJCD: ioctl: resume\n" );
-#endif
-    if( sjcd_audio_status == CDROM_AUDIO_PAUSED ){
-      /*
-       * continue play starting at saved location
-       */
-      if( sjcd_play( &sjcd_playing ) < 0 ){
-       sjcd_audio_status = CDROM_AUDIO_ERROR;
-       return( -EIO );
-      } else {
-       sjcd_audio_status = CDROM_AUDIO_PLAY;
-       return( 0 );
-      }
-    } else return( -EINVAL );
-  }
-
-  case CDROMPLAYTRKIND:{
-    struct cdrom_ti ti; int s;
+                       printk("SJCD: ioctl: resume\n");
+#endif
+                       if (sjcd_audio_status == CDROM_AUDIO_PAUSED) {
+                               /*
+                                * continue play starting at saved location
+                                */
+                               if (sjcd_play(&sjcd_playing) < 0) {
+                                       sjcd_audio_status =
+                                           CDROM_AUDIO_ERROR;
+                                       return (-EIO);
+                               } else {
+                                       sjcd_audio_status =
+                                           CDROM_AUDIO_PLAY;
+                                       return (0);
+                               }
+                       } else
+                               return (-EINVAL);
+               }
+
+       case CDROMPLAYTRKIND:{
+                       struct cdrom_ti ti;
+                       int s;
 #if defined( SJCD_TRACE )
-    printk( "SJCD: ioctl: playtrkind\n" );
-#endif
-    if( ( s = verify_area( VERIFY_READ, (void *)arg, sizeof( ti ) ) ) == 0 ){
-      copy_from_user( &ti, (void *)arg, sizeof( ti ) );
-
-      if( ti.cdti_trk0 < sjcd_first_track_no ) return( -EINVAL );
-      if( ti.cdti_trk1 > sjcd_last_track_no )
-       ti.cdti_trk1 = sjcd_last_track_no;
-      if( ti.cdti_trk0 > ti.cdti_trk1 ) return( -EINVAL );
-
-      sjcd_playing.start = sjcd_table_of_contents[ ti.cdti_trk0 ].un.track_msf;
-      sjcd_playing.end = ( ti.cdti_trk1 < sjcd_last_track_no ) ?
-       sjcd_table_of_contents[ ti.cdti_trk1 + 1 ].un.track_msf :
-         sjcd_table_of_contents[ 0 ].un.track_msf;
-      
-      if( sjcd_play( &sjcd_playing ) < 0 ){
-       sjcd_audio_status = CDROM_AUDIO_ERROR;
-       return( -EIO );
-      } else sjcd_audio_status = CDROM_AUDIO_PLAY;
-    }
-    return( s );
-  }
-
-  case CDROMPLAYMSF:{
-    struct cdrom_msf sjcd_msf; int s;
+                       printk("SJCD: ioctl: playtrkind\n");
+#endif
+                       if ((s =
+                            verify_area(VERIFY_READ, (void *) arg,
+                                        sizeof(ti))) == 0) {
+                               copy_from_user(&ti, (void *) arg,
+                                              sizeof(ti));
+
+                               if (ti.cdti_trk0 < sjcd_first_track_no)
+                                       return (-EINVAL);
+                               if (ti.cdti_trk1 > sjcd_last_track_no)
+                                       ti.cdti_trk1 = sjcd_last_track_no;
+                               if (ti.cdti_trk0 > ti.cdti_trk1)
+                                       return (-EINVAL);
+
+                               sjcd_playing.start =
+                                   sjcd_table_of_contents[ti.cdti_trk0].
+                                   un.track_msf;
+                               sjcd_playing.end =
+                                   (ti.cdti_trk1 <
+                                    sjcd_last_track_no) ?
+                                   sjcd_table_of_contents[ti.cdti_trk1 +
+                                                          1].un.
+                                   track_msf : sjcd_table_of_contents[0].
+                                   un.track_msf;
+
+                               if (sjcd_play(&sjcd_playing) < 0) {
+                                       sjcd_audio_status =
+                                           CDROM_AUDIO_ERROR;
+                                       return (-EIO);
+                               } else
+                                       sjcd_audio_status =
+                                           CDROM_AUDIO_PLAY;
+                       }
+                       return (s);
+               }
+
+       case CDROMPLAYMSF:{
+                       struct cdrom_msf sjcd_msf;
+                       int s;
 #if defined( SJCD_TRACE )
-    printk( "SJCD: ioctl: playmsf\n" );
-#endif
-    if( ( s = verify_area( VERIFY_READ, (void *)arg, sizeof( sjcd_msf ) ) ) == 0 ){
-      if( sjcd_audio_status == CDROM_AUDIO_PLAY ){
-       sjcd_send_cmd( SCMD_PAUSE );
-       ( void )sjcd_receive_status();
-       sjcd_audio_status = CDROM_AUDIO_NO_STATUS;
-      }
-
-      copy_from_user( &sjcd_msf, (void *)arg, sizeof( sjcd_msf ) );
-
-      sjcd_playing.start.min = bin2bcd( sjcd_msf.cdmsf_min0 );
-      sjcd_playing.start.sec = bin2bcd( sjcd_msf.cdmsf_sec0 );
-      sjcd_playing.start.frame = bin2bcd( sjcd_msf.cdmsf_frame0 );
-      sjcd_playing.end.min = bin2bcd( sjcd_msf.cdmsf_min1 );
-      sjcd_playing.end.sec = bin2bcd( sjcd_msf.cdmsf_sec1 );
-      sjcd_playing.end.frame = bin2bcd( sjcd_msf.cdmsf_frame1 );
-
-      if( sjcd_play( &sjcd_playing ) < 0 ){
-       sjcd_audio_status = CDROM_AUDIO_ERROR;
-       return( -EIO );
-      } else sjcd_audio_status = CDROM_AUDIO_PLAY;
-    }
-    return( s );
-  }
-
-  case CDROMREADTOCHDR:{
-    struct cdrom_tochdr toc_header; int s;
+                       printk("SJCD: ioctl: playmsf\n");
+#endif
+                       if ((s =
+                            verify_area(VERIFY_READ, (void *) arg,
+                                        sizeof(sjcd_msf))) == 0) {
+                               if (sjcd_audio_status == CDROM_AUDIO_PLAY) {
+                                       sjcd_send_cmd(SCMD_PAUSE);
+                                       (void) sjcd_receive_status();
+                                       sjcd_audio_status =
+                                           CDROM_AUDIO_NO_STATUS;
+                               }
+
+                               copy_from_user(&sjcd_msf, (void *) arg,
+                                              sizeof(sjcd_msf));
+
+                               sjcd_playing.start.min =
+                                   bin2bcd(sjcd_msf.cdmsf_min0);
+                               sjcd_playing.start.sec =
+                                   bin2bcd(sjcd_msf.cdmsf_sec0);
+                               sjcd_playing.start.frame =
+                                   bin2bcd(sjcd_msf.cdmsf_frame0);
+                               sjcd_playing.end.min =
+                                   bin2bcd(sjcd_msf.cdmsf_min1);
+                               sjcd_playing.end.sec =
+                                   bin2bcd(sjcd_msf.cdmsf_sec1);
+                               sjcd_playing.end.frame =
+                                   bin2bcd(sjcd_msf.cdmsf_frame1);
+
+                               if (sjcd_play(&sjcd_playing) < 0) {
+                                       sjcd_audio_status =
+                                           CDROM_AUDIO_ERROR;
+                                       return (-EIO);
+                               } else
+                                       sjcd_audio_status =
+                                           CDROM_AUDIO_PLAY;
+                       }
+                       return (s);
+               }
+
+       case CDROMREADTOCHDR:{
+                       struct cdrom_tochdr toc_header;
+                       int s;
 #if defined (SJCD_TRACE )
-    printk( "SJCD: ioctl: readtocheader\n" );
-#endif
-    if( ( s = verify_area( VERIFY_WRITE, (void *)arg, sizeof( toc_header ) ) ) == 0 ){
-      toc_header.cdth_trk0 = sjcd_first_track_no;
-      toc_header.cdth_trk1 = sjcd_last_track_no;
-      copy_to_user( (void *)arg, &toc_header, sizeof( toc_header ) );
-    }
-    return( s );
-  }
-
-  case CDROMREADTOCENTRY:{
-    struct cdrom_tocentry toc_entry; int s;
+                       printk("SJCD: ioctl: readtocheader\n");
+#endif
+                       if ((s =
+                            verify_area(VERIFY_WRITE, (void *) arg,
+                                        sizeof(toc_header))) == 0) {
+                               toc_header.cdth_trk0 = sjcd_first_track_no;
+                               toc_header.cdth_trk1 = sjcd_last_track_no;
+                               copy_to_user((void *) arg, &toc_header,
+                                            sizeof(toc_header));
+                       }
+                       return (s);
+               }
+
+       case CDROMREADTOCENTRY:{
+                       struct cdrom_tocentry toc_entry;
+                       int s;
 #if defined( SJCD_TRACE )
-    printk( "SJCD: ioctl: readtocentry\n" );
-#endif
-    if( ( s = verify_area( VERIFY_WRITE, (void *)arg, sizeof( toc_entry ) ) ) == 0 ){
-      struct sjcd_hw_disk_info *tp;
-
-      copy_from_user( &toc_entry, (void *)arg, sizeof( toc_entry ) );
-
-      if( toc_entry.cdte_track == CDROM_LEADOUT )
-       tp = &sjcd_table_of_contents[ 0 ];
-      else if( toc_entry.cdte_track < sjcd_first_track_no ) return( -EINVAL );
-      else if( toc_entry.cdte_track > sjcd_last_track_no ) return( -EINVAL );
-      else tp = &sjcd_table_of_contents[ toc_entry.cdte_track ];
-
-      toc_entry.cdte_adr = tp->track_control & 0x0F;
-      toc_entry.cdte_ctrl = tp->track_control >> 4;
-
-      switch( toc_entry.cdte_format ){
-      case CDROM_LBA:
-       toc_entry.cdte_addr.lba = msf2hsg( &( tp->un.track_msf ) );
-       break;
-      case CDROM_MSF:
-       toc_entry.cdte_addr.msf.minute = bcd2bin( tp->un.track_msf.min );
-       toc_entry.cdte_addr.msf.second = bcd2bin( tp->un.track_msf.sec );
-       toc_entry.cdte_addr.msf.frame = bcd2bin( tp->un.track_msf.frame );
-       break;
-      default: return( -EINVAL );
-      }
-      copy_to_user( (void *)arg, &toc_entry, sizeof( toc_entry ) );
-    }
-    return( s );
-  }
-
-  case CDROMSUBCHNL:{
-    struct cdrom_subchnl subchnl; int s;
+                       printk("SJCD: ioctl: readtocentry\n");
+#endif
+                       if ((s =
+                            verify_area(VERIFY_WRITE, (void *) arg,
+                                        sizeof(toc_entry))) == 0) {
+                               struct sjcd_hw_disk_info *tp;
+
+                               copy_from_user(&toc_entry, (void *) arg,
+                                              sizeof(toc_entry));
+
+                               if (toc_entry.cdte_track == CDROM_LEADOUT)
+                                       tp = &sjcd_table_of_contents[0];
+                               else if (toc_entry.cdte_track <
+                                        sjcd_first_track_no)
+                                       return (-EINVAL);
+                               else if (toc_entry.cdte_track >
+                                        sjcd_last_track_no)
+                                       return (-EINVAL);
+                               else
+                                       tp = &sjcd_table_of_contents
+                                           [toc_entry.cdte_track];
+
+                               toc_entry.cdte_adr =
+                                   tp->track_control & 0x0F;
+                               toc_entry.cdte_ctrl =
+                                   tp->track_control >> 4;
+
+                               switch (toc_entry.cdte_format) {
+                               case CDROM_LBA:
+                                       toc_entry.cdte_addr.lba =
+                                           msf2hsg(&(tp->un.track_msf));
+                                       break;
+                               case CDROM_MSF:
+                                       toc_entry.cdte_addr.msf.minute =
+                                           bcd2bin(tp->un.track_msf.min);
+                                       toc_entry.cdte_addr.msf.second =
+                                           bcd2bin(tp->un.track_msf.sec);
+                                       toc_entry.cdte_addr.msf.frame =
+                                           bcd2bin(tp->un.track_msf.
+                                                   frame);
+                                       break;
+                               default:
+                                       return (-EINVAL);
+                               }
+                               copy_to_user((void *) arg, &toc_entry,
+                                            sizeof(toc_entry));
+                       }
+                       return (s);
+               }
+
+       case CDROMSUBCHNL:{
+                       struct cdrom_subchnl subchnl;
+                       int s;
 #if defined( SJCD_TRACE )
-    printk( "SJCD: ioctl: subchnl\n" );
-#endif
-    if( ( s = verify_area( VERIFY_WRITE, (void *)arg, sizeof( subchnl ) ) ) == 0 ){
-      struct sjcd_hw_qinfo q_info;
-
-      copy_from_user( &subchnl, (void *)arg, sizeof( subchnl ) );
-      if( sjcd_get_q_info( &q_info ) < 0 ) return( -EIO );
-
-      subchnl.cdsc_audiostatus = sjcd_audio_status;
-      subchnl.cdsc_adr = q_info.track_control & 0x0F;
-      subchnl.cdsc_ctrl = q_info.track_control >> 4;
-      subchnl.cdsc_trk = bcd2bin( q_info.track_no );
-      subchnl.cdsc_ind = bcd2bin( q_info.x );
-
-      switch( subchnl.cdsc_format ){
-      case CDROM_LBA:
-       subchnl.cdsc_absaddr.lba = msf2hsg( &( q_info.abs ) );
-       subchnl.cdsc_reladdr.lba = msf2hsg( &( q_info.rel ) );
-       break;
-      case CDROM_MSF:
-       subchnl.cdsc_absaddr.msf.minute = bcd2bin( q_info.abs.min );
-       subchnl.cdsc_absaddr.msf.second = bcd2bin( q_info.abs.sec );
-       subchnl.cdsc_absaddr.msf.frame = bcd2bin( q_info.abs.frame );
-       subchnl.cdsc_reladdr.msf.minute = bcd2bin( q_info.rel.min );
-       subchnl.cdsc_reladdr.msf.second = bcd2bin( q_info.rel.sec );
-       subchnl.cdsc_reladdr.msf.frame = bcd2bin( q_info.rel.frame );
-       break;
-      default: return( -EINVAL );
-      }
-      copy_to_user( (void *)arg, &subchnl, sizeof( subchnl ) );
-    }
-    return( s );
-  }
-
-  case CDROMVOLCTRL:{
-    struct cdrom_volctrl vol_ctrl; int s;
+                       printk("SJCD: ioctl: subchnl\n");
+#endif
+                       if ((s =
+                            verify_area(VERIFY_WRITE, (void *) arg,
+                                        sizeof(subchnl))) == 0) {
+                               struct sjcd_hw_qinfo q_info;
+
+                               copy_from_user(&subchnl, (void *) arg,
+                                              sizeof(subchnl));
+                               if (sjcd_get_q_info(&q_info) < 0)
+                                       return (-EIO);
+
+                               subchnl.cdsc_audiostatus =
+                                   sjcd_audio_status;
+                               subchnl.cdsc_adr =
+                                   q_info.track_control & 0x0F;
+                               subchnl.cdsc_ctrl =
+                                   q_info.track_control >> 4;
+                               subchnl.cdsc_trk =
+                                   bcd2bin(q_info.track_no);
+                               subchnl.cdsc_ind = bcd2bin(q_info.x);
+
+                               switch (subchnl.cdsc_format) {
+                               case CDROM_LBA:
+                                       subchnl.cdsc_absaddr.lba =
+                                           msf2hsg(&(q_info.abs));
+                                       subchnl.cdsc_reladdr.lba =
+                                           msf2hsg(&(q_info.rel));
+                                       break;
+                               case CDROM_MSF:
+                                       subchnl.cdsc_absaddr.msf.minute =
+                                           bcd2bin(q_info.abs.min);
+                                       subchnl.cdsc_absaddr.msf.second =
+                                           bcd2bin(q_info.abs.sec);
+                                       subchnl.cdsc_absaddr.msf.frame =
+                                           bcd2bin(q_info.abs.frame);
+                                       subchnl.cdsc_reladdr.msf.minute =
+                                           bcd2bin(q_info.rel.min);
+                                       subchnl.cdsc_reladdr.msf.second =
+                                           bcd2bin(q_info.rel.sec);
+                                       subchnl.cdsc_reladdr.msf.frame =
+                                           bcd2bin(q_info.rel.frame);
+                                       break;
+                               default:
+                                       return (-EINVAL);
+                               }
+                               copy_to_user((void *) arg, &subchnl,
+                                            sizeof(subchnl));
+                       }
+                       return (s);
+               }
+
+       case CDROMVOLCTRL:{
+                       struct cdrom_volctrl vol_ctrl;
+                       int s;
 #if defined( SJCD_TRACE )
-    printk( "SJCD: ioctl: volctrl\n" );
-#endif
-    if( ( s = verify_area( VERIFY_READ, (void *)arg, sizeof( vol_ctrl ) ) ) == 0 ){
-      unsigned char dummy[ 4 ];
-
-      copy_from_user( &vol_ctrl, (void *)arg, sizeof( vol_ctrl ) );
-      sjcd_send_4_cmd( SCMD_SET_VOLUME, vol_ctrl.channel0, 0xFF,
-                     vol_ctrl.channel1, 0xFF );
-      if( sjcd_receive_status() < 0 ) return( -EIO );
-      ( void )sjcd_load_response( dummy, 4 );
-    }
-    return( s );
-  }
-
-  case CDROMEJECT:{
+                       printk("SJCD: ioctl: volctrl\n");
+#endif
+                       if ((s =
+                            verify_area(VERIFY_READ, (void *) arg,
+                                        sizeof(vol_ctrl))) == 0) {
+                               unsigned char dummy[4];
+
+                               copy_from_user(&vol_ctrl, (void *) arg,
+                                              sizeof(vol_ctrl));
+                               sjcd_send_4_cmd(SCMD_SET_VOLUME,
+                                               vol_ctrl.channel0, 0xFF,
+                                               vol_ctrl.channel1, 0xFF);
+                               if (sjcd_receive_status() < 0)
+                                       return (-EIO);
+                               (void) sjcd_load_response(dummy, 4);
+                       }
+                       return (s);
+               }
+
+       case CDROMEJECT:{
 #if defined( SJCD_TRACE )
-    printk( "SJCD: ioctl: eject\n" );
+                       printk("SJCD: ioctl: eject\n");
 #endif
-    if( !sjcd_command_is_in_progress ){
-      sjcd_tray_unlock();
-      sjcd_send_cmd( SCMD_EJECT_TRAY );
-      ( void )sjcd_receive_status();
-    }
-    return( 0 );
-  }
+                       if (!sjcd_command_is_in_progress) {
+                               sjcd_tray_unlock();
+                               sjcd_send_cmd(SCMD_EJECT_TRAY);
+                               (void) sjcd_receive_status();
+                       }
+                       return (0);
+               }
 
 #if defined( SJCD_GATHER_STAT )
-  case 0xABCD:{
-    int s;
+       case 0xABCD:{
+                       int s;
 #if defined( SJCD_TRACE )
-    printk( "SJCD: ioctl: statistic\n" );
+                       printk("SJCD: ioctl: statistic\n");
 #endif
-    if( ( s = verify_area( VERIFY_WRITE, (void *)arg, sizeof( statistic ) ) ) == 0 )
-      copy_to_user( (void *)arg, &statistic, sizeof( statistic ) );
-    return( s );
-  }
+                       if ((s =
+                            verify_area(VERIFY_WRITE, (void *) arg,
+                                        sizeof(statistic))) == 0)
+                               copy_to_user((void *) arg, &statistic,
+                                            sizeof(statistic));
+                       return (s);
+               }
 #endif
 
-  default:
-    return( -EINVAL );
-  }
+       default:
+               return (-EINVAL);
+       }
 }
 
 /*
  * Invalidate internal buffers of the driver.
  */
-static void sjcd_invalidate_buffers( void ){
-  int i;
-  for( i = 0; i < SJCD_BUF_SIZ; sjcd_buf_bn[ i++ ] = -1 );
-  sjcd_buf_out = -1;
+static void sjcd_invalidate_buffers(void)
+{
+       int i;
+       for (i = 0; i < SJCD_BUF_SIZ; sjcd_buf_bn[i++] = -1);
+       sjcd_buf_out = -1;
 }
 
 /*
@@ -939,508 +1077,595 @@ static void sjcd_invalidate_buffers( void ){
     ( !QUEUE_EMPTY && MAJOR( CURRENT->rq_dev ) == MAJOR_NR && \
       CURRENT->cmd == READ && CURRENT->sector != -1 )
 
-static void sjcd_transfer( void ){
+static void sjcd_transfer(void)
+{
 #if defined( SJCD_TRACE )
-  printk( "SJCD: transfer:\n" );
-#endif
-  if( CURRENT_IS_VALID ){
-    while( CURRENT->nr_sectors ){
-      int i, bn = CURRENT->sector / 4;
-      for( i = 0; i < SJCD_BUF_SIZ && sjcd_buf_bn[ i ] != bn; i++ );
-      if( i < SJCD_BUF_SIZ ){
-       int offs = ( i * 4 + ( CURRENT->sector & 3 ) ) * 512;
-       int nr_sectors = 4 - ( CURRENT->sector & 3 );
-       if( sjcd_buf_out != i ){
-         sjcd_buf_out = i;
-         if( sjcd_buf_bn[ i ] != bn ){
-           sjcd_buf_out = -1;
-           continue;
-         }
-       }
-       if( nr_sectors > CURRENT->nr_sectors )
-         nr_sectors = CURRENT->nr_sectors;
+       printk("SJCD: transfer:\n");
+#endif
+       if (CURRENT_IS_VALID) {
+               while (CURRENT->nr_sectors) {
+                       int i, bn = CURRENT->sector / 4;
+                       for (i = 0;
+                            i < SJCD_BUF_SIZ && sjcd_buf_bn[i] != bn;
+                            i++);
+                       if (i < SJCD_BUF_SIZ) {
+                               int offs =
+                                   (i * 4 + (CURRENT->sector & 3)) * 512;
+                               int nr_sectors = 4 - (CURRENT->sector & 3);
+                               if (sjcd_buf_out != i) {
+                                       sjcd_buf_out = i;
+                                       if (sjcd_buf_bn[i] != bn) {
+                                               sjcd_buf_out = -1;
+                                               continue;
+                                       }
+                               }
+                               if (nr_sectors > CURRENT->nr_sectors)
+                                       nr_sectors = CURRENT->nr_sectors;
 #if defined( SJCD_TRACE )
-       printk( "SJCD: copy out\n" );
-#endif
-       memcpy( CURRENT->buffer, sjcd_buf + offs, nr_sectors * 512 );
-       CURRENT->nr_sectors -= nr_sectors;
-       CURRENT->sector += nr_sectors;
-       CURRENT->buffer += nr_sectors * 512;
-      } else {
-       sjcd_buf_out = -1;
-       break;
-      }
-    }
-  }
+                               printk("SJCD: copy out\n");
+#endif
+                               memcpy(CURRENT->buffer, sjcd_buf + offs,
+                                      nr_sectors * 512);
+                               CURRENT->nr_sectors -= nr_sectors;
+                               CURRENT->sector += nr_sectors;
+                               CURRENT->buffer += nr_sectors * 512;
+                       } else {
+                               sjcd_buf_out = -1;
+                               break;
+                       }
+               }
+       }
 #if defined( SJCD_TRACE )
-  printk( "SJCD: transfer: done\n" );
+       printk("SJCD: transfer: done\n");
 #endif
 }
 
-static void sjcd_poll( void ){
+static void sjcd_poll(void)
+{
 #if defined( SJCD_GATHER_STAT )
-  /*
-   * Update total number of ticks.
-   */
-  statistic.ticks++;
-  statistic.tticks[ sjcd_transfer_state ]++;
+       /*
+        * Update total number of ticks.
+        */
+       statistic.ticks++;
+       statistic.tticks[sjcd_transfer_state]++;
 #endif
 
ReSwitch: switch( sjcd_transfer_state ){
-      
-  case SJCD_S_IDLE:{
     ReSwitch:switch (sjcd_transfer_state) {
+
+       case SJCD_S_IDLE:{
 #if defined( SJCD_GATHER_STAT )
-    statistic.idle_ticks++;
+                       statistic.idle_ticks++;
 #endif
 #if defined( SJCD_TRACE )
-    printk( "SJCD_S_IDLE\n" );
+                       printk("SJCD_S_IDLE\n");
 #endif
-    return;
-  }
+                       return;
+               }
 
-  case SJCD_S_START:{
+       case SJCD_S_START:{
 #if defined( SJCD_GATHER_STAT )
-    statistic.start_ticks++;
+                       statistic.start_ticks++;
 #endif
-    sjcd_send_cmd( SCMD_GET_STATUS );
-    sjcd_transfer_state =
-      sjcd_mode == SCMD_MODE_COOKED ? SJCD_S_READ : SJCD_S_MODE;
-    sjcd_transfer_timeout = 500;
+                       sjcd_send_cmd(SCMD_GET_STATUS);
+                       sjcd_transfer_state =
+                           sjcd_mode ==
+                           SCMD_MODE_COOKED ? SJCD_S_READ : SJCD_S_MODE;
+                       sjcd_transfer_timeout = 500;
 #if defined( SJCD_TRACE )
-    printk( "SJCD_S_START: goto SJCD_S_%s mode\n",
-          sjcd_transfer_state == SJCD_S_READ ? "READ" : "MODE" );
-#endif
-    break;
-  }
-    
-  case SJCD_S_MODE:{
-    if( sjcd_check_status() ){
-      /*
-       * Previous command is completed.
-       */
-      if( !sjcd_status_valid || sjcd_command_failed ){
+                       printk("SJCD_S_START: goto SJCD_S_%s mode\n",
+                              sjcd_transfer_state ==
+                              SJCD_S_READ ? "READ" : "MODE");
+#endif
+                       break;
+               }
+
+       case SJCD_S_MODE:{
+                       if (sjcd_check_status()) {
+                               /*
+                                * Previous command is completed.
+                                */
+                               if (!sjcd_status_valid
+                                   || sjcd_command_failed) {
 #if defined( SJCD_TRACE )
-       printk( "SJCD_S_MODE: pre-cmd failed: goto to SJCD_S_STOP mode\n" );
-#endif
-       sjcd_transfer_state = SJCD_S_STOP;
-       goto ReSwitch;
-      }
-
-      sjcd_mode = 0; /* unknown mode; should not be valid when failed */
-      sjcd_send_1_cmd( SCMD_SET_MODE, SCMD_MODE_COOKED );
-      sjcd_transfer_state = SJCD_S_READ; sjcd_transfer_timeout = 1000;
+                                       printk
+                                           ("SJCD_S_MODE: pre-cmd failed: goto to SJCD_S_STOP mode\n");
+#endif
+                                       sjcd_transfer_state = SJCD_S_STOP;
+                                       goto ReSwitch;
+                               }
+
+                               sjcd_mode = 0;  /* unknown mode; should not be valid when failed */
+                               sjcd_send_1_cmd(SCMD_SET_MODE,
+                                               SCMD_MODE_COOKED);
+                               sjcd_transfer_state = SJCD_S_READ;
+                               sjcd_transfer_timeout = 1000;
 #if defined( SJCD_TRACE )
-      printk( "SJCD_S_MODE: goto SJCD_S_READ mode\n" );
+                               printk
+                                   ("SJCD_S_MODE: goto SJCD_S_READ mode\n");
 #endif
-    }
+                       }
 #if defined( SJCD_GATHER_STAT )
-    else statistic.mode_ticks++;
-#endif
-    break;
-  }
-
-  case SJCD_S_READ:{
-    if( sjcd_status_valid ? 1 : sjcd_check_status() ){
-      /*
-       * Previous command is completed.
-       */
-      if( !sjcd_status_valid || sjcd_command_failed ){
+                       else
+                               statistic.mode_ticks++;
+#endif
+                       break;
+               }
+
+       case SJCD_S_READ:{
+                       if (sjcd_status_valid ? 1 : sjcd_check_status()) {
+                               /*
+                                * Previous command is completed.
+                                */
+                               if (!sjcd_status_valid
+                                   || sjcd_command_failed) {
 #if defined( SJCD_TRACE )
-       printk( "SJCD_S_READ: pre-cmd failed: goto to SJCD_S_STOP mode\n" );
+                                       printk
+                                           ("SJCD_S_READ: pre-cmd failed: goto to SJCD_S_STOP mode\n");
 #endif
-       sjcd_transfer_state = SJCD_S_STOP;
-       goto ReSwitch;
-      }
-      if( !sjcd_media_is_available ){
+                                       sjcd_transfer_state = SJCD_S_STOP;
+                                       goto ReSwitch;
+                               }
+                               if (!sjcd_media_is_available) {
 #if defined( SJCD_TRACE )
-       printk( "SJCD_S_READ: no disk: goto to SJCD_S_STOP mode\n" );
-#endif
-       sjcd_transfer_state = SJCD_S_STOP;
-       goto ReSwitch;
-      }
-      if( sjcd_mode != SCMD_MODE_COOKED ){
-       /*
-        * We seem to come from set mode. So discard one byte of result.
-        */
-       if( sjcd_load_response( &sjcd_mode, 1 ) != 0 ){
+                                       printk
+                                           ("SJCD_S_READ: no disk: goto to SJCD_S_STOP mode\n");
+#endif
+                                       sjcd_transfer_state = SJCD_S_STOP;
+                                       goto ReSwitch;
+                               }
+                               if (sjcd_mode != SCMD_MODE_COOKED) {
+                                       /*
+                                        * We seem to come from set mode. So discard one byte of result.
+                                        */
+                                       if (sjcd_load_response
+                                           (&sjcd_mode, 1) != 0) {
 #if defined( SJCD_TRACE )
-         printk( "SJCD_S_READ: load failed: goto to SJCD_S_STOP mode\n" );
-#endif
-         sjcd_transfer_state = SJCD_S_STOP;
-         goto ReSwitch;
-       }
-       if( sjcd_mode != SCMD_MODE_COOKED ){
+                                               printk
+                                                   ("SJCD_S_READ: load failed: goto to SJCD_S_STOP mode\n");
+#endif
+                                               sjcd_transfer_state =
+                                                   SJCD_S_STOP;
+                                               goto ReSwitch;
+                                       }
+                                       if (sjcd_mode != SCMD_MODE_COOKED) {
 #if defined( SJCD_TRACE )
-         printk( "SJCD_S_READ: mode failed: goto to SJCD_S_STOP mode\n" );
-#endif
-         sjcd_transfer_state = SJCD_S_STOP;
-         goto ReSwitch;
-       }
-      }
-
-      if( CURRENT_IS_VALID ){
-       struct sjcd_play_msf msf;
-
-       sjcd_next_bn = CURRENT->sector / 4;
-       hsg2msf( sjcd_next_bn, &msf.start );
-       msf.end.min = 0; msf.end.sec = 0;            
-       msf.end.frame = sjcd_read_count = SJCD_BUF_SIZ;
+                                               printk
+                                                   ("SJCD_S_READ: mode failed: goto to SJCD_S_STOP mode\n");
+#endif
+                                               sjcd_transfer_state =
+                                                   SJCD_S_STOP;
+                                               goto ReSwitch;
+                                       }
+                               }
+
+                               if (CURRENT_IS_VALID) {
+                                       struct sjcd_play_msf msf;
+
+                                       sjcd_next_bn = CURRENT->sector / 4;
+                                       hsg2msf(sjcd_next_bn, &msf.start);
+                                       msf.end.min = 0;
+                                       msf.end.sec = 0;
+                                       msf.end.frame = sjcd_read_count =
+                                           SJCD_BUF_SIZ;
 #if defined( SJCD_TRACE )
-       printk( "SJCD: ---reading msf-address %x:%x:%x  %x:%x:%x\n",
-              msf.start.min, msf.start.sec, msf.start.frame,
-              msf.end.min,   msf.end.sec,   msf.end.frame );
-       printk( "sjcd_next_bn:%x buf_in:%x buf_out:%x buf_bn:%x\n", \
-            sjcd_next_bn, sjcd_buf_in, sjcd_buf_out,
-            sjcd_buf_bn[ sjcd_buf_in ] );
-#endif 
-       sjcd_send_6_cmd( SCMD_DATA_READ, &msf );
-       sjcd_transfer_state = SJCD_S_DATA;
-       sjcd_transfer_timeout = 500;
+                                       printk
+                                           ("SJCD: ---reading msf-address %x:%x:%x  %x:%x:%x\n",
+                                            msf.start.min, msf.start.sec,
+                                            msf.start.frame, msf.end.min,
+                                            msf.end.sec, msf.end.frame);
+                                       printk
+                                           ("sjcd_next_bn:%x buf_in:%x buf_out:%x buf_bn:%x\n",
+                                            sjcd_next_bn, sjcd_buf_in,
+                                            sjcd_buf_out,
+                                            sjcd_buf_bn[sjcd_buf_in]);
+#endif
+                                       sjcd_send_6_cmd(SCMD_DATA_READ,
+                                                       &msf);
+                                       sjcd_transfer_state = SJCD_S_DATA;
+                                       sjcd_transfer_timeout = 500;
 #if defined( SJCD_TRACE )
-       printk( "SJCD_S_READ: go to SJCD_S_DATA mode\n" );
+                                       printk
+                                           ("SJCD_S_READ: go to SJCD_S_DATA mode\n");
 #endif
-      } else {
+                               } else {
 #if defined( SJCD_TRACE )
-       printk( "SJCD_S_READ: nothing to read: go to SJCD_S_STOP mode\n" );
+                                       printk
+                                           ("SJCD_S_READ: nothing to read: go to SJCD_S_STOP mode\n");
 #endif
-       sjcd_transfer_state = SJCD_S_STOP;
-       goto ReSwitch;
-      }
-    }
+                                       sjcd_transfer_state = SJCD_S_STOP;
+                                       goto ReSwitch;
+                               }
+                       }
 #if defined( SJCD_GATHER_STAT )
-    else statistic.read_ticks++;
+                       else
+                               statistic.read_ticks++;
 #endif
-    break;
-  }
+                       break;
+               }
 
-  case SJCD_S_DATA:{
-    unsigned char stat;
+       case SJCD_S_DATA:{
+                       unsigned char stat;
 
-  sjcd_s_data: stat = inb( SJCDPORT( 1 ) );
+                     sjcd_s_data:stat =
+                           inb(SJCDPORT
+                               (1));
 #if defined( SJCD_TRACE )
-    printk( "SJCD_S_DATA: status = 0x%02x\n", stat );
+                       printk("SJCD_S_DATA: status = 0x%02x\n", stat);
 #endif
-    if( SJCD_STATUS_AVAILABLE( stat ) ){
-      /*
-       * No data is waiting for us in the drive buffer. Status of operation
-       * completion is available. Read and parse it.
-       */
-      sjcd_load_status();
+                       if (SJCD_STATUS_AVAILABLE(stat)) {
+                               /*
+                                * No data is waiting for us in the drive buffer. Status of operation
+                                * completion is available. Read and parse it.
+                                */
+                               sjcd_load_status();
 
-      if( !sjcd_status_valid || sjcd_command_failed ){
+                               if (!sjcd_status_valid
+                                   || sjcd_command_failed) {
 #if defined( SJCD_TRACE )
-       printk( "SJCD: read block %d failed, maybe audio disk? Giving up\n",
-              sjcd_next_bn );
+                                       printk
+                                           ("SJCD: read block %d failed, maybe audio disk? Giving up\n",
+                                            sjcd_next_bn);
 #endif
-       if( CURRENT_IS_VALID ) end_request( 0 );
+                                       if (CURRENT_IS_VALID)
+                                               end_request(0);
 #if defined( SJCD_TRACE )
-       printk( "SJCD_S_DATA: pre-cmd failed: go to SJCD_S_STOP mode\n" );
-#endif
-       sjcd_transfer_state = SJCD_S_STOP;
-       goto ReSwitch;
-      }
-
-      if( !sjcd_media_is_available ){
-       printk( "SJCD_S_DATA: no disk: go to SJCD_S_STOP mode\n" );
-       sjcd_transfer_state = SJCD_S_STOP;
-       goto ReSwitch;
-      }
-
-      sjcd_transfer_state = SJCD_S_READ;
-      goto ReSwitch;
-    } else if( SJCD_DATA_AVAILABLE( stat ) ){
-      /*
-       * One frame is read into device buffer. We must copy it to our memory.
-       * Otherwise cdrom hangs up. Check to see if we have something to copy
-       * to.
-       */
-      if( !CURRENT_IS_VALID && sjcd_buf_in == sjcd_buf_out ){
+                                       printk
+                                           ("SJCD_S_DATA: pre-cmd failed: go to SJCD_S_STOP mode\n");
+#endif
+                                       sjcd_transfer_state = SJCD_S_STOP;
+                                       goto ReSwitch;
+                               }
+
+                               if (!sjcd_media_is_available) {
+                                       printk
+                                           ("SJCD_S_DATA: no disk: go to SJCD_S_STOP mode\n");
+                                       sjcd_transfer_state = SJCD_S_STOP;
+                                       goto ReSwitch;
+                               }
+
+                               sjcd_transfer_state = SJCD_S_READ;
+                               goto ReSwitch;
+                       } else if (SJCD_DATA_AVAILABLE(stat)) {
+                               /*
+                                * One frame is read into device buffer. We must copy it to our memory.
+                                * Otherwise cdrom hangs up. Check to see if we have something to copy
+                                * to.
+                                */
+                               if (!CURRENT_IS_VALID
+                                   && sjcd_buf_in == sjcd_buf_out) {
 #if defined( SJCD_TRACE )
-       printk( "SJCD_S_DATA: nothing to read: go to SJCD_S_STOP mode\n" );
-       printk( " ... all the date would be discarded\n" );
-#endif
-       sjcd_transfer_state = SJCD_S_STOP;
-       goto ReSwitch;
-      }
-
-      /*
-       * Everything seems to be OK. Just read the frame and recalculate
-       * indices.
-       */
-      sjcd_buf_bn[ sjcd_buf_in ] = -1; /* ??? */
-      insb( SJCDPORT( 2 ), sjcd_buf + 2048 * sjcd_buf_in, 2048 );
+                                       printk
+                                           ("SJCD_S_DATA: nothing to read: go to SJCD_S_STOP mode\n");
+                                       printk
+                                           (" ... all the date would be discarded\n");
+#endif
+                                       sjcd_transfer_state = SJCD_S_STOP;
+                                       goto ReSwitch;
+                               }
+
+                               /*
+                                * Everything seems to be OK. Just read the frame and recalculate
+                                * indices.
+                                */
+                               sjcd_buf_bn[sjcd_buf_in] = -1;  /* ??? */
+                               insb(SJCDPORT(2),
+                                    sjcd_buf + 2048 * sjcd_buf_in, 2048);
 #if defined( SJCD_TRACE )
-      printk( "SJCD_S_DATA: next_bn=%d, buf_in=%d, buf_out=%d, buf_bn=%d\n",
-            sjcd_next_bn, sjcd_buf_in, sjcd_buf_out,
-            sjcd_buf_bn[ sjcd_buf_in ] );
-#endif
-      sjcd_buf_bn[ sjcd_buf_in ] = sjcd_next_bn++;
-      if( sjcd_buf_out == -1 ) sjcd_buf_out = sjcd_buf_in;
-      if( ++sjcd_buf_in == SJCD_BUF_SIZ ) sjcd_buf_in = 0;
-
-      /*
-       * Only one frame is ready at time. So we should turn over to wait for
-       * another frame. If we need that, of course.
-       */
-      if( --sjcd_read_count == 0 ){
-       /*
-        * OK, request seems to be precessed. Continue transferring...
-        */
-       if( !sjcd_transfer_is_active ){
-         while( CURRENT_IS_VALID ){
-           /*
-            * Continue transferring.
-            */
-           sjcd_transfer();
-           if( CURRENT->nr_sectors == 0 ) end_request( 1 );
-           else break;
-         }
-       }
-       if( CURRENT_IS_VALID &&
-          ( CURRENT->sector / 4 < sjcd_next_bn ||
-           CURRENT->sector / 4 > sjcd_next_bn + SJCD_BUF_SIZ ) ){
+                               printk
+                                   ("SJCD_S_DATA: next_bn=%d, buf_in=%d, buf_out=%d, buf_bn=%d\n",
+                                    sjcd_next_bn, sjcd_buf_in,
+                                    sjcd_buf_out,
+                                    sjcd_buf_bn[sjcd_buf_in]);
+#endif
+                               sjcd_buf_bn[sjcd_buf_in] = sjcd_next_bn++;
+                               if (sjcd_buf_out == -1)
+                                       sjcd_buf_out = sjcd_buf_in;
+                               if (++sjcd_buf_in == SJCD_BUF_SIZ)
+                                       sjcd_buf_in = 0;
+
+                               /*
+                                * Only one frame is ready at time. So we should turn over to wait for
+                                * another frame. If we need that, of course.
+                                */
+                               if (--sjcd_read_count == 0) {
+                                       /*
+                                        * OK, request seems to be precessed. Continue transferring...
+                                        */
+                                       if (!sjcd_transfer_is_active) {
+                                               while (CURRENT_IS_VALID) {
+                                                       /*
+                                                        * Continue transferring.
+                                                        */
+                                                       sjcd_transfer();
+                                                       if (CURRENT->
+                                                           nr_sectors ==
+                                                           0)
+                                                               end_request
+                                                                   (1);
+                                                       else
+                                                               break;
+                                               }
+                                       }
+                                       if (CURRENT_IS_VALID &&
+                                           (CURRENT->sector / 4 <
+                                            sjcd_next_bn
+                                            || CURRENT->sector / 4 >
+                                            sjcd_next_bn +
+                                            SJCD_BUF_SIZ)) {
 #if defined( SJCD_TRACE )
-         printk( "SJCD_S_DATA: can't read: go to SJCD_S_STOP mode\n" );
-#endif
-         sjcd_transfer_state = SJCD_S_STOP;
-         goto ReSwitch;
-       }
-      }
-      /*
-       * Now we should turn around rather than wait for while.
-       */
-      goto sjcd_s_data;
-    }
+                                               printk
+                                                   ("SJCD_S_DATA: can't read: go to SJCD_S_STOP mode\n");
+#endif
+                                               sjcd_transfer_state =
+                                                   SJCD_S_STOP;
+                                               goto ReSwitch;
+                                       }
+                               }
+                               /*
+                                * Now we should turn around rather than wait for while.
+                                */
+                               goto sjcd_s_data;
+                       }
 #if defined( SJCD_GATHER_STAT )
-    else statistic.data_ticks++;
+                       else
+                               statistic.data_ticks++;
 #endif
-    break;
-  }
+                       break;
+               }
 
-  case SJCD_S_STOP:{
-    sjcd_read_count = 0;
-    sjcd_send_cmd( SCMD_STOP );
-    sjcd_transfer_state = SJCD_S_STOPPING;
-    sjcd_transfer_timeout = 500;
+       case SJCD_S_STOP:{
+                       sjcd_read_count = 0;
+                       sjcd_send_cmd(SCMD_STOP);
+                       sjcd_transfer_state = SJCD_S_STOPPING;
+                       sjcd_transfer_timeout = 500;
 #if defined( SJCD_GATHER_STAT )
-    statistic.stop_ticks++;
+                       statistic.stop_ticks++;
 #endif
-    break;
-  }
+                       break;
+               }
+
+       case SJCD_S_STOPPING:{
+                       unsigned char stat;
 
-  case SJCD_S_STOPPING:{
-    unsigned char stat;
-    
-    stat = inb( SJCDPORT( 1 ) );
+                       stat = inb(SJCDPORT(1));
 #if defined( SJCD_TRACE )
-    printk( "SJCD_S_STOP: status = 0x%02x\n", stat );
-#endif      
-    if( SJCD_DATA_AVAILABLE( stat ) ){
-      int i;
+                       printk("SJCD_S_STOP: status = 0x%02x\n", stat);
+#endif
+                       if (SJCD_DATA_AVAILABLE(stat)) {
+                               int i;
 #if defined( SJCD_TRACE )
-      printk( "SJCD_S_STOP: discard data\n" );
-#endif
-      /*
-       * Discard all the data from the pipe. Foolish method.
-       */
-      for( i = 2048; i--; ( void )inb( SJCDPORT( 2 ) ) );
-      sjcd_transfer_timeout = 500;
-    } else if( SJCD_STATUS_AVAILABLE( stat ) ){
-      sjcd_load_status();
-      if( sjcd_status_valid && sjcd_media_is_changed ) {
-       sjcd_toc_uptodate = 0;
-       sjcd_invalidate_buffers();
-      }
-      if( CURRENT_IS_VALID ){
-       if( sjcd_status_valid ) sjcd_transfer_state = SJCD_S_READ;
-       else sjcd_transfer_state = SJCD_S_START;
-      } else sjcd_transfer_state = SJCD_S_IDLE;
-      goto ReSwitch;
-    }
+                               printk("SJCD_S_STOP: discard data\n");
+#endif
+                               /*
+                                * Discard all the data from the pipe. Foolish method.
+                                */
+                               for (i = 2048; i--;
+                                    (void) inb(SJCDPORT(2)));
+                               sjcd_transfer_timeout = 500;
+                       } else if (SJCD_STATUS_AVAILABLE(stat)) {
+                               sjcd_load_status();
+                               if (sjcd_status_valid
+                                   && sjcd_media_is_changed) {
+                                       sjcd_toc_uptodate = 0;
+                                       sjcd_invalidate_buffers();
+                               }
+                               if (CURRENT_IS_VALID) {
+                                       if (sjcd_status_valid)
+                                               sjcd_transfer_state =
+                                                   SJCD_S_READ;
+                                       else
+                                               sjcd_transfer_state =
+                                                   SJCD_S_START;
+                               } else
+                                       sjcd_transfer_state = SJCD_S_IDLE;
+                               goto ReSwitch;
+                       }
 #if defined( SJCD_GATHER_STAT )
-    else statistic.stopping_ticks++;
-#endif
-    break;
-  }
-
-  default:
-    printk( "SJCD: poll: invalid state %d\n", sjcd_transfer_state );
-    return;
-  }
-  
-  if( --sjcd_transfer_timeout == 0 ){
-    printk( "SJCD: timeout in state %d\n", sjcd_transfer_state );
-    while( CURRENT_IS_VALID ) end_request( 0 );
-    sjcd_send_cmd( SCMD_STOP );
-    sjcd_transfer_state = SJCD_S_IDLE;
-    goto ReSwitch;
-    }
-
-  /*
-   * Get back in some time. 1 should be replaced with count variable to
-   * avoid unnecessary testings.
-   */
-  SJCD_SET_TIMER( sjcd_poll, 1 );
+                       else
+                               statistic.stopping_ticks++;
+#endif
+                       break;
+               }
+
+       default:
+               printk("SJCD: poll: invalid state %d\n",
+                      sjcd_transfer_state);
+               return;
+       }
+
+       if (--sjcd_transfer_timeout == 0) {
+               printk("SJCD: timeout in state %d\n", sjcd_transfer_state);
+               while (CURRENT_IS_VALID)
+                       end_request(0);
+               sjcd_send_cmd(SCMD_STOP);
+               sjcd_transfer_state = SJCD_S_IDLE;
+               goto ReSwitch;
+       }
+
+       /*
+        * Get back in some time. 1 should be replaced with count variable to
+        * avoid unnecessary testings.
+        */
+       SJCD_SET_TIMER(sjcd_poll, 1);
 }
 
-static void do_sjcd_request( request_queue_t * q ){
+static void do_sjcd_request(request_queue_t * q)
+{
 #if defined( SJCD_TRACE )
-  printk( "SJCD: do_sjcd_request(%ld+%ld)\n",
-        CURRENT->sector, CURRENT->nr_sectors );
-#endif
-  sjcd_transfer_is_active = 1;
-  while( CURRENT_IS_VALID ){
-    /*
-     * Who of us are paranoiac?
-     */
-    if( CURRENT->bh && !buffer_locked(CURRENT->bh) )
-      panic( DEVICE_NAME ": block not locked" );
-
-    sjcd_transfer();
-    if( CURRENT->nr_sectors == 0 ) end_request( 1 );
-    else {
-      sjcd_buf_out = -1;         /* Want to read a block not in buffer */
-      if( sjcd_transfer_state == SJCD_S_IDLE ){
-       if( !sjcd_toc_uptodate ){
-         if( sjcd_update_toc() < 0 ){
-           printk( "SJCD: transfer: discard\n" );
-           while( CURRENT_IS_VALID ) end_request( 0 );
-           break;
-         }
+       printk("SJCD: do_sjcd_request(%ld+%ld)\n",
+              CURRENT->sector, CURRENT->nr_sectors);
+#endif
+       sjcd_transfer_is_active = 1;
+       while (CURRENT_IS_VALID) {
+               /*
+                * Who of us are paranoiac?
+                */
+               if (CURRENT->bh && !buffer_locked(CURRENT->bh))
+                       panic(DEVICE_NAME ": block not locked");
+
+               sjcd_transfer();
+               if (CURRENT->nr_sectors == 0)
+                       end_request(1);
+               else {
+                       sjcd_buf_out = -1;      /* Want to read a block not in buffer */
+                       if (sjcd_transfer_state == SJCD_S_IDLE) {
+                               if (!sjcd_toc_uptodate) {
+                                       if (sjcd_update_toc() < 0) {
+                                               printk
+                                                   ("SJCD: transfer: discard\n");
+                                               while (CURRENT_IS_VALID)
+                                                       end_request(0);
+                                               break;
+                                       }
+                               }
+                               sjcd_transfer_state = SJCD_S_START;
+                               SJCD_SET_TIMER(sjcd_poll, HZ / 100);
+                       }
+                       break;
+               }
        }
-       sjcd_transfer_state = SJCD_S_START;
-       SJCD_SET_TIMER( sjcd_poll, HZ/100 );
-      }
-      break;
-    }
-  }
-  sjcd_transfer_is_active = 0;
+       sjcd_transfer_is_active = 0;
 #if defined( SJCD_TRACE )
-  printk( "sjcd_next_bn:%x sjcd_buf_in:%x sjcd_buf_out:%x sjcd_buf_bn:%x\n",
-        sjcd_next_bn, sjcd_buf_in, sjcd_buf_out, sjcd_buf_bn[ sjcd_buf_in ] );
-  printk( "do_sjcd_request ends\n" );
+       printk
+           ("sjcd_next_bn:%x sjcd_buf_in:%x sjcd_buf_out:%x sjcd_buf_bn:%x\n",
+            sjcd_next_bn, sjcd_buf_in, sjcd_buf_out,
+            sjcd_buf_bn[sjcd_buf_in]);
+       printk("do_sjcd_request ends\n");
 #endif
 }
 
 /*
  * Open the device special file. Check disk is in.
  */
-int sjcd_open( struct inode *ip, struct file *fp ){
-  /*
-   * Check the presence of device.
-   */
-  if( !sjcd_present ) return( -ENXIO );
-  
-  /*
-   * Only read operations are allowed. Really? (:-)
-   */
-  if( fp->f_mode & 2 ) return( -EROFS );
-  
-  MOD_INC_USE_COUNT;
-
-  if( sjcd_open_count == 0 ){
-    int s, sjcd_open_tries;
+int sjcd_open(struct inode *ip, struct file *fp)
+{
+       /*
+        * Check the presence of device.
+        */
+       if (!sjcd_present)
+               return (-ENXIO);
+
+       /*
+        * Only read operations are allowed. Really? (:-)
+        */
+       if (fp->f_mode & 2)
+               return (-EROFS);
+
+       MOD_INC_USE_COUNT;
+
+       if (sjcd_open_count == 0) {
+               int s, sjcd_open_tries;
 /* We don't know that, do we? */
 /*
     sjcd_audio_status = CDROM_AUDIO_NO_STATUS;
 */
-    sjcd_mode = 0;
-    sjcd_door_was_open = 0;
-    sjcd_transfer_state = SJCD_S_IDLE;
-    sjcd_invalidate_buffers();
-    sjcd_status_valid = 0;
-
-    /*
-     * Strict status checking.
-     */
-    for( sjcd_open_tries = 4; --sjcd_open_tries; ){
-      if( !sjcd_status_valid ) sjcd_get_status();
-      if( !sjcd_status_valid ){
+               sjcd_mode = 0;
+               sjcd_door_was_open = 0;
+               sjcd_transfer_state = SJCD_S_IDLE;
+               sjcd_invalidate_buffers();
+               sjcd_status_valid = 0;
+
+               /*
+                * Strict status checking.
+                */
+               for (sjcd_open_tries = 4; --sjcd_open_tries;) {
+                       if (!sjcd_status_valid)
+                               sjcd_get_status();
+                       if (!sjcd_status_valid) {
 #if defined( SJCD_DIAGNOSTIC )
-       printk( "SJCD: open: timed out when check status.\n" );
+                               printk
+                                   ("SJCD: open: timed out when check status.\n");
 #endif
-       goto err_out;
-      } else if( !sjcd_media_is_available ){
+                               goto err_out;
+                       } else if (!sjcd_media_is_available) {
 #if defined( SJCD_DIAGNOSTIC )
-       printk("SJCD: open: no disk in drive\n");
+                               printk("SJCD: open: no disk in drive\n");
 #endif
-       if( !sjcd_door_closed ){
-         sjcd_door_was_open = 1;
+                               if (!sjcd_door_closed) {
+                                       sjcd_door_was_open = 1;
 #if defined( SJCD_TRACE )
-         printk("SJCD: open: close the tray\n");
+                                       printk
+                                           ("SJCD: open: close the tray\n");
 #endif
-         s = sjcd_tray_close();
-         if( s < 0 || !sjcd_status_valid || sjcd_command_failed ){
+                                       s = sjcd_tray_close();
+                                       if (s < 0 || !sjcd_status_valid
+                                           || sjcd_command_failed) {
 #if defined( SJCD_DIAGNOSTIC )
-           printk("SJCD: open: tray close attempt failed\n");
-#endif
-           goto err_out;
-         }
-         continue;
-       } else goto err_out;
-      }
-      break;
-    }
-    s = sjcd_tray_lock();
-    if( s < 0 || !sjcd_status_valid || sjcd_command_failed ){
+                                               printk
+                                                   ("SJCD: open: tray close attempt failed\n");
+#endif
+                                               goto err_out;
+                                       }
+                                       continue;
+                               } else
+                                       goto err_out;
+                       }
+                       break;
+               }
+               s = sjcd_tray_lock();
+               if (s < 0 || !sjcd_status_valid || sjcd_command_failed) {
 #if defined( SJCD_DIAGNOSTIC )
-      printk("SJCD: open: tray lock attempt failed\n");
+                       printk("SJCD: open: tray lock attempt failed\n");
 #endif
-      goto err_out;
-    }
+                       goto err_out;
+               }
 #if defined( SJCD_TRACE )
-    printk( "SJCD: open: done\n" );
+               printk("SJCD: open: done\n");
 #endif
-  }
+       }
 
-  ++sjcd_open_count;
-  return( 0 );
+       ++sjcd_open_count;
+       return (0);
 
-err_out:
-  MOD_DEC_USE_COUNT;
-  return( -EIO );
+      err_out:
+       MOD_DEC_USE_COUNT;
+       return (-EIO);
 }
 
 /*
  * On close, we flush all sjcd blocks from the buffer cache.
  */
-static int sjcd_release( struct inode *inode, struct file *file ){
-  int s;
+static int sjcd_release(struct inode *inode, struct file *file)
+{
+       int s;
 
 #if defined( SJCD_TRACE )
-  printk( "SJCD: release\n" );
+       printk("SJCD: release\n");
 #endif
 #ifdef MODULE
-  MOD_DEC_USE_COUNT;
+       MOD_DEC_USE_COUNT;
 #endif
-  if( --sjcd_open_count == 0 ){
-    sjcd_invalidate_buffers();
-    s = sjcd_tray_unlock();
-    if( s < 0 || !sjcd_status_valid || sjcd_command_failed ){
+       if (--sjcd_open_count == 0) {
+               sjcd_invalidate_buffers();
+               s = sjcd_tray_unlock();
+               if (s < 0 || !sjcd_status_valid || sjcd_command_failed) {
 #if defined( SJCD_DIAGNOSTIC )
-      printk("SJCD: release: tray unlock attempt failed.\n");
-#endif
-    }
-    if( sjcd_door_was_open ){
-      s = sjcd_tray_open();
-      if( s < 0 || !sjcd_status_valid || sjcd_command_failed ){
+                       printk
+                           ("SJCD: release: tray unlock attempt failed.\n");
+#endif
+               }
+               if (sjcd_door_was_open) {
+                       s = sjcd_tray_open();
+                       if (s < 0 || !sjcd_status_valid
+                           || sjcd_command_failed) {
 #if defined( SJCD_DIAGNOSTIC )
-       printk("SJCD: release: tray unload attempt failed.\n");
+                               printk
+                                   ("SJCD: release: tray unload attempt failed.\n");
 #endif
-      }
-    }
-  }
-  return 0;
+                       }
+               }
+       }
+       return 0;
 }
 
 /*
  * A list of file operations allowed for this cdrom.
  */
 static struct block_device_operations sjcd_fops = {
-       open:                   sjcd_open,
-       release:                sjcd_release,
-       ioctl:                  sjcd_ioctl,
-       check_media_change:     sjcd_disk_change,
+       open:sjcd_open,
+       release:sjcd_release,
+       ioctl:sjcd_ioctl,
+       check_media_change:sjcd_disk_change,
 };
 
 static int blksize = 2048;
@@ -1453,146 +1678,156 @@ static int secsize = 2048;
  * The version is two BCD-coded bytes.
  */
 static struct {
-  unsigned char major, minor;
+       unsigned char major, minor;
 } sjcd_version;
 
 /*
  * Test for presence of drive and initialize it. Called at boot time.
  * Probe cdrom, find out version and status.
  */
-int __init sjcd_init( void ){
-  int i;
+int __init sjcd_init(void)
+{
+       int i;
 
-  printk(KERN_INFO "SJCD: Sanyo CDR-H94A cdrom driver version %d.%d.\n", SJCD_VERSION_MAJOR,
-    SJCD_VERSION_MINOR);
+       printk(KERN_INFO
+              "SJCD: Sanyo CDR-H94A cdrom driver version %d.%d.\n",
+              SJCD_VERSION_MAJOR, SJCD_VERSION_MINOR);
 
 #if defined( SJCD_TRACE )
-  printk("SJCD: sjcd=0x%x: ", sjcd_base);
-#endif  
+       printk("SJCD: sjcd=0x%x: ", sjcd_base);
+#endif
 
        hardsect_size[MAJOR_NR] = &secsize;
        blksize_size[MAJOR_NR] = &blksize;
 
-  if( devfs_register_blkdev( MAJOR_NR, "sjcd", &sjcd_fops ) != 0 ){
-    printk( "SJCD: Unable to get major %d for Sanyo CD-ROM\n", MAJOR_NR );
-    return( -EIO );
-  }
-  
-  blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
-  read_ahead[ MAJOR_NR ] = 4;
-  register_disk(NULL, MKDEV(MAJOR_NR,0), 1, &sjcd_fops, 0);
-  
-  if( check_region( sjcd_base, 4 ) ){
-    printk( "SJCD: Init failed, I/O port (%X) is already in use\n",
-      sjcd_base );
-    sjcd_cleanup();
-    return( -EIO );
-  }
-  
-  /*
-   * Check for card. Since we are booting now, we can't use standard
-   * wait algorithm.
-   */
-  printk(KERN_INFO "SJCD: Resetting: " );
-  sjcd_send_cmd( SCMD_RESET );
-  for( i = 1000; i > 0 && !sjcd_status_valid; --i ){
-    unsigned long timer;
-
-    /*
-     * Wait 10ms approx.
-     */
-    for( timer = jiffies; time_before_eq(jiffies, timer); );
-    if ( (i % 100) == 0 ) printk( "." );
-    ( void )sjcd_check_status();
-  }
-  if( i == 0 || sjcd_command_failed ){
-    printk( " reset failed, no drive found.\n" );
-    sjcd_cleanup();
-    return( -EIO );
-  } else printk( "\n" );
-
-  /*
-   * Get and print out cdrom version.
-   */
-  printk(KERN_INFO "SJCD: Getting version: " );
-  sjcd_send_cmd( SCMD_GET_VERSION );
-  for( i = 1000; i > 0 && !sjcd_status_valid; --i ){
-    unsigned long timer;
-
-    /*
-     * Wait 10ms approx.
-     */
-    for( timer = jiffies; time_before_eq(jiffies, timer); );
-    if ( (i % 100) == 0 ) printk( "." );
-    ( void )sjcd_check_status();
-  }
-  if( i == 0 || sjcd_command_failed ){
-    printk( " get version failed, no drive found.\n" );
-    sjcd_cleanup();
-    return( -EIO );
-  }
-
-  if( sjcd_load_response( &sjcd_version, sizeof( sjcd_version ) ) == 0 ){
-    printk( " %1x.%02x\n", ( int )sjcd_version.major,
-            ( int )sjcd_version.minor );
-  } else {
-    printk( " read version failed, no drive found.\n" );
-    sjcd_cleanup();
-    return( -EIO );
-  }
-
-  /*
-   * Check and print out the tray state. (if it is needed?).
-   */
-  if( !sjcd_status_valid ){
-    printk(KERN_INFO "SJCD: Getting status: " );
-    sjcd_send_cmd( SCMD_GET_STATUS );
-    for( i = 1000; i > 0 && !sjcd_status_valid; --i ){
-      unsigned long timer;
-
-      /*
-       * Wait 10ms approx.
-       */
-      for( timer = jiffies; time_before_eq(jiffies, timer); );
-      if ( (i % 100) == 0 ) printk( "." );
-      ( void )sjcd_check_status();
-    }
-    if( i == 0 || sjcd_command_failed ){
-      printk( " get status failed, no drive found.\n" );
-      sjcd_cleanup();
-      return( -EIO );
-    } else printk( "\n" );
-  }
-
-  printk(KERN_INFO "SJCD: Status: port=0x%x.\n", sjcd_base);
-  devfs_register (NULL, "sjcd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
-                 S_IFBLK | S_IRUGO | S_IWUGO, &sjcd_fops, NULL);
-
-  sjcd_present++;
-  return( 0 );
+       if (devfs_register_blkdev(MAJOR_NR, "sjcd", &sjcd_fops) != 0) {
+               printk("SJCD: Unable to get major %d for Sanyo CD-ROM\n",
+                      MAJOR_NR);
+               return (-EIO);
+       }
+
+       blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
+       read_ahead[MAJOR_NR] = 4;
+       register_disk(NULL, MKDEV(MAJOR_NR, 0), 1, &sjcd_fops, 0);
+
+       if (check_region(sjcd_base, 4)) {
+               printk
+                   ("SJCD: Init failed, I/O port (%X) is already in use\n",
+                    sjcd_base);
+               sjcd_cleanup();
+               return (-EIO);
+       }
+
+       /*
+        * Check for card. Since we are booting now, we can't use standard
+        * wait algorithm.
+        */
+       printk(KERN_INFO "SJCD: Resetting: ");
+       sjcd_send_cmd(SCMD_RESET);
+       for (i = 1000; i > 0 && !sjcd_status_valid; --i) {
+               unsigned long timer;
+
+               /*
+                * Wait 10ms approx.
+                */
+               for (timer = jiffies; time_before_eq(jiffies, timer););
+               if ((i % 100) == 0)
+                       printk(".");
+               (void) sjcd_check_status();
+       }
+       if (i == 0 || sjcd_command_failed) {
+               printk(" reset failed, no drive found.\n");
+               sjcd_cleanup();
+               return (-EIO);
+       } else
+               printk("\n");
+
+       /*
+        * Get and print out cdrom version.
+        */
+       printk(KERN_INFO "SJCD: Getting version: ");
+       sjcd_send_cmd(SCMD_GET_VERSION);
+       for (i = 1000; i > 0 && !sjcd_status_valid; --i) {
+               unsigned long timer;
+
+               /*
+                * Wait 10ms approx.
+                */
+               for (timer = jiffies; time_before_eq(jiffies, timer););
+               if ((i % 100) == 0)
+                       printk(".");
+               (void) sjcd_check_status();
+       }
+       if (i == 0 || sjcd_command_failed) {
+               printk(" get version failed, no drive found.\n");
+               sjcd_cleanup();
+               return (-EIO);
+       }
+
+       if (sjcd_load_response(&sjcd_version, sizeof(sjcd_version)) == 0) {
+               printk(" %1x.%02x\n", (int) sjcd_version.major,
+                      (int) sjcd_version.minor);
+       } else {
+               printk(" read version failed, no drive found.\n");
+               sjcd_cleanup();
+               return (-EIO);
+       }
+
+       /*
+        * Check and print out the tray state. (if it is needed?).
+        */
+       if (!sjcd_status_valid) {
+               printk(KERN_INFO "SJCD: Getting status: ");
+               sjcd_send_cmd(SCMD_GET_STATUS);
+               for (i = 1000; i > 0 && !sjcd_status_valid; --i) {
+                       unsigned long timer;
+
+                       /*
+                        * Wait 10ms approx.
+                        */
+                       for (timer = jiffies;
+                            time_before_eq(jiffies, timer););
+                       if ((i % 100) == 0)
+                               printk(".");
+                       (void) sjcd_check_status();
+               }
+               if (i == 0 || sjcd_command_failed) {
+                       printk(" get status failed, no drive found.\n");
+                       sjcd_cleanup();
+                       return (-EIO);
+               } else
+                       printk("\n");
+       }
+
+       printk(KERN_INFO "SJCD: Status: port=0x%x.\n", sjcd_base);
+       devfs_register(NULL, "sjcd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
+                      S_IFBLK | S_IRUGO | S_IWUGO, &sjcd_fops, NULL);
+
+       sjcd_present++;
+       return (0);
 }
 
-static int
-sjcd_cleanup(void)
+static int sjcd_cleanup(void)
 {
-  if( (devfs_unregister_blkdev(MAJOR_NR, "sjcd") == -EINVAL) )
-    printk( "SJCD: cannot unregister device.\n" );
-  else {
-    release_region( sjcd_base, 4 );
-    blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-  }
-
-  return(0);
+       if ((devfs_unregister_blkdev(MAJOR_NR, "sjcd") == -EINVAL))
+               printk("SJCD: cannot unregister device.\n");
+       else {
+               release_region(sjcd_base, 4);
+               blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+       }
+
+       return (0);
 }
 
 
 void __exit sjcd_exit(void)
 {
-  devfs_unregister(devfs_find_handle(NULL, "sjcd", 0, 0, DEVFS_SPECIAL_BLK,0));
-  if ( sjcd_cleanup() )
-    printk( "SJCD: module: cannot be removed.\n" );
-  else
-    printk(KERN_INFO "SJCD: module: removed.\n");
+       devfs_unregister(devfs_find_handle
+                        (NULL, "sjcd", 0, 0, DEVFS_SPECIAL_BLK, 0));
+       if (sjcd_cleanup())
+               printk("SJCD: module: cannot be removed.\n");
+       else
+               printk(KERN_INFO "SJCD: module: removed.\n");
 }
 
 #ifdef MODULE
@@ -1601,3 +1836,4 @@ module_init(sjcd_init);
 module_exit(sjcd_exit);
 
 
+MODULE_LICENSE("GPL");
index fb016439c73f8c8098e98bb47962050acec8cff9..42bdc16a0dd15464aebe38fbc83dea187f234216 100644 (file)
@@ -29,7 +29,7 @@
 
 /* Uncomment this if your mouse drivers expect the kernel to
  * return with EAGAIN if the mouse does not have any events
- * available, even if the mouse is opened in nonblocking mode.
+ * available, even if the mouse is opened in blocking mode.
  * Please report use of this "feature" to the author using the
  * above address.
  */
@@ -444,3 +444,5 @@ EXPORT_SYMBOL(busmouse_add_movement);
 EXPORT_SYMBOL(busmouse_add_buttons);
 EXPORT_SYMBOL(register_busmouse);
 EXPORT_SYMBOL(unregister_busmouse);
+
+MODULE_LICENSE("GPL");
index 28d92604b111a82c5181cc5938184a7578023657..b438c9c63d8efd75edcc4d5fa52ba5e7a6883898 100644 (file)
@@ -502,7 +502,7 @@ static struct file_operations dsp56k_fops = {
 
 static devfs_handle_t devfs_handle;
 
-static const char banner[] __initdata = KERN_INFO "DSP56k driver installed\n";
+static char banner[] __initdata = KERN_INFO "DSP56k driver installed\n";
 
 static int __init dsp56k_init_driver(void)
 {
@@ -531,3 +531,5 @@ static void __exit dsp56k_cleanup_driver(void)
        devfs_unregister(devfs_handle);
 }
 module_exit(dsp56k_cleanup_driver);
+
+MODULE_LICENSE("GPL");
index 164cb42525e64486c1054190cffead0e459b9308..44a222b2f7eacac6428b49b0555bed7af0cfe6e1 100644 (file)
@@ -273,9 +273,6 @@ int __init misc_init(void)
 #ifdef CONFIG_SGI_NEWPORT_GFX
        gfx_register ();
 #endif
-#ifdef CONFIG_SGI
-       streamable_init ();
-#endif
 #ifdef CONFIG_TOSHIBA
        tosh_init();
 #endif
index 129e94cb53acb0f3fd8437b63035aabbe8a70d19..36534874246227271e719a85df4fa5713240c349 100644 (file)
@@ -798,7 +798,7 @@ static struct miscdevice pc110_pad = {
  *     asked to open it by an application.
  */
 
-static const char banner[] __initdata = KERN_INFO "PC110 digitizer pad at 0x%X, irq %d.\n";
+static char banner[] __initdata = KERN_INFO "PC110 digitizer pad at 0x%X, irq %d.\n";
 
 static int __init pc110pad_init_driver(void)
 {
@@ -840,3 +840,9 @@ static void __exit pc110pad_exit_driver(void)
 
 module_init(pc110pad_init_driver);
 module_exit(pc110pad_exit_driver);
+
+MODULE_AUTHOR("Alan Cox, Robin O'Leary");
+MODULE_DESCRIPTION("Driver for the touchpad on the IBM PC110 palmtop");
+MODULE_LICENSE("GPL");
+
+EXPORT_NO_SYMBOLS;
index 770ebd69a593ba5439ae0e4ef05ffade26921363..e8228cc9e993dde870505033f533b003e6e247ef 100644 (file)
@@ -338,8 +338,8 @@ static int __init probe_qp(void)
        return 1;
 }
 
-static const char msg_banner[] __initdata = KERN_INFO "82C710 type pointing device detected -- driver installed.\n";
-static const char msg_nomem[]  __initdata = KERN_ERR "qpmouse: no queue memory.\n";
+static char msg_banner[] __initdata = KERN_INFO "82C710 type pointing device detected -- driver installed.\n";
+static char msg_nomem[]  __initdata = KERN_ERR "qpmouse: no queue memory.\n";
 
 static int __init qpmouse_init_driver(void)
 {
@@ -371,3 +371,6 @@ static void __exit qpmouse_exit_driver(void)
 module_init(qpmouse_init_driver);
 module_exit(qpmouse_exit_driver);
 
+
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
index 5e4741556c9f103dcd5112cc68ddd70b30117ce3..1b26619ca27edb180fc185f124e4f0018fdd1a50 100644 (file)
@@ -248,6 +248,7 @@ long rio_irqmask = -1;
 #ifndef TWO_ZERO
 MODULE_AUTHOR("Rogier Wolff <R.E.Wolff@bitwizard.nl>, Patrick van de Lageweg <patrick@bitwizard.nl>");
 MODULE_DESCRIPTION("RIO driver");
+MODULE_LICENSE("GPL");
 MODULE_PARM(rio_poll, "i");
 MODULE_PARM(rio_debug, "i");
 MODULE_PARM(rio_irqmask, "i");
index 7b3345242e65d086f8dd606dc7b7878b896e5daf..8cc048dcfd530f56de52e233e4de3a7fe3dec77e 100644 (file)
@@ -481,7 +481,7 @@ PKT *PacketP;
                                not freed. */
                        /* Call tmgr HANGUP HERE */
                        /* Fix this later when every thing works !!!! RAMRAJ */
-                       gs_got_break (PortP);
+                       gs_got_break (&PortP->gs);
                        break;
 
                case COMPLETE:
index 39cf73765fafd22990edd375414e4e0de4b319f6..3295c7d6e6d2793f61b4fca177c70caa58f3ca48 100644 (file)
@@ -96,11 +96,7 @@ static inline int inword(const unsigned char c) {
 /* set inwordLut contents. Invoked by ioctl(). */
 int sel_loadlut(const unsigned long arg)
 {
-       int err = -EFAULT;
-
-       if (!copy_from_user(inwordLut, (u32 *)(arg+4), 32))
-               err = 0;
-       return err;
+       return copy_from_user(inwordLut, (u32 *)(arg+4), 32) ? -EFAULT : 0;
 }
 
 /* does screen address p correspond to character at LH/RH edge of screen? */
@@ -130,15 +126,13 @@ int set_selection(const unsigned long arg, struct tty_struct *tty, int user)
 
          args = (unsigned short *)(arg + 1);
          if (user) {
-                 int err;
-                 err = verify_area(VERIFY_READ, args, sizeof(short) * 5);
-                 if (err)
-                       return err;
-                 get_user(xs, args++);
-                 get_user(ys, args++);
-                 get_user(xe, args++);
-                 get_user(ye, args++);
-                 get_user(sel_mode, args);
+                 if (verify_area(VERIFY_READ, args, sizeof(short) * 5))
+                       return -EFAULT;
+                 __get_user(xs, args++);
+                 __get_user(ys, args++);
+                 __get_user(xe, args++);
+                 __get_user(ye, args++);
+                 __get_user(sel_mode, args);
          } else {
                  xs = *(args++); /* set selection from kernel */
                  ys = *(args++);
diff --git a/drivers/char/serial_tx3912.c b/drivers/char/serial_tx3912.c
new file mode 100644 (file)
index 0000000..57a030c
--- /dev/null
@@ -0,0 +1,1079 @@
+/*
+ *  drivers/char/serial_tx3912.c
+ *
+ *  Copyright (C) 1999 Harald Koerfgen
+ *  Copyright (C) 2000 Jim Pick <jim@jimpick.com>
+ *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *  
+ *  Serial driver for TMPR3912/05 and PR31700 processors
+ */
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/tty.h>
+#include <linux/major.h>
+#include <linux/ptrace.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/malloc.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/delay.h>
+#include <asm/wbflush.h>
+#include <asm/tx3912.h>
+#include "serial_tx3912.h"
+
+/*
+ * Forward declarations for serial routines
+ */
+static void rs_disable_tx_interrupts (void * ptr);
+static void rs_enable_tx_interrupts (void * ptr); 
+static void rs_disable_rx_interrupts (void * ptr); 
+static void rs_enable_rx_interrupts (void * ptr); 
+static int rs_get_CD (void * ptr); 
+static void rs_shutdown_port (void * ptr); 
+static int rs_set_real_termios (void *ptr);
+static int rs_chars_in_buffer (void * ptr); 
+static void rs_hungup (void *ptr);
+static void rs_close (void *ptr);
+
+/*
+ * Used by generic serial driver to access hardware
+ */
+static struct real_driver rs_real_driver = { 
+       disable_tx_interrupts: rs_disable_tx_interrupts, 
+       enable_tx_interrupts:  rs_enable_tx_interrupts, 
+       disable_rx_interrupts: rs_disable_rx_interrupts, 
+       enable_rx_interrupts:  rs_enable_rx_interrupts, 
+       get_CD:                rs_get_CD, 
+       shutdown_port:         rs_shutdown_port,  
+       set_real_termios:      rs_set_real_termios,  
+       chars_in_buffer:       rs_chars_in_buffer, 
+       close:                 rs_close, 
+       hungup:                rs_hungup,
+}; 
+
+/*
+ * Structures and such for TTY sessions and usage counts
+ */
+static struct tty_driver rs_driver, rs_callout_driver;
+static struct tty_struct * rs_table[TX3912_UART_NPORTS] = { NULL, };
+static struct termios ** rs_termios;
+static struct termios ** rs_termios_locked;
+struct rs_port *rs_ports;
+int rs_refcount;
+int rs_initialized = 0;
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Here starts the interrupt handling routines.  All of the following
+ * subroutines are declared as inline and are folded into
+ * rs_interrupt().  They were separated out for readability's sake.
+ *
+ * Note: rs_interrupt() is a "fast" interrupt, which means that it
+ * runs with interrupts turned off.  People who may want to modify
+ * rs_interrupt() should try to keep the interrupt handler as fast as
+ * possible.  After you are done making modifications, it is not a bad
+ * idea to do:
+ * 
+ * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
+ *
+ * and look at the resulting assemble code in serial.s.
+ *
+ *                             - Ted Ts'o (tytso@mit.edu), 7-Mar-93
+ * -----------------------------------------------------------------------
+ */
+static inline void receive_char_pio(struct rs_port *port)
+{
+       struct tty_struct *tty = port->gs.tty;
+       unsigned char ch;
+       int counter = 2048;
+
+       /* While there are characters, get them ... */
+       while (counter>0) {
+               if (!(inl(port->base + TX3912_UART_CTRL1) & UART_RX_HOLD_FULL))
+                       break;
+               ch = inb(port->base + TX3912_UART_DATA);
+               if (tty->flip.count < TTY_FLIPBUF_SIZE) {
+                       *tty->flip.char_buf_ptr++ = ch;
+                       *tty->flip.flag_buf_ptr++ = 0;
+                       tty->flip.count++;
+               }
+               udelay(1); /* Allow things to happen - it take a while */
+               counter--;
+       }
+       if (!counter)
+               printk( "Ugh, looped in receive_char_pio!\n" );
+
+       tty_flip_buffer_push(tty);
+
+#if 0
+       /* Now handle error conditions */
+       if (*status & (INTTYPE(UART_RXOVERRUN_INT) |
+                       INTTYPE(UART_FRAMEERR_INT) |
+                       INTTYPE(UART_PARITYERR_INT) |
+                       INTTYPE(UART_BREAK_INT))) {
+
+               /*
+                * Now check to see if character should be
+                * ignored, and mask off conditions which
+                * should be ignored.
+                */
+               if (*status & port->ignore_status_mask) {
+                       goto ignore_char;
+               }
+               *status &= port->read_status_mask;
+               
+               if (*status & INTTYPE(UART_BREAK_INT)) {
+                       rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "handling break....");
+                       *tty->flip.flag_buf_ptr = TTY_BREAK;
+               }
+               else if (*status & INTTYPE(UART_PARITYERR_INT)) {
+                       *tty->flip.flag_buf_ptr = TTY_PARITY;
+               }
+               else if (*status & INTTYPE(UART_FRAMEERR_INT)) {
+                       *tty->flip.flag_buf_ptr = TTY_FRAME;
+               }
+               if (*status & INTTYPE(UART_RXOVERRUN_INT)) {
+                       /*
+                        * Overrun is special, since it's
+                        * reported immediately, and doesn't
+                        * affect the current character
+                        */
+                       if (tty->flip.count < TTY_FLIPBUF_SIZE) {
+                               tty->flip.count++;
+                               tty->flip.flag_buf_ptr++;
+                               tty->flip.char_buf_ptr++;
+                               *tty->flip.flag_buf_ptr = TTY_OVERRUN;
+                       }
+               }
+       }
+
+       tty->flip.flag_buf_ptr++;
+       tty->flip.char_buf_ptr++;
+       tty->flip.count++;
+
+ignore_char:
+       tty_flip_buffer_push(tty);
+#endif
+}
+
+static inline void transmit_char_pio(struct rs_port *port)
+{
+       /* While I'm able to transmit ... */
+       for (;;) {
+               if (!(inl(port->base + TX3912_UART_CTRL1) & UART_TX_EMPTY))
+                       break;
+               else if (port->x_char) {
+                       outb(port->x_char, port->base + TX3912_UART_DATA);
+                       port->icount.tx++;
+                       port->x_char = 0;
+               }
+               else if (port->gs.xmit_cnt <= 0 || port->gs.tty->stopped ||
+                   port->gs.tty->hw_stopped) {
+                       break;
+               }
+               else {
+                       outb(port->gs.xmit_buf[port->gs.xmit_tail++],
+                               port->base + TX3912_UART_DATA);
+                       port->icount.tx++;
+                       port->gs.xmit_tail &= SERIAL_XMIT_SIZE-1;
+                       if (--port->gs.xmit_cnt <= 0) {
+                               break;
+                       }
+               }
+               udelay(10); /* Allow things to happen - it take a while */
+       }
+
+       if (port->gs.xmit_cnt <= 0 || port->gs.tty->stopped ||
+            port->gs.tty->hw_stopped) {
+               rs_disable_tx_interrupts(port);
+       }
+       
+        if (port->gs.xmit_cnt <= port->gs.wakeup_chars) {
+                if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+                    port->gs.tty->ldisc.write_wakeup)
+                        (port->gs.tty->ldisc.write_wakeup)(port->gs.tty);
+                rs_dprintk (TX3912_UART_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n",
+                            port->gs.wakeup_chars); 
+                wake_up_interruptible(&port->gs.tty->write_wait);
+               }       
+}
+
+
+
+static inline void check_modem_status(struct rs_port *port)
+{
+        /* We don't have a carrier detect line - but just respond
+           like we had one anyways so that open() becomes unblocked */
+       wake_up_interruptible(&port->gs.open_wait);
+}
+
+int count = 0;
+
+/*
+ * This is the serial driver's interrupt routine (inlined, because
+ * there are two different versions of this, one for each serial port,
+ * differing only by the bits used in interrupt status 2 register)
+ */
+
+static inline void rs_rx_interrupt(int irq, void *dev_id,
+                                 struct pt_regs * regs, int intshift)
+{
+       struct rs_port * port;
+       unsigned long int2status;
+       unsigned long flags;
+       unsigned long ints;
+
+       save_and_cli(flags);
+
+       port = (struct rs_port *)dev_id;
+       rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "rs_interrupt (port %p, shift %d)...", port, intshift);
+
+       /* Get the interrrupts we have enabled */
+       int2status = IntStatus2 & IntEnable2;
+
+       /* Get interrupts in easy to use form */
+       ints = int2status >> intshift;
+
+       /* Clear any interrupts we might be about to handle */
+       IntClear2 = int2status & (
+               (INTTYPE(UART_RXOVERRUN_INT) |
+                INTTYPE(UART_FRAMEERR_INT) |
+                INTTYPE(UART_BREAK_INT) |
+                INTTYPE(UART_PARITYERR_INT) |
+                INTTYPE(UART_RX_INT)) << intshift);
+
+       if (!port || !port->gs.tty) {
+               restore_flags(flags);
+               return;
+       }
+
+       /* RX Receiver Holding Register Overrun */
+       if (ints & INTTYPE(UART_RXOVERRUN_INT)) {
+               rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "overrun");
+               port->icount.overrun++;
+       }
+
+       /* RX Frame Error */
+       if (ints & INTTYPE(UART_FRAMEERR_INT)) {
+               rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "frame error");
+               port->icount.frame++;
+       }
+
+       /* Break signal received */
+       if (ints & INTTYPE(UART_BREAK_INT)) {
+               rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "break");
+               port->icount.brk++;
+       }
+
+       /* RX Parity Error */
+       if (ints & INTTYPE(UART_PARITYERR_INT)) {
+               rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "parity error");
+               port->icount.parity++;
+       }
+
+       /* Receive byte (non-DMA) */
+       if (ints & INTTYPE(UART_RX_INT)) {
+               receive_char_pio(port);
+       }
+
+       restore_flags(flags);
+
+       rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "end.\n");
+}
+
+static inline void rs_tx_interrupt(int irq, void *dev_id,
+                                 struct pt_regs * regs, int intshift)
+{
+       struct rs_port * port;
+       unsigned long int2status;
+       unsigned long flags;
+       unsigned long ints;
+
+       save_and_cli(flags);
+
+       port = (struct rs_port *)dev_id;
+       rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "rs_interrupt (port %p, shift %d)...", port, intshift);
+
+       /* Get the interrrupts we have enabled */
+       int2status = IntStatus2 & IntEnable2;
+
+       if (!port || !port->gs.tty) {
+               restore_flags(flags);
+               return;
+       }
+
+       /* Get interrupts in easy to use form */
+       ints = int2status >> intshift;
+
+       /* Clear any interrupts we might be about to handle */
+       IntClear2 = int2status & (
+               (INTTYPE(UART_TX_INT) |
+                INTTYPE(UART_EMPTY_INT) |
+                INTTYPE(UART_TXOVERRUN_INT)) << intshift);
+
+       /* TX holding register empty, so transmit byte (non-DMA) */
+       if (ints & (INTTYPE(UART_TX_INT) | INTTYPE(UART_EMPTY_INT))) {
+               transmit_char_pio(port);
+       }
+
+       /* TX Transmit Holding Register Overrun (shouldn't happen) */
+       if (ints & INTTYPE(UART_TXOVERRUN_INT)) {
+               printk ( "rs: TX overrun\n");
+       }
+
+       /*
+       check_modem_status();
+       */
+
+       restore_flags(flags);
+
+       rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "end.\n");
+}
+
+static void rs_rx_interrupt_uarta(int irq, void *dev_id,
+                                        struct pt_regs * regs)
+{
+       rs_rx_interrupt(irq, dev_id, regs, UARTA_SHIFT);
+}
+
+static void rs_tx_interrupt_uarta(int irq, void *dev_id,
+                                        struct pt_regs * regs)
+{
+       rs_tx_interrupt(irq, dev_id, regs, UARTA_SHIFT);
+}
+
+/*
+ ***********************************************************************
+ *                Here are the routines that actually                  *
+ *              interface with the generic_serial driver               *
+ ***********************************************************************
+ */
+static void rs_disable_tx_interrupts (void * ptr) 
+{
+       struct rs_port *port = ptr; 
+       unsigned long flags;
+
+       save_and_cli(flags);
+        port->gs.flags &= ~GS_TX_INTEN;
+
+       IntEnable2 &= ~((INTTYPE(UART_TX_INT) |
+                       INTTYPE(UART_EMPTY_INT) |
+                       INTTYPE(UART_TXOVERRUN_INT)) << port->intshift);
+
+       IntClear2 = (INTTYPE(UART_TX_INT) |
+                       INTTYPE(UART_EMPTY_INT) |
+                       INTTYPE(UART_TXOVERRUN_INT)) << port->intshift;
+
+       restore_flags(flags);
+}
+
+static void rs_enable_tx_interrupts (void * ptr) 
+{
+       struct rs_port *port = ptr; 
+       unsigned long flags;
+
+       save_and_cli(flags);
+
+       IntClear2 = (INTTYPE(UART_TX_INT) |
+                       INTTYPE(UART_EMPTY_INT) |
+                       INTTYPE(UART_TXOVERRUN_INT)) << port->intshift;
+
+       IntEnable2 |= (INTTYPE(UART_TX_INT) |
+                       INTTYPE(UART_EMPTY_INT) |
+                       INTTYPE(UART_TXOVERRUN_INT)) << port->intshift;
+
+       /* Send a char to start TX interrupts happening */
+       transmit_char_pio(port);
+
+       restore_flags(flags);
+}
+
+static void rs_disable_rx_interrupts (void * ptr) 
+{
+       struct rs_port *port = ptr;
+       unsigned long flags;
+
+       save_and_cli(flags);
+
+       IntEnable2 &= ~((INTTYPE(UART_RX_INT) |
+                        INTTYPE(UART_RXOVERRUN_INT) |
+                        INTTYPE(UART_FRAMEERR_INT) |
+                        INTTYPE(UART_BREAK_INT) |
+                        INTTYPE(UART_PARITYERR_INT)) << port->intshift);
+
+       IntClear2 = (INTTYPE(UART_RX_INT) |
+                        INTTYPE(UART_RXOVERRUN_INT) |
+                        INTTYPE(UART_FRAMEERR_INT) |
+                        INTTYPE(UART_BREAK_INT) |
+                        INTTYPE(UART_PARITYERR_INT)) << port->intshift;
+
+       restore_flags(flags);
+}
+
+static void rs_enable_rx_interrupts (void * ptr) 
+{
+       struct rs_port *port = ptr;
+       unsigned long flags;
+
+       save_and_cli(flags);
+
+       IntEnable2 |= (INTTYPE(UART_RX_INT) |
+                        INTTYPE(UART_RXOVERRUN_INT) |
+                        INTTYPE(UART_FRAMEERR_INT) |
+                        INTTYPE(UART_BREAK_INT) |
+                        INTTYPE(UART_PARITYERR_INT)) << port->intshift;
+
+       /* Empty the input buffer - apparently this is *vital* */
+       while (inl(port->base + TX3912_UART_CTRL1) & UART_RX_HOLD_FULL) { 
+               inb(port->base + TX3912_UART_DATA);
+       }
+
+       IntClear2 = (INTTYPE(UART_RX_INT) |
+                        INTTYPE(UART_RXOVERRUN_INT) |
+                        INTTYPE(UART_FRAMEERR_INT) |
+                        INTTYPE(UART_BREAK_INT) |
+                        INTTYPE(UART_PARITYERR_INT)) << port->intshift;
+
+       restore_flags(flags);
+}
+
+
+static int rs_get_CD (void * ptr) 
+{
+       /* No Carried Detect in Hardware - just return true */
+       func_exit();
+       return (1);
+}
+
+static void rs_shutdown_port (void * ptr) 
+{
+       struct rs_port *port = ptr; 
+
+       func_enter();
+
+       port->gs.flags &= ~GS_ACTIVE;
+
+       func_exit();
+}
+
+static int rs_set_real_termios (void *ptr)
+{
+       struct rs_port *port = ptr;
+       int t;
+
+       switch (port->gs.baud) {
+               /* Save some typing work... */
+#define e(x) case x:t= TX3912_UART_CTRL2_B ## x ; break
+               e(300);e(600);e(1200);e(2400);e(4800);e(9600);
+               e(19200);e(38400);e(57600);e(76800);e(115200);e(230400);
+       case 0      :t = -1;
+               break;
+       default:
+               /* Can I return "invalid"? */
+               t = TX3912_UART_CTRL2_B9600;
+               printk (KERN_INFO "rs: unsupported baud rate: %d.\n", port->gs.baud);
+               break;
+       }
+#undef e
+       if (t >= 0) {
+               /* Jim: Set Hardware Baud rate - there is some good
+                  code in drivers/char/serial.c */
+
+               /* Program hardware for parity, data bits, stop bits (note: these are hardcoded to 8N1 */
+               UartA_Ctrl1 &= 0xf000000f;
+               UartA_Ctrl1 &= ~(UART_DIS_TXD | SER_SEVEN_BIT | SER_EVEN_PARITY | SER_TWO_STOP);
+
+#define CFLAG port->gs.tty->termios->c_cflag
+               if (C_PARENB(port->gs.tty)) {
+                       if (!C_PARODD(port->gs.tty))
+                               UartA_Ctrl1 |= SER_EVEN_PARITY;
+                       else
+                               UartA_Ctrl1 |= SER_ODD_PARITY;
+               }
+               if ((CFLAG & CSIZE)==CS6)
+                       printk(KERN_ERR "6 bits not supported\n");
+               if ((CFLAG & CSIZE)==CS5)
+                       printk(KERN_ERR "5 bits not supported\n");
+               if ((CFLAG & CSIZE)==CS7)
+                       UartA_Ctrl1 |= SER_SEVEN_BIT;
+               if (C_CSTOPB(port->gs.tty))
+                       UartA_Ctrl1 |= SER_TWO_STOP;
+
+               outl(t, port->base + TX3912_UART_CTRL2);
+               outl(0, port->base + TX3912_UART_DMA_CTRL1);
+               outl(0, port->base + TX3912_UART_DMA_CTRL2);
+               UartA_Ctrl1 |= TX3912_UART_CTRL1_UARTON;
+
+        /* wait until UARTA is stable */
+        while (~UartA_Ctrl1 & TX3912_UART_CTRL1_UARTON);
+       }
+
+       func_exit ();
+        return 0;
+}
+
+static int rs_chars_in_buffer (void * ptr) 
+{
+       struct rs_port *port = ptr;
+       int scratch;
+
+       scratch = inl(port->base + TX3912_UART_CTRL1);
+
+       return ((scratch & UART_TX_EMPTY) ? 0 : 1);
+}
+
+/* ********************************************************************** *
+ *                Here are the routines that actually                     *
+ *               interface with the rest of the system                    *
+ * ********************************************************************** */
+static int rs_open  (struct tty_struct * tty, struct file * filp)
+{
+       struct rs_port *port;
+       int retval, line;
+
+       func_enter();
+
+       if (!rs_initialized) {
+               return -EIO;
+       }
+
+       line = MINOR(tty->device) - tty->driver.minor_start;
+       rs_dprintk (TX3912_UART_DEBUG_OPEN, "%d: opening line %d. tty=%p ctty=%p)\n", 
+                   (int) current->pid, line, tty, current->tty);
+
+       if ((line < 0) || (line >= TX3912_UART_NPORTS))
+               return -ENODEV;
+
+       /* Pre-initialized already */
+       port = & rs_ports[line];
+
+       rs_dprintk (TX3912_UART_DEBUG_OPEN, "port = %p\n", port);
+
+       tty->driver_data = port;
+       port->gs.tty = tty;
+       port->gs.count++;
+
+       rs_dprintk (TX3912_UART_DEBUG_OPEN, "starting port\n");
+
+       /*
+        * Start up serial port
+        */
+       retval = gs_init_port(&port->gs);
+       rs_dprintk (TX3912_UART_DEBUG_OPEN, "done gs_init\n");
+       if (retval) {
+               port->gs.count--;
+               return retval;
+       }
+
+       port->gs.flags |= GS_ACTIVE;
+
+       rs_dprintk (TX3912_UART_DEBUG_OPEN, "before inc_use_count (count=%d.\n", 
+                   port->gs.count);
+       if (port->gs.count == 1) {
+               MOD_INC_USE_COUNT;
+       }
+       rs_dprintk (TX3912_UART_DEBUG_OPEN, "after inc_use_count\n");
+
+       /* Jim: Initialize port hardware here */
+
+       /* Enable high-priority interrupts for UARTA */
+       IntEnable6 |= INT6_UARTARXINT; 
+       rs_enable_rx_interrupts(&rs_ports[0]); 
+
+       retval = gs_block_til_ready(&port->gs, filp);
+       rs_dprintk (TX3912_UART_DEBUG_OPEN, "Block til ready returned %d. Count=%d\n", 
+                   retval, port->gs.count);
+
+       if (retval) {
+               MOD_DEC_USE_COUNT;
+               port->gs.count--;
+               return retval;
+       }
+       /* tty->low_latency = 1; */
+
+       if ((port->gs.count == 1) && (port->gs.flags & ASYNC_SPLIT_TERMIOS)) {
+               if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+                       *tty->termios = port->gs.normal_termios;
+               else 
+                       *tty->termios = port->gs.callout_termios;
+               rs_set_real_termios (port);
+       }
+
+       port->gs.session = current->session;
+       port->gs.pgrp = current->pgrp;
+       func_exit();
+
+       /* Jim */
+/*     cli(); */
+
+       return 0;
+
+}
+
+
+
+static void rs_close (void *ptr)
+{
+       func_enter ();
+
+       /* Anything to do here? */
+
+       MOD_DEC_USE_COUNT;
+       func_exit ();
+}
+
+
+/* I haven't the foggiest why the decrement use count has to happen
+   here. The whole linux serial drivers stuff needs to be redesigned.
+   My guess is that this is a hack to minimize the impact of a bug
+   elsewhere. Thinking about it some more. (try it sometime) Try
+   running minicom on a serial port that is driven by a modularized
+   driver. Have the modem hangup. Then remove the driver module. Then
+   exit minicom.  I expect an "oops".  -- REW */
+static void rs_hungup (void *ptr)
+{
+       func_enter ();
+       MOD_DEC_USE_COUNT;
+       func_exit ();
+}
+
+static int rs_ioctl (struct tty_struct * tty, struct file * filp, 
+                     unsigned int cmd, unsigned long arg)
+{
+       int rc;
+       struct rs_port *port = tty->driver_data;
+       int ival;
+
+       rc = 0;
+       switch (cmd) {
+       case TIOCGSOFTCAR:
+               rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
+                             (unsigned int *) arg);
+               break;
+       case TIOCSSOFTCAR:
+               if ((rc = verify_area(VERIFY_READ, (void *) arg,
+                                     sizeof(int))) == 0) {
+                       get_user(ival, (unsigned int *) arg);
+                       tty->termios->c_cflag =
+                               (tty->termios->c_cflag & ~CLOCAL) |
+                               (ival ? CLOCAL : 0);
+               }
+               break;
+       case TIOCGSERIAL:
+               if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
+                                     sizeof(struct serial_struct))) == 0)
+                       gs_getserial(&port->gs, (struct serial_struct *) arg);
+               break;
+       case TIOCSSERIAL:
+               if ((rc = verify_area(VERIFY_READ, (void *) arg,
+                                     sizeof(struct serial_struct))) == 0)
+                       rc = gs_setserial(&port->gs, (struct serial_struct *) arg);
+               break;
+       default:
+               rc = -ENOIOCTLCMD;
+               break;
+       }
+
+       /* func_exit(); */
+       return rc;
+}
+
+
+/*
+ * This function is used to send a high-priority XON/XOFF character to
+ * the device
+ */
+static void rs_send_xchar(struct tty_struct * tty, char ch)
+{
+       struct rs_port *port = (struct rs_port *)tty->driver_data;
+       func_enter ();
+       
+       port->x_char = ch;
+       if (ch) {
+               /* Make sure transmit interrupts are on */
+               rs_enable_tx_interrupts(tty);
+       }
+
+       func_exit();
+}
+
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ * 
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void rs_throttle(struct tty_struct * tty)
+{
+#ifdef TX3912_UART_DEBUG_THROTTLE
+       char    buf[64];
+       
+       printk("throttle %s: %d....\n", tty_name(tty, buf),
+              tty->ldisc.chars_in_buffer(tty));
+#endif
+
+       func_enter ();
+       
+       if (I_IXOFF(tty))
+               rs_send_xchar(tty, STOP_CHAR(tty));
+
+       func_exit ();
+}
+
+static void rs_unthrottle(struct tty_struct * tty)
+{
+       struct rs_port *port = (struct rs_port *)tty->driver_data;
+#ifdef TX3912_UART_DEBUG_THROTTLE
+       char    buf[64];
+       
+       printk("unthrottle %s: %d....\n", tty_name(tty, buf),
+              tty->ldisc.chars_in_buffer(tty));
+#endif
+
+       func_enter();
+       
+       if (I_IXOFF(tty)) {
+               if (port->x_char)
+                       port->x_char = 0;
+               else
+                       rs_send_xchar(tty, START_CHAR(tty));
+       }
+
+       func_exit();
+}
+
+
+
+
+
+/* ********************************************************************** *
+ *                    Here are the initialization routines.               *
+ * ********************************************************************** */
+
+void * ckmalloc (int size)
+{
+        void *p;
+
+        p = kmalloc(size, GFP_KERNEL);
+        if (p) 
+                memset(p, 0, size);
+        return p;
+}
+
+
+
+static int rs_init_portstructs(void)
+{
+       struct rs_port *port;
+       int i;
+
+       /* Debugging */
+       func_enter();
+
+       rs_ports          = ckmalloc(TX3912_UART_NPORTS * sizeof (struct rs_port));
+       if (!rs_ports)
+               return -ENOMEM;
+
+       rs_termios        = ckmalloc(TX3912_UART_NPORTS * sizeof (struct termios *));
+       if (!rs_termios) {
+               kfree (rs_ports);
+               return -ENOMEM;
+       }
+
+       rs_termios_locked = ckmalloc(TX3912_UART_NPORTS * sizeof (struct termios *));
+       if (!rs_termios_locked) {
+               kfree (rs_ports);
+               kfree (rs_termios);
+               return -ENOMEM;
+       }
+
+       /* Adjust the values in the "driver" */
+       rs_driver.termios = rs_termios;
+       rs_driver.termios_locked = rs_termios_locked;
+
+       port = rs_ports;
+       for (i=0; i < TX3912_UART_NPORTS;i++) {
+               rs_dprintk (TX3912_UART_DEBUG_INIT, "initing port %d\n", i);
+               port->gs.callout_termios = tty_std_termios;
+               port->gs.normal_termios = tty_std_termios;
+               port->gs.magic = SERIAL_MAGIC;
+               port->gs.close_delay = HZ/2;
+               port->gs.closing_wait = 30 * HZ;
+               port->gs.rd = &rs_real_driver;
+#ifdef NEW_WRITE_LOCKING
+               port->gs.port_write_sem = MUTEX;
+#endif
+#ifdef DECLARE_WAITQUEUE
+               init_waitqueue_head(&port->gs.open_wait);
+               init_waitqueue_head(&port->gs.close_wait);
+#endif
+               port->base = (i == 0) ? TX3912_UARTA_BASE : TX3912_UARTB_BASE;
+               port->intshift = (i == 0) ? UARTA_SHIFT : UARTB_SHIFT;
+               rs_dprintk (TX3912_UART_DEBUG_INIT, "base 0x%08lx intshift %d\n",
+                           port->base, port->intshift);
+               port++;
+       }
+
+       func_exit();
+       return 0;
+}
+
+static int rs_init_drivers(void)
+{
+       int error;
+
+       func_enter();
+
+       memset(&rs_driver, 0, sizeof(rs_driver));
+       rs_driver.magic = TTY_DRIVER_MAGIC;
+       rs_driver.driver_name = "serial";
+       rs_driver.name = "ttyS";
+       rs_driver.major = TTY_MAJOR;
+       rs_driver.minor_start = 64;
+       rs_driver.num = TX3912_UART_NPORTS;
+       rs_driver.type = TTY_DRIVER_TYPE_SERIAL;
+       rs_driver.subtype = SERIAL_TYPE_NORMAL;
+       rs_driver.init_termios = tty_std_termios;
+       rs_driver.init_termios.c_cflag =
+               B115200 | CS8 | CREAD | HUPCL | CLOCAL;
+       rs_driver.refcount = &rs_refcount;
+       rs_driver.table = rs_table;
+       rs_driver.termios = rs_termios;
+       rs_driver.termios_locked = rs_termios_locked;
+
+       rs_driver.open  = rs_open;
+       rs_driver.close = gs_close;
+       rs_driver.write = gs_write;
+       rs_driver.put_char = gs_put_char; 
+       rs_driver.flush_chars = gs_flush_chars;
+       rs_driver.write_room = gs_write_room;
+       rs_driver.chars_in_buffer = gs_chars_in_buffer;
+       rs_driver.flush_buffer = gs_flush_buffer;
+       rs_driver.ioctl = rs_ioctl;
+       rs_driver.throttle = rs_throttle;
+       rs_driver.unthrottle = rs_unthrottle;
+       rs_driver.set_termios = gs_set_termios;
+       rs_driver.stop = gs_stop;
+       rs_driver.start = gs_start;
+       rs_driver.hangup = gs_hangup;
+
+       rs_callout_driver = rs_driver;
+       rs_callout_driver.name = "cua";
+       rs_callout_driver.major = TTYAUX_MAJOR;
+       rs_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+
+       if ((error = tty_register_driver(&rs_driver))) {
+               printk(KERN_ERR "Couldn't register serial driver, error = %d\n",
+                      error);
+               return 1;
+       }
+       if ((error = tty_register_driver(&rs_callout_driver))) {
+               tty_unregister_driver(&rs_driver);
+               printk(KERN_ERR "Couldn't register callout driver, error = %d\n",
+                      error);
+               return 1;
+       }
+
+       func_exit();
+       return 0;
+}
+
+
+void __init tx3912_rs_init(void)
+{
+       int rc;
+
+
+       func_enter();
+       rs_dprintk (TX3912_UART_DEBUG_INIT, "Initing serial module... (rs_debug=%d)\n", rs_debug);
+
+       rc = rs_init_portstructs ();
+       rs_init_drivers ();
+       if (request_irq(2, rs_tx_interrupt_uarta, SA_SHIRQ | SA_INTERRUPT,
+                       "serial", &rs_ports[0])) {
+               printk(KERN_ERR "rs: Cannot allocate irq for UARTA.\n");
+               rc = 0;
+       }
+       if (request_irq(3, rs_rx_interrupt_uarta, SA_SHIRQ | SA_INTERRUPT,
+                       "serial", &rs_ports[0])) {
+               printk(KERN_ERR "rs: Cannot allocate irq for UARTA.\n");
+               rc = 0;
+       }
+
+       IntEnable6 |= INT6_UARTARXINT; 
+       rs_enable_rx_interrupts(&rs_ports[0]); 
+
+#ifndef CONFIG_SERIAL_TX3912_CONSOLE
+{
+       unsigned int scratch = 0;
+
+       /* Setup master clock for UART */
+       scratch = inl(TX3912_CLK_CTRL_BASE);
+       scratch &= ~TX3912_CLK_CTRL_SIBMCLKDIV_MASK;
+       scratch |= ((0x2 << TX3912_CLK_CTRL_SIBMCLKDIV_SHIFT) &
+                               TX3912_CLK_CTRL_SIBMCLKDIV_MASK)
+                       | TX3912_CLK_CTRL_SIBMCLKDIR
+                       | TX3912_CLK_CTRL_ENSIBMCLK
+                       | TX3912_CLK_CTRL_CSERSEL;
+       outl(scratch, TX3912_CLK_CTRL_BASE);
+
+       /* Configure UARTA clock */
+       scratch = inl(TX3912_CLK_CTRL_BASE);
+       scratch |= ((0x3 << TX3912_CLK_CTRL_CSERDIV_SHIFT) &
+                               TX3912_CLK_CTRL_CSERDIV_MASK)
+                       | TX3912_CLK_CTRL_ENCSERCLK
+                       | TX3912_CLK_CTRL_ENUARTACLK;
+       outl(scratch, TX3912_CLK_CTRL_BASE);
+               
+       /* Setup UARTA for 115200,8N1 */
+       outl(0, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
+       outl(TX3912_UART_CTRL2_B115200, TX3912_UARTA_BASE + TX3912_UART_CTRL2);
+       outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL1);
+       outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL2);
+
+       /* Enable UARTA */
+       outl(TX3912_UART_CTRL1_ENUART, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
+       while (~inl(TX3912_UARTA_BASE + TX3912_UART_CTRL1) &
+               TX3912_UART_CTRL1_UARTON);
+}
+#endif
+
+       /* Note: I didn't do anything to enable the second UART */
+       if (rc >= 0) 
+               rs_initialized++;
+
+       func_exit();
+}
+
+/*
+ * Begin serial console routines
+ */
+#ifdef CONFIG_SERIAL_TX3912_CONSOLE
+
+void serial_outc(unsigned char c)
+{
+       int i;
+       unsigned long int2;
+       #define BUSY_WAIT 10000
+
+       /*
+        * Turn UARTA interrupts off
+        */
+       int2 = IntEnable2;
+       IntEnable2 &=
+               ~(INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY);
+
+       /*
+        * The UART_TX_EMPTY bit in UartA_Ctrl1 seems
+        * not to be very reliable :-(
+        *
+        * Wait for the Tx register to become empty
+        */
+       for (i = 0; !(IntStatus2 & INT2_UARTATXINT) && (i < BUSY_WAIT); i++);
+
+       IntClear2 = INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY;
+       UartA_Data = c;
+       for (i = 0; !(IntStatus2 & INT2_UARTATXINT) && (i < BUSY_WAIT); i++);
+       IntClear2 = INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY;
+
+       IntEnable2 = int2;
+}
+
+static int serial_console_wait_key(struct console *co)
+{
+       unsigned int int2, res;
+
+       int2 = IntEnable2;
+       IntEnable2 = 0;
+
+       while (!(UartA_Ctrl1 & UART_RX_HOLD_FULL));
+       res = UartA_Data;
+       udelay(10);
+       
+       IntEnable2 = int2;
+       return res;
+}
+
+static void serial_console_write(struct console *co, const char *s,
+               unsigned count)
+{
+       unsigned int i;
+
+       for (i = 0; i < count; i++) {
+               if (*s == '\n')
+                       serial_outc('\r');
+               serial_outc(*s++);
+       }
+}
+
+static kdev_t serial_console_device(struct console *c)
+{
+       return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+static __init int serial_console_setup(struct console *co, char *options)
+{
+       unsigned int scratch = 0;
+
+       /* Setup master clock for UART */
+       scratch = inl(TX3912_CLK_CTRL_BASE);
+       scratch &= ~TX3912_CLK_CTRL_SIBMCLKDIV_MASK;
+       scratch |= ((0x2 << TX3912_CLK_CTRL_SIBMCLKDIV_SHIFT) &
+                               TX3912_CLK_CTRL_SIBMCLKDIV_MASK)
+                       | TX3912_CLK_CTRL_SIBMCLKDIR
+                       | TX3912_CLK_CTRL_ENSIBMCLK
+                       | TX3912_CLK_CTRL_CSERSEL;
+       outl(scratch, TX3912_CLK_CTRL_BASE);
+
+       /* Configure UARTA clock */
+       scratch = inl(TX3912_CLK_CTRL_BASE);
+       scratch |= ((0x3 << TX3912_CLK_CTRL_CSERDIV_SHIFT) &
+                               TX3912_CLK_CTRL_CSERDIV_MASK)
+                       | TX3912_CLK_CTRL_ENCSERCLK
+                       | TX3912_CLK_CTRL_ENUARTACLK;
+       outl(scratch, TX3912_CLK_CTRL_BASE);
+               
+       /* Setup UARTA for 115200,8N1 */
+       outl(0, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
+       outl(TX3912_UART_CTRL2_B115200, TX3912_UARTA_BASE + TX3912_UART_CTRL2);
+       outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL1);
+       outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL2);
+
+       /* Enable UARTA */
+       outl(TX3912_UART_CTRL1_ENUART, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
+       while (~inl(TX3912_UARTA_BASE + TX3912_UART_CTRL1) &
+               TX3912_UART_CTRL1_UARTON);
+
+       return 0;
+}
+
+static struct console sercons = {
+       name:     "ttyS",
+       write:    serial_console_write,
+       device:   serial_console_device,
+       wait_key: serial_console_wait_key,
+       setup:    serial_console_setup,
+       flags:    CON_PRINTBUFFER,
+       index:    -1
+};
+
+void __init tx3912_console_init(void)
+{
+       register_console(&sercons);
+}
+
+#endif
diff --git a/drivers/char/serial_tx3912.h b/drivers/char/serial_tx3912.h
new file mode 100644 (file)
index 0000000..8276797
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ *  drivers/char/serial_tx3912.h
+ *
+ *  Copyright (C) 1999 Harald Koerfgen
+ *  Copyright (C) 2000 Jim Pick <jim@jimpick.com>
+ *  Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Serial driver for TMPR3912/05 and PR31700 processors
+ */
+#include <linux/serialP.h>
+#include <linux/generic_serial.h>
+
+/* UART Interrupt (Interrupt 2) bits (UARTA,UARTB) */
+#define UART_RX_INT         9  /* receiver holding register full  (31, 21) */
+#define UART_RXOVERRUN_INT  8  /* receiver overrun error          (30, 20) */
+#define UART_FRAMEERR_INT   7  /* receiver frame error            (29, 19) */
+#define UART_BREAK_INT      6  /* received break signal           (28, 18) */
+#define UART_PARITYERR_INT  5  /* receiver parity error           (27, 17) */
+#define UART_TX_INT         4  /* transmit holding register empty (26, 16) */
+#define UART_TXOVERRUN_INT  3  /* transmit overrun error          (25, 15) */
+#define UART_EMPTY_INT      2  /* both trans/recv regs empty      (24, 14) */
+#define UART_DMAFULL_INT    1  /* DMA at end of buffer            (23, 13) */
+#define UART_DMAHALF_INT    0  /* DMA halfway through buffer */   (22, 12) */
+
+#define UARTA_SHIFT        22
+#define UARTB_SHIFT        12
+
+#define INTTYPE(interrupttype)            (1 << interrupttype)
+
+/* 
+ * This driver can spew a whole lot of debugging output at you. If you
+ * need maximum performance, you should disable the DEBUG define.
+ */
+#undef TX3912_UART_DEBUG
+
+#ifdef TX3912_UART_DEBUG
+#define TX3912_UART_DEBUG_OPEN         0x00000001
+#define TX3912_UART_DEBUG_SETTING      0x00000002
+#define TX3912_UART_DEBUG_FLOW         0x00000004
+#define TX3912_UART_DEBUG_MODEMSIGNALS 0x00000008
+#define TX3912_UART_DEBUG_TERMIOS      0x00000010
+#define TX3912_UART_DEBUG_TRANSMIT     0x00000020
+#define TX3912_UART_DEBUG_RECEIVE      0x00000040
+#define TX3912_UART_DEBUG_INTERRUPTS   0x00000080
+#define TX3912_UART_DEBUG_PROBE                0x00000100
+#define TX3912_UART_DEBUG_INIT         0x00000200
+#define TX3912_UART_DEBUG_CLEANUP      0x00000400
+#define TX3912_UART_DEBUG_CLOSE                0x00000800
+#define TX3912_UART_DEBUG_FIRMWARE     0x00001000
+#define TX3912_UART_DEBUG_MEMTEST      0x00002000
+#define TX3912_UART_DEBUG_THROTTLE     0x00004000
+#define TX3912_UART_DEBUG_ALL          0xffffffff
+
+int rs_debug = TX3912_UART_DEBUG_ALL & ~TX3912_UART_DEBUG_TRANSMIT;
+
+#define rs_dprintk(f, str...) if (rs_debug & f) printk (str)
+#define func_enter() rs_dprintk (TX3912_UART_DEBUG_FLOW,       \
+                               "rs: enter " __FUNCTION__ "\n")
+#define func_exit() rs_dprintk (TX3912_UART_DEBUG_FLOW,        \
+                               "rs: exit " __FUNCTION__ "\n")
+
+#else
+#define rs_dprintk(f, str...)
+#define func_enter()
+#define func_exit()
+
+#endif /* TX3912_UART_DEBUG */
+
+/*
+ * Number of serial ports
+ */
+#define TX3912_UART_NPORTS  2
+
+/*
+ * Hardware specific serial port structure
+ */
+struct rs_port {       
+       struct gs_port          gs;             /* Must be first field! */
+
+       unsigned long           base;
+       int                     intshift;       /* Register shift */
+       struct wait_queue       *shutdown_wait; 
+       int                     stat_flags;
+        struct async_icount    icount;         /* Counters for 4 input IRQs */
+       int                     read_status_mask;
+       int                     ignore_status_mask;
+       int                     x_char;         /* XON/XOFF character */
+}; 
index b4e2d12b10d4699903a6007ee14bf1975d7ae9f7..132d311068e0a722dbc164f08598c834b4708555 100644 (file)
@@ -160,7 +160,7 @@ static struct miscdevice softdog_miscdev = {
        fops:           &softdog_fops,
 };
 
-static const char banner[] __initdata = KERN_INFO "Software Watchdog Timer: 0.05, timer margin: %d sec\n";
+static char banner[] __initdata = KERN_INFO "Software Watchdog Timer: 0.05, timer margin: %d sec\n";
 
 static int __init watchdog_init(void)
 {
index 9458888ee323ed0a25a4194af22b0933b8581c15..42b38fd31735cf377257eeaccc0b225b91aa87f7 100644 (file)
@@ -365,6 +365,8 @@ MODULE_PARM(sx_maxints, "i");
 MODULE_PARM(sx_debug, "i");
 MODULE_PARM(sx_irqmask, "i");
 
+MODULE_LICENSE("GPL");
+
 static struct real_driver sx_real_driver = {
        sx_disable_tx_interrupts,
        sx_enable_tx_interrupts,
@@ -1139,7 +1141,7 @@ static inline void sx_check_modem_signals (struct sx_port *port)
                sx_dprintk (SX_DEBUG_MODEMSIGNALS, "got a break.\n");
 
                sx_write_channel_byte (port, hi_state, hi_state);
-               gs_got_break (port);
+               gs_got_break (&port->gs);
        }
        if (hi_state & ST_DCD) {
                hi_state &= ~ST_DCD;
@@ -1614,6 +1616,7 @@ static int do_memtest (struct sx_board *board, int min, int max)
 #define R0         if (read_sx_word (board, i) != 0x55aa) return 1
 #define R1         if (read_sx_word (board, i) != 0xaa55) return 1
 
+#if 0
 /* This memtest takes a human-noticable time. You normally only do it
    once a boot, so I guess that it is worth it. */
 static int do_memtest_w (struct sx_board *board, int min, int max)
@@ -1628,6 +1631,7 @@ static int do_memtest_w (struct sx_board *board, int min, int max)
 
        return 0;
 }
+#endif
 
 
 static int sx_fw_ioctl (struct inode *inode, struct file *filp,
index aaeaf05bd1f55d6334ef4811123428a7bfb15bab..a1bb133fbd5837173bec6520a9e6b1c37810775d 100644 (file)
@@ -92,7 +92,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/smp_lock.h>
-#include <linux/devfs_fs_kernel.h> 
+#include <linux/devfs_fs_kernel.h>
 
 #include <asm/dma.h>
 #include <asm/system.h>
  * card+drive info if runtime configuration has been selected.
  */
 
-static struct mtconfiginfo qic02_tape_dynconf =        /* user settable */
-    { 0, 0, BOGUS_IRQ, 0, 0, TPQD_DEFAULT_FLAGS, };
+static struct mtconfiginfo qic02_tape_dynconf =        /* user settable */
+{ 0, 0, BOGUS_IRQ, 0, 0, TPQD_DEFAULT_FLAGS, };
 static struct qic02_ccb qic02_tape_ccb;        /* private stuff */
 
 #else
@@ -127,11 +127,11 @@ unsigned long qic02_tape_debug = TPQD_DEFAULT_FLAGS;
 # if ((QIC02_TAPE_IFC!=WANGTEK) && (QIC02_TAPE_IFC!=ARCHIVE) && (QIC02_TAPE_IFC!=MOUNTAIN))
 #  error No valid interface card specified
 # endif
-#endif /* CONFIG_QIC02_DYNCONF */
+#endif                         /* CONFIG_QIC02_DYNCONF */
 
-static volatile int ctlbits;     /* control reg bits for tape interface */
+static volatile int ctlbits;   /* control reg bits for tape interface */
 
-static wait_queue_head_t qic02_tape_transfer; /* sync rw with interrupts */
+static wait_queue_head_t qic02_tape_transfer;  /* sync rw with interrupts */
 
 static volatile struct mtget ioctl_status;     /* current generic status */
 
@@ -146,15 +146,15 @@ static char rcs_date[] = "$Date: 1997/01/26 07:13:20 $";
  * by an interrupt.
  */
 static volatile flag status_dead = YES;        /* device is legally dead until proven alive */
-static                 flag status_zombie = YES; /* it's `zombie' until irq/dma allocated */
+static flag status_zombie = YES;       /* it's `zombie' until irq/dma allocated */
 
 static volatile flag status_bytes_wr = NO;     /* write FM at close or not */
 static volatile flag status_bytes_rd = NO;     /* (rd|wr) used for rewinding */
 
-static volatile unsigned long status_cmd_pending; /* cmd in progress */
+static volatile unsigned long status_cmd_pending;      /* cmd in progress */
 static volatile flag status_expect_int = NO;   /* ready for interrupts */
-static volatile flag status_timer_on = NO;     /* using time-out */
-static volatile int  status_error;             /* int handler may detect error */
+static volatile flag status_timer_on = NO;     /* using time-out */
+static volatile int status_error;      /* int handler may detect error */
 static volatile flag status_eof_detected = NO; /* end of file */
 static volatile flag status_eom_detected = NO; /* end of recorded media */
 static volatile flag status_eot_detected = NO; /* end of tape */
@@ -163,8 +163,8 @@ static volatile flag doing_write = NO;
 
 static volatile unsigned long dma_bytes_todo;
 static volatile unsigned long dma_bytes_done;
-static volatile unsigned dma_mode;             /* !=0 also means DMA in use */
-static                 flag need_rewind = YES;
+static volatile unsigned dma_mode;     /* !=0 also means DMA in use */
+static flag need_rewind = YES;
 
 static kdev_t current_tape_dev;
 static int extra_blocks_left = BLOCKS_BEYOND_EW;
@@ -198,7 +198,7 @@ static char seek_addr_buf[AR_SEEK_BUF_SIZE];
  * mode is allowed as long as no actual writing has been done. After writing
  * the File Mark, repositioning and reading are allowed again.
  */
-static int  mode_access;       /* access mode: READ or WRITE */
+static int mode_access;                /* access mode: READ or WRITE */
 
 static int qic02_get_resources(void);
 static void qic02_release_resources(void);
@@ -210,17 +210,17 @@ static void qic02_release_resources(void);
  * must ensure that a large enough buffer is passed to the kernel, in order
  * to reduce tape repositioning wear and tear.
  */
-static void *buffaddr; /* virtual address of buffer */
+static void *buffaddr;         /* virtual address of buffer */
 
 /* This translates minor numbers to the corresponding recording format: */
 static const char *format_names[] = {
-       "not set",      /* for dumb drives unable to handle format selection */
-       "11",           /* extinct */
+       "not set",              /* for dumb drives unable to handle format selection */
+       "11",                   /* extinct */
        "24",
        "120",
        "150",
-       "300",          /* untested. */
-       "600"           /* untested. */
+       "300",                  /* untested. */
+       "600"                   /* untested. */
 };
 
 
@@ -248,52 +248,72 @@ static struct exception_list_type {
        const char *msg;
        /* EXC_nr attribute should match with tpqic02.h */
 } exception_list[] = {
-       {0, 0,
-               "Unknown exception status code",                /* extra: 0 */},
-       {~(0), TP_ST0|TP_CNI|TP_USL|TP_WRP,
-               "Drive not online"                              /* 1 */},
-               /* Drive presence goes before cartridge presence. */
-       {~(TP_WRP|TP_USL), TP_ST0|TP_CNI,
-               /* My Wangtek 5150EQ sometimes reports a status code
-                * of 0x00e0, which is not a valid exception code, but
-                * I think it should be recognized as "NO CARTRIDGE".
-                */
-               "Cartridge not in place"                        /* 2 */},
-       {(unsigned short) ~(TP_ST1|TP_BOM), (TP_ST0|TP_WRP),
-               "Write protected cartridge"                     /* 3 */},
-       {(unsigned short) ~(TP_ST1|TP_EOR), (TP_ST0|TP_EOM),
-               "End of media"                                  /* 4 */},
-       {~TP_WRP, TP_ST0|TP_UDA| TP_ST1|TP_BOM,
-               "Read or Write abort. Rewind tape."             /* 5 */},
-       {~TP_WRP, TP_ST0|TP_UDA,
-               "Read error. Bad block transferred."            /* 6 */},
-       {~TP_WRP, TP_ST0|TP_UDA|TP_BNL,
-               "Read error. Filler block transferred."         /* 7 */},
-       {~TP_WRP, TP_ST0|TP_UDA|TP_BNL |TP_ST1|TP_NDT,
-               "Read error. No data detected."                 /* 8 */},
-       {~TP_WRP, TP_ST0|TP_EOM|TP_UDA|TP_BNL |TP_ST1|TP_NDT,
-               "Read error. No data detected. EOM."            /* 9 */},
-       {~(TP_WRP|TP_MBD|TP_PAR|TP_EOR), TP_ST0|TP_UDA|TP_BNL |TP_ST1|TP_NDT|TP_BOM,
-               "Read error. No data detected. BOM."            /* 10 */},
-       {~(TP_WRP|TP_EOM), TP_ST0|TP_FIL,
-               /* Status 0x0089 (EOM & FM) is viewed as an FM,
-                * because it can only happen during a read.
-                * EOM is checked separately for an FM condition.
-                */
-               "File mark detected"                            /* 11 */},
-       {~(TP_ST0|TP_CNI|TP_USL|TP_WRP|TP_BOM), TP_ST1|TP_ILL,
-               "Illegal command"                               /* 12 */},
-       {~(TP_ST0|TP_CNI|TP_USL|TP_WRP|TP_BOM), TP_ST1|TP_POR,
-               "Reset occurred"                                        /* 13 */},
-       {~TP_WRP, TP_ST0|TP_FIL|TP_MBD,         /* NOTE: ST1 not set! */
-               "Marginal block detected"                       /* 14 */},
-       {~(TP_ST0|TP_WRP|TP_EOM|TP_UDA|TP_BNL|TP_FIL |TP_NDT), TP_ST1|TP_EOR,
+       {
+       0, 0, "Unknown exception status code", /* extra: 0 */ },
+       {
+       ~(0), TP_ST0 | TP_CNI | TP_USL | TP_WRP,
+                   "Drive not online" /* 1 */ },
+           /* Drive presence goes before cartridge presence. */
+       {
+               ~(TP_WRP | TP_USL), TP_ST0 | TP_CNI,
+                   /* My Wangtek 5150EQ sometimes reports a status code
+                    * of 0x00e0, which is not a valid exception code, but
+                    * I think it should be recognized as "NO CARTRIDGE".
+                    */
+       "Cartridge not in place" /* 2 */ },
+       {
+       (unsigned short) ~(TP_ST1 | TP_BOM), (TP_ST0 | TP_WRP),
+                   "Write protected cartridge" /* 3 */ },
+       {
+       (unsigned short) ~(TP_ST1 | TP_EOR), (TP_ST0 | TP_EOM),
+                   "End of media" /* 4 */ },
+       {
+       ~TP_WRP, TP_ST0 | TP_UDA | TP_ST1 | TP_BOM,
+                   "Read or Write abort. Rewind tape." /* 5 */ },
+       {
+       ~TP_WRP, TP_ST0 | TP_UDA,
+                   "Read error. Bad block transferred." /* 6 */ },
+       {
+       ~TP_WRP, TP_ST0 | TP_UDA | TP_BNL,
+                   "Read error. Filler block transferred." /* 7 */ },
+       {
+       ~TP_WRP, TP_ST0 | TP_UDA | TP_BNL | TP_ST1 | TP_NDT,
+                   "Read error. No data detected." /* 8 */ },
+       {
+       ~TP_WRP,
+                   TP_ST0 | TP_EOM | TP_UDA | TP_BNL | TP_ST1 |
+                   TP_NDT, "Read error. No data detected. EOM." /* 9 */ },
+       {
+       ~(TP_WRP | TP_MBD | TP_PAR | TP_EOR),
+                   TP_ST0 | TP_UDA | TP_BNL | TP_ST1 | TP_NDT |
+                   TP_BOM,
+                   "Read error. No data detected. BOM." /* 10 */ },
+       {
+               ~(TP_WRP | TP_EOM), TP_ST0 | TP_FIL,
+                   /* Status 0x0089 (EOM & FM) is viewed as an FM,
+                    * because it can only happen during a read.
+                    * EOM is checked separately for an FM condition.
+                    */
+       "File mark detected" /* 11 */ },
+       {
+       ~(TP_ST0 | TP_CNI | TP_USL | TP_WRP | TP_BOM),
+                   TP_ST1 | TP_ILL, "Illegal command" /* 12 */ },
+       {
+       ~(TP_ST0 | TP_CNI | TP_USL | TP_WRP | TP_BOM),
+                   TP_ST1 | TP_POR, "Reset occurred" /* 13 */ },
+       {
+               ~TP_WRP, TP_ST0 | TP_FIL | TP_MBD,      /* NOTE: ST1 not set! */
+       "Marginal block detected" /* 14 */ },
+       {
+               ~(TP_ST0 | TP_WRP | TP_EOM | TP_UDA | TP_BNL | TP_FIL |
+                 TP_NDT), TP_ST1 | TP_EOR,
                /********** Is the extra TP_NDT really needed Eddy? **********/
-               "End of recorded media"                         /* extra: 15 */},
-               /* 15 is returned when SEEKEOD completes successfully */
-       {~(TP_WRP|TP_ST0), TP_ST1|TP_BOM,
-               "Beginning of media"                            /* extra: 16 */}
+       "End of recorded media" /* extra: 15 */ },
+           /* 15 is returned when SEEKEOD completes successfully */
+       {
+       ~(TP_WRP | TP_ST0), TP_ST1 | TP_BOM, "Beginning of media" /* extra: 16 */ }
 };
+
 #define NR_OF_EXC      (sizeof(exception_list)/sizeof(struct exception_list_type))
 
 /* Compare expected struct size and actual struct size. This
@@ -310,7 +330,7 @@ static void tpqputs(unsigned long flags, const char *s)
 {
        if ((flags & TPQD_ALWAYS) || (flags & QIC02_TAPE_DEBUG))
                printk(TPQIC02_NAME ": %s\n", s);
-} /* tpqputs */
+}                              /* tpqputs */
 
 
 /* Perform byte order swapping for a 16-bit word.
@@ -318,11 +338,10 @@ static void tpqputs(unsigned long flags, const char *s)
  * [FIXME] This should probably be in include/asm/
  * ([FIXME] i486 can do this faster)
  */
-static inline void byte_swap_w(volatile unsigned short * w)
+static inline void byte_swap_w(volatile unsigned short *w)
 {
        int t = *w;
-
-       *w = (t>>8) | ((t & 0xff)<<8);
+       *w = (t >> 8) | ((t & 0xff) << 8);
 }
 
 
@@ -334,37 +353,32 @@ static inline void byte_swap_w(volatile unsigned short * w)
  */
 static void ifc_init(void)
 {
-    if (QIC02_TAPE_IFC == WANGTEK) /* || (QIC02_TAPE_IFC == EVEREX) */
-    {
-       ctlbits = WT_CTL_ONLINE;        /* online */
-       outb_p(ctlbits, QIC02_CTL_PORT);
-    }
-    else if (QIC02_TAPE_IFC == ARCHIVE)
-    {
-       ctlbits = 0;                    /* no interrupts yet */
-       outb_p(ctlbits, QIC02_CTL_PORT);
-       outb_p(0, AR_RESET_DMA_PORT);   /* dummy write to reset DMA */
-    }
-    else /* MOUNTAIN */
-    {
-       ctlbits = MTN_CTL_ONLINE;       /* online, and logic enabled */
-       outb_p(ctlbits, QIC02_CTL_PORT);
-    }
-} /* ifc_init */
+       if (QIC02_TAPE_IFC == WANGTEK) {        /* || (QIC02_TAPE_IFC == EVEREX) */
+               ctlbits = WT_CTL_ONLINE;        /* online */
+               outb_p(ctlbits, QIC02_CTL_PORT);
+       } else if (QIC02_TAPE_IFC == ARCHIVE) {
+               ctlbits = 0;    /* no interrupts yet */
+               outb_p(ctlbits, QIC02_CTL_PORT);
+               outb_p(0, AR_RESET_DMA_PORT);   /* dummy write to reset DMA */
+       } else {                /* MOUNTAIN */
+
+               ctlbits = MTN_CTL_ONLINE;       /* online, and logic enabled */
+               outb_p(ctlbits, QIC02_CTL_PORT);
+       }
+}                              /* ifc_init */
 
 
 static void report_qic_exception(unsigned n)
 {
-    if (n >= NR_OF_EXC)
-    {
-       tpqputs(TPQD_ALWAYS, "Oops -- report_qic_exception");
-       n = 0;
-    }
-    if (TPQDBG(SENSE_TEXT) || n==0)
-    {
-       printk(TPQIC02_NAME ": sense: %s\n", exception_list[n].msg);
-    }
-} /* report_qic_exception */
+       if (n >= NR_OF_EXC) {
+               tpqputs(TPQD_ALWAYS, "Oops -- report_qic_exception");
+               n = 0;
+       }
+       if (TPQDBG(SENSE_TEXT) || n == 0) {
+               printk(TPQIC02_NAME ": sense: %s\n",
+                      exception_list[n].msg);
+       }
+}                              /* report_qic_exception */
 
 
 /* Try to map the drive-exception bits `s' to a predefined "exception number",
@@ -374,18 +388,18 @@ static void report_qic_exception(unsigned n)
  */
 static int decode_qic_exception_nr(unsigned s)
 {
-    int i;
+       int i;
 
-    for (i=1; i<NR_OF_EXC; i++)
-    {
-       if ((s & exception_list[i].mask)==exception_list[i].code)
-       {
-           return i;
+       for (i = 1; i < NR_OF_EXC; i++) {
+               if ((s & exception_list[i].mask) == exception_list[i].code) {
+                       return i;
+               }
        }
-    }
-    printk(TPQIC02_NAME ": decode_qic_exception_nr: exception(%x) not recognized\n", s);
-    return 0;
-} /* decode_qic_exception_nr */
+       printk(TPQIC02_NAME
+              ": decode_qic_exception_nr: exception(%x) not recognized\n",
+              s);
+       return 0;
+}                              /* decode_qic_exception_nr */
 
 
 
@@ -394,44 +408,36 @@ static int decode_qic_exception_nr(unsigned s)
  */
 static void handle_qic_exception(int exnr, int exbits)
 {
-    if (exnr==EXC_NCART)
-    {
-       /* Cartridge was changed. Redo sense().
-        * EXC_NCART should be handled in open().
-        * It is not permitted to remove the tape while
-        * the tape driver has open files. 
-        */
-       need_rewind = YES;
-       status_eof_detected = NO;
-       status_eom_detected = NO;
-    }
-    else if (exnr==EXC_XFILLER)
-    {
-       tpqputs(TPQD_ALWAYS, "[Bad block -- filler data transferred.]");
-    }
-    else if (exnr==EXC_XBAD)
-    {
-       tpqputs(TPQD_ALWAYS, "[CRC failed!]");
-    }
-    else if (exnr==EXC_MARGINAL)
-    {
-       /* A marginal block behaves much like a FM.
-        * User may continue reading, if desired.
-        */
-       tpqputs(TPQD_ALWAYS, "[Marginal block]");
-       doing_read = NO;
-    }
-    else if (exnr==EXC_FM)
-    {
-       doing_read = NO;
-    }
-} /* handle_qic_exception */
+       if (exnr == EXC_NCART) {
+               /* Cartridge was changed. Redo sense().
+                * EXC_NCART should be handled in open().
+                * It is not permitted to remove the tape while
+                * the tape driver has open files. 
+                */
+               need_rewind = YES;
+               status_eof_detected = NO;
+               status_eom_detected = NO;
+       } else if (exnr == EXC_XFILLER) {
+               tpqputs(TPQD_ALWAYS,
+                       "[Bad block -- filler data transferred.]");
+       } else if (exnr == EXC_XBAD) {
+               tpqputs(TPQD_ALWAYS, "[CRC failed!]");
+       } else if (exnr == EXC_MARGINAL) {
+               /* A marginal block behaves much like a FM.
+                * User may continue reading, if desired.
+                */
+               tpqputs(TPQD_ALWAYS, "[Marginal block]");
+               doing_read = NO;
+       } else if (exnr == EXC_FM) {
+               doing_read = NO;
+       }
+}                              /* handle_qic_exception */
 
 
 static inline int is_exception(void)
 {
-    return (inb(QIC02_STAT_PORT) & QIC02_STAT_EXCEPTION) == 0;
-} /* is_exception */
+       return (inb(QIC02_STAT_PORT) & QIC02_STAT_EXCEPTION) == 0;
+}                              /* is_exception */
 
 
 /* Reset the tape drive and controller.
@@ -440,54 +446,49 @@ static inline int is_exception(void)
  */
 static int tape_reset(int verbose)
 {
-    ifc_init();                                /* reset interface card */
-
-    /* assert reset */
-    if (QIC02_TAPE_IFC == MOUNTAIN)
-    {
-       outb_p(ctlbits & ~MTN_QIC02_CTL_RESET_NOT, QIC02_CTL_PORT);
-    }
-    else /* WANGTEK, ARCHIVE */
-    {
-       outb_p(ctlbits | QIC02_CTL_RESET, QIC02_CTL_PORT);
-    }
-    
-    /* Next, we need to wait >=25 usec. */
-    udelay(30);
-
-    /* after reset, we will be at BOT (modulo an automatic rewind) */
-    status_eof_detected = NO;
-    status_eom_detected = NO;
-    status_cmd_pending = 0;
-    need_rewind = YES;
-    doing_read = doing_write = NO;
-    ioctl_status.mt_fileno = ioctl_status.mt_blkno = 0;
-    
-    /* de-assert reset */
-    if (QIC02_TAPE_IFC == MOUNTAIN)
-    {
-       outb_p(ctlbits | MTN_QIC02_CTL_RESET_NOT, QIC02_CTL_PORT);
-    }
-    else
-    {
-       outb_p(ctlbits & ~QIC02_CTL_RESET, QIC02_CTL_PORT);
-    }
-    
-    /* KLUDGE FOR G++ BUG */
-    { int stat = inb_p(QIC02_STAT_PORT);
-       status_dead = ((stat & QIC02_STAT_RESETMASK) != QIC02_STAT_RESETVAL); }
-    /* if successful, inb(STAT) returned RESETVAL */
-    if (status_dead == YES)
-    {
-       printk(TPQIC02_NAME ": reset failed!\n");
-    }
-    else if (verbose)
-    {
-       printk(TPQIC02_NAME ": reset successful\n");
-    }
-    
-    return (status_dead == YES)? TE_DEAD : TE_OK;
-} /* tape_reset */
+       ifc_init();             /* reset interface card */
+
+       /* assert reset */
+       if (QIC02_TAPE_IFC == MOUNTAIN) {
+               outb_p(ctlbits & ~MTN_QIC02_CTL_RESET_NOT, QIC02_CTL_PORT);
+       } else {                /* WANGTEK, ARCHIVE */
+
+               outb_p(ctlbits | QIC02_CTL_RESET, QIC02_CTL_PORT);
+       }
+
+       /* Next, we need to wait >=25 usec. */
+       udelay(30);
+
+       /* after reset, we will be at BOT (modulo an automatic rewind) */
+       status_eof_detected = NO;
+       status_eom_detected = NO;
+       status_cmd_pending = 0;
+       need_rewind = YES;
+       doing_read = doing_write = NO;
+       ioctl_status.mt_fileno = ioctl_status.mt_blkno = 0;
+
+       /* de-assert reset */
+       if (QIC02_TAPE_IFC == MOUNTAIN) {
+               outb_p(ctlbits | MTN_QIC02_CTL_RESET_NOT, QIC02_CTL_PORT);
+       } else {
+               outb_p(ctlbits & ~QIC02_CTL_RESET, QIC02_CTL_PORT);
+       }
+
+       /* KLUDGE FOR G++ BUG */
+       {
+               int stat = inb_p(QIC02_STAT_PORT);
+               status_dead =
+                   ((stat & QIC02_STAT_RESETMASK) != QIC02_STAT_RESETVAL);
+       }
+       /* if successful, inb(STAT) returned RESETVAL */
+       if (status_dead == YES) {
+               printk(TPQIC02_NAME ": reset failed!\n");
+       } else if (verbose) {
+               printk(TPQIC02_NAME ": reset successful\n");
+       }
+
+       return (status_dead == YES) ? TE_DEAD : TE_OK;
+}                              /* tape_reset */
 
 
 
@@ -504,7 +505,7 @@ static int notify_cmd(char cmd, short ignore_ex)
 {
        int i;
 
-       outb_p(cmd, QIC02_CMD_PORT);    /* output the command */
+       outb_p(cmd, QIC02_CMD_PORT);    /* output the command */
 
        /* wait 1 usec before asserting /REQUEST */
        udelay(1);
@@ -512,7 +513,7 @@ static int notify_cmd(char cmd, short ignore_ex)
        if ((!ignore_ex) && is_exception()) {
                tpqputs(TPQD_ALWAYS, "*** exception detected in notify_cmd");
                /** force a reset here **/
-               if (tape_reset(1)==TE_DEAD)
+               if (tape_reset(1) == TE_DEAD)
                        return TE_DEAD;
                if (is_exception()) {
                        tpqputs(TPQD_ALWAYS, "exception persists after reset.");
@@ -520,33 +521,36 @@ static int notify_cmd(char cmd, short ignore_ex)
                }
        }
 
-       outb_p(ctlbits | QIC02_CTL_REQUEST, QIC02_CTL_PORT);  /* set request bit */
+       outb_p(ctlbits | QIC02_CTL_REQUEST, QIC02_CTL_PORT);    /* set request bit */
        i = TAPE_NOTIFY_TIMEOUT;
        /* The specs say this takes about 500 usec, but there is no upper limit!
         * If the drive were busy retensioning or something like that,
         * it could be *much* longer!
         */
-       while ((inb_p(QIC02_STAT_PORT) & QIC02_STAT_READY) && (--i>0))
-               /*skip*/;                         /* wait for ready */
-       if (i==0) {
-               tpqputs(TPQD_ALWAYS, "timed out waiting for ready in notify_cmd");
+       while ((inb_p(QIC02_STAT_PORT) & QIC02_STAT_READY) && (--i > 0))
+               /*skip */ ;
+       /* wait for ready */
+       if (i == 0) {
+               tpqputs(TPQD_ALWAYS,
+                       "timed out waiting for ready in notify_cmd");
                status_dead = YES;
                return TE_TIM;
        }
 
-       outb_p(ctlbits & ~QIC02_CTL_REQUEST, QIC02_CTL_PORT); /* reset request bit */
+       outb_p(ctlbits & ~QIC02_CTL_REQUEST, QIC02_CTL_PORT);   /* reset request bit */
        i = TAPE_NOTIFY_TIMEOUT;
        /* according to the specs this one should never time-out */
-       while (((inb_p(QIC02_STAT_PORT) & QIC02_STAT_READY) == 0) && (--i>0))
-               /*skip*/;                         /* wait for not ready */
-       if (i==0) {
+       while (((inb_p(QIC02_STAT_PORT) & QIC02_STAT_READY) == 0) && (--i > 0))
+               /*skip */ ;
+       /* wait for not ready */
+       if (i == 0) {
                tpqputs(TPQD_ALWAYS, "timed out waiting for !ready in notify_cmd");
                status_dead = YES;
                return TE_TIM;
        }
        /* command accepted */
        return TE_OK;
-} /* notify_cmd */
+}                              /* notify_cmd */
 
 
 
@@ -563,20 +567,22 @@ static int wait_for_ready(time_t timeout)
         * First, busy wait a few usec:
         */
        spin_t = 50;
-       while (((stat = inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK) && (--spin_t>0))
+       while (((stat = inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK) && (--spin_t > 0))
                /*SKIP*/;
        if ((stat & QIC02_STAT_READY) == 0)
-               return TE_OK;                   /* covers 99.99% of all calls */
+               return TE_OK;   /* covers 99.99% of all calls */
 
        /* Then use schedule() a few times */
-       spin_t = 3;     /* max 0.03 sec busy waiting */
+       spin_t = 3;             /* max 0.03 sec busy waiting */
        if (spin_t > timeout)
                spin_t = timeout;
        timeout -= spin_t;
        spin_t += jiffies;
 
-       while (((stat = inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK) && time_before(jiffies, spin_t))
-               schedule();             /* don't waste all the CPU time */
+       /* FIXME...*/
+       while (((stat = inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK) 
+               && time_before(jiffies, spin_t))
+               schedule();     /* don't waste all the CPU time */
        if ((stat & QIC02_STAT_READY) == 0)
                return TE_OK;
 
@@ -589,13 +595,13 @@ static int wait_for_ready(time_t timeout)
        spin_t += timeout;
        TPQDEB({printk("wait_for_ready: additional timeout: %d\n", spin_t);})
 
-               /* not ready and no exception && timeout not expired yet */
+           /* not ready and no exception && timeout not expired yet */
        while (((stat = inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK) && time_before(jiffies, spin_t)) {
                /* be `nice` to other processes on long operations... */
                current->state = TASK_INTERRUPTIBLE;
                /* nap 0.30 sec between checks, */
                /* but could be woken up earlier by signals... */
-               schedule_timeout(3*HZ/10);
+               schedule_timeout(3 * HZ / 10);
        }
 
        /* don't use jiffies for this test because it may have changed by now */
@@ -605,12 +611,13 @@ static int wait_for_ready(time_t timeout)
        }
 
        if ((stat & QIC02_STAT_EXCEPTION) == 0) {
-               tpqputs(TPQD_ALWAYS, "exception detected after waiting_for_ready");
+               tpqputs(TPQD_ALWAYS,
+                       "exception detected after waiting_for_ready");
                return TE_EX;
        } else {
                return TE_OK;
        }
-} /* wait_for_ready */
+}                              /* wait_for_ready */
 
 
 
@@ -619,7 +626,7 @@ static int send_qic02_data(char sb[], unsigned size, int ignore_ex)
 {
        int i, stat;
 
-       for (i=0; i<size; i++) {
+       for (i = 0; i < size; i++) {
 
                stat = wait_for_ready(TIM_S);
                if (stat != TE_OK)
@@ -630,8 +637,8 @@ static int send_qic02_data(char sb[], unsigned size, int ignore_ex)
                        return stat;
        }
        return TE_OK;
-       
-} /* send_qic02_data */
+
+}                              /* send_qic02_data */
 
 
 /* Send a QIC-02 command (`cmd') to the tape drive, with
@@ -650,7 +657,7 @@ static int send_qic02_cmd(int cmd, time_t timeout, int ignore_ex)
                tpqputs(TPQD_ALWAYS, "send_qic02_cmd: Exception!");
                return TE_EX;
        }
-       if (stat & QIC02_STAT_READY) {                  /* if not ready */
+       if (stat & QIC02_STAT_READY) {  /* if not ready */
                tpqputs(TPQD_ALWAYS, "send_qic02_cmd: not Ready!");
                return TE_ERR;
        }
@@ -662,8 +669,8 @@ static int send_qic02_cmd(int cmd, time_t timeout, int ignore_ex)
         */
        status_cmd_pending = cmd;
 
-       stat = notify_cmd(cmd, ignore_ex); /* tell drive new command was loaded, */
-                                          /* inherit exception check. */
+       stat = notify_cmd(cmd, ignore_ex);      /* tell drive new command was loaded, */
+       /* inherit exception check. */
        if (TP_HAVE_SEEK && (cmd == AR_QCMDV_SEEK_BLK)) {
                /* This one needs to send 3 more bytes, MSB first */
                stat = send_qic02_data(seek_addr_buf, sizeof(seek_addr_buf), ignore_ex);
@@ -673,7 +680,7 @@ static int send_qic02_cmd(int cmd, time_t timeout, int ignore_ex)
                tpqputs(TPQD_ALWAYS, "send_qic02_cmd failed");
        }
        return stat;
-} /* send_qic02_cmd */
+}                              /* send_qic02_cmd */
 
 
 
@@ -683,8 +690,8 @@ static int send_qic02_cmd(int cmd, time_t timeout, int ignore_ex)
  */
 static int rdstatus(char *stp, unsigned size, char qcmd)
 {
-       int     s, n;
-       char    *q = stp;
+       int s, n;
+       char *q = stp;
 
        /* Try to busy-wait a few (700) usec, after that de-schedule.
         *
@@ -693,21 +700,22 @@ static int rdstatus(char *stp, unsigned size, char qcmd)
         * de-schedule immediately, we waste a lot of time because a
         * task switch is much longer than we usually have to wait here.
         */
-       n = 1000;       /* 500 is not enough on a 486/33 */
-       while ((n>0) && ((inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK))
-               n--;  /* wait for ready or exception or timeout */
-       if (n==0) {
+       n = 1000;               /* 500 is not enough on a 486/33 */
+       while ((n > 0) && ((inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK))
+               n--;            /* wait for ready or exception or timeout */
+       if (n == 0) {
                /* n (above) should be chosen such that on your machine
                 * you rarely ever see the message below, and it should
                 * be small enough to give reasonable response time.]
                 */
+               /* FIXME */
                tpqputs(TPQD_ALWAYS, "waiting looong in rdstatus() -- drive dead?");
                while ((inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK)
                        schedule();
                tpqputs(TPQD_ALWAYS, "finished waiting in rdstatus()");
        }
 
-       (void) notify_cmd(qcmd, 1);                     /* send read status command */
+       (void) notify_cmd(qcmd, 1);     /* send read status command */
        /* ignore return code -- should always be ok, STAT may contain 
         * exception flag from previous exception which we are trying to clear.
         */
@@ -715,21 +723,22 @@ static int rdstatus(char *stp, unsigned size, char qcmd)
        if (TP_DIAGS(current_tape_dev))
                printk(TPQIC02_NAME ": reading status bytes: ");
 
-       for (q=stp; q<stp+size; q++)
-       {
-               do s = inb_p(QIC02_STAT_PORT);
+       for (q = stp; q < stp + size; q++) {
+               do
+                       s = inb_p(QIC02_STAT_PORT);
                while ((s & QIC02_STAT_MASK) == QIC02_STAT_MASK);       /* wait for ready or exception */
 
-               if ((s & QIC02_STAT_EXCEPTION) == 0) {          /* if exception */
+               if ((s & QIC02_STAT_EXCEPTION) == 0) {  /* if exception */
                        tpqputs(TPQD_ALWAYS, "rdstatus: exception error");
-                       ioctl_status.mt_erreg = 0;              /* dunno... */
-                       return TE_NS;                           /* error, shouldn't happen... */
+                       ioctl_status.mt_erreg = 0;      /* dunno... */
+                       return TE_NS;   /* error, shouldn't happen... */
                }
 
-               *q = inb_p(QIC02_DATA_PORT);                    /* read status byte */
+               *q = inb_p(QIC02_DATA_PORT);    /* read status byte */
 
                if (TP_DIAGS(current_tape_dev))
-                       printk("[%1d]=0x%x  ", q-stp, (unsigned) (*q) & 0xff);
+                       printk("[%1d]=0x%x  ", q - stp,
+                              (unsigned) (*q) & 0xff);
 
                outb_p(ctlbits | QIC02_CTL_REQUEST, QIC02_CTL_PORT);    /* set request */
 
@@ -745,13 +754,14 @@ static int rdstatus(char *stp, unsigned size, char qcmd)
         * My drive doesn't seem to need it here yet, but others do?
         */
        while (inb_p(QIC02_STAT_PORT) & QIC02_STAT_READY)
-               /*skip*/;                         /* wait for ready */
+               /*skip */ ;
+       /* wait for ready */
 
        if (TP_DIAGS(current_tape_dev))
                printk("\n");
 
        return TE_OK;
-} /* rdstatus */
+}                              /* rdstatus */
 
 
 
@@ -769,7 +779,7 @@ static int get_status(volatile struct tpstatus *stp)
        /* should probably swap status bytes #definition */
 #endif
        return stat;
-} /* get_status */
+}                              /* get_status */
 
 
 #if 0
@@ -782,7 +792,7 @@ static int get_status(volatile struct tpstatus *stp)
  */
 static int get_ext_status3(void)
 {
-       char vus[64];   /* vendor unique status */
+       char vus[64];           /* vendor unique status */
        int stat, i;
 
        tpqputs(TPQD_ALWAYS, "Attempting to read Extended Status 3...");
@@ -791,15 +801,15 @@ static int get_ext_status3(void)
                return stat;
 
        tpqputs(TPQD_ALWAYS, "Returned status bytes:");
-       for (i=0; i<sizeof(vus); i++) {
-               if ( i % 8 == 0 )
+       for (i = 0; i < sizeof(vus); i++) {
+               if (i % 8 == 0)
                        printk("\n" TPQIC02_NAME ": %2d:");
                printk(" %2x", vus[i] & 0xff);
        }
        printk("\n");
 
        return TE_OK;
-} /* get_ext_status3 */
+}                              /* get_ext_status3 */
 #endif
 
 
@@ -812,13 +822,14 @@ static int tp_sense(int ignore)
        static void finish_rw(int cmd);
 
        if (TPQDBG(SENSE_TEXT))
-               printk(TPQIC02_NAME ": tp_sense(ignore=0x%x) enter\n", ignore);
+               printk(TPQIC02_NAME ": tp_sense(ignore=0x%x) enter\n",
+                      ignore);
 
        /* sense() is not allowed during a read or write cycle */
        if (doing_write == YES)
                tpqputs(TPQD_ALWAYS, "Warning: File Mark inserted because of sense() request");
        /* The extra test is to avoid calling finish_rw during booting */
-       if ((doing_read!=NO) || (doing_write!=NO))
+       if ((doing_read != NO) || (doing_write != NO))
                finish_rw(QCMD_RD_STAT);
 
        if (get_status(&tperror) != TE_OK) {
@@ -827,27 +838,29 @@ static int tp_sense(int ignore)
        }
 
        err = tperror.exs;      /* get exception status bits */
-       if (err & (TP_ST0|TP_ST1))
+       if (err & (TP_ST0 | TP_ST1))
                printk(TPQIC02_NAME ": tp_sense: status: %x, error count: %d, underruns: %d\n",
-                       tperror.exs, tperror.dec, tperror.urc);
-       else if ((tperror.dec!=0) || (tperror.urc!=0) || TPQDBG(SENSE_CNTS))
-               printk(TPQIC02_NAME ": tp_sense: no hard errors, soft error count: %d, underruns: %d\n",
-                       tperror.dec, tperror.urc);
+                      tperror.exs, tperror.dec, tperror.urc);
+       else if ((tperror.dec != 0) || (tperror.urc != 0)
+                || TPQDBG(SENSE_CNTS))
+               printk(TPQIC02_NAME
+                      ": tp_sense: no hard errors, soft error count: %d, underruns: %d\n",
+                      tperror.dec, tperror.urc);
 
        /* Set generic status. HP-UX defines these, but some extra would 
         * be useful. Problem is to remain compatible. [Do we want to be
         * compatible??]
         */
        if (err & TP_ST0) {
-               if (err & TP_CNI)               /* no cartridge */
+               if (err & TP_CNI)       /* no cartridge */
                        gs |= GMT_DR_OPEN(-1);
                if (status_dead == NO)
                        gs |= GMT_ONLINE(-1);   /* always online */
-               if (err & TP_USL)               /* not online */
+               if (err & TP_USL)       /* not online */
                        gs &= ~GMT_ONLINE(-1);
                if (err & TP_WRP)
                        gs |= GMT_WR_PROT(-1);
-               if (err & TP_EOM) {             /* end of media */
+               if (err & TP_EOM) {     /* end of media */
                        gs |= GMT_EOT(-1);      /* not sure this is correct for writes */
                        status_eom_detected = YES;
                        /* I don't know whether drive always reports EOF at or before EOM. */
@@ -871,10 +884,10 @@ static int tp_sense(int ignore)
        ioctl_status.mt_dsreg = tperror.exs;    /* "drive status" */
        ioctl_status.mt_erreg = tperror.dec;    /* "sense key error" */
 
-       if (err & (TP_ST0|TP_ST1)) {
+       if (err & (TP_ST0 | TP_ST1)) {
                /* My Wangtek occasionally reports `status' 1212 which should be ignored. */
                exnr = decode_qic_exception_nr(err);
-               handle_qic_exception(exnr, err);                /* update driver state wrt drive status */
+               handle_qic_exception(exnr, err);        /* update driver state wrt drive status */
                report_qic_exception(exnr);
        }
        err &= ~ignore;         /* mask unwanted errors -- not the correct way, use exception nrs?? */
@@ -882,7 +895,7 @@ static int tp_sense(int ignore)
            ((err & TP_ST1) && (err & REPORT_ERR1)))
                return TE_ERR;
        return TE_OK;
-} /* tp_sense */
+}                              /* tp_sense */
 
 
 
@@ -895,15 +908,17 @@ static int wait_for_rewind(time_t timeout)
 
        stat = inb(QIC02_STAT_PORT) & QIC02_STAT_MASK;
        if (TPQDBG(REWIND))
-               printk(TPQIC02_NAME ": Waiting for (re-)wind to finish: stat=0x%x\n", stat);
+               printk(TPQIC02_NAME
+                      ": Waiting for (re-)wind to finish: stat=0x%x\n",
+                      stat);
 
        stat = wait_for_ready(timeout);
 
        if (stat != TE_OK) {
-                       tpqputs(TPQD_ALWAYS, "(re-) winding failed\n");
+               tpqputs(TPQD_ALWAYS, "(re-) winding failed\n");
        }
        return stat;
-} /* wait_for_rewind */
+}                              /* wait_for_rewind */
 
 
 
@@ -919,22 +934,21 @@ static int ll_do_qic_cmd(int cmd, time_t timeout)
 
        if (status_dead == YES) {
                tpqputs(TPQD_ALWAYS, "Drive is dead. Do a `mt reset`.");
-               return -ENXIO;                  /* User should do an MTRESET. */
+               return -ENXIO;  /* User should do an MTRESET. */
        }
 
-       stat = wait_for_ready(timeout);         /* wait for ready or exception */
+       stat = wait_for_ready(timeout); /* wait for ready or exception */
        if (stat == TE_EX) {
-               if (tp_sense(TP_WRP|TP_BOM|TP_EOM|TP_FIL)!=TE_OK)
+               if (tp_sense(TP_WRP | TP_BOM | TP_EOM | TP_FIL) != TE_OK)
                        return -EIO;
                /* else nothing to worry about, I hope */
                stat = TE_OK;
        }
        if (stat != TE_OK) {
-               printk(TPQIC02_NAME ": ll_do_qic_cmd(%x, %ld) failed\n", cmd, (long) timeout);
+               printk(TPQIC02_NAME ": ll_do_qic_cmd(%x, %ld) failed\n",
+                      cmd, (long) timeout);
                return -EIO;
        }
-
-
 #if OBSOLETE
        /* wait for ready since it may not be active immediately after reading status */
        while ((inb_p(QIC02_STAT_PORT) & QIC02_STAT_READY) != 0);
@@ -942,16 +956,17 @@ static int ll_do_qic_cmd(int cmd, time_t timeout)
 
        stat = send_qic02_cmd(cmd, timeout, 0); /* (checks for exceptions) */
 
-       if (cmd==QCMD_RD_FM) {
+       if (cmd == QCMD_RD_FM) {
                status_eof_detected = NO;
                ioctl_status.mt_fileno++;
                /* Should update block count as well, but can't.
                 * Can do a `read address' for some drives, when MTNOP is done.
                 */
-       } else if (cmd==QCMD_WRT_FM) {
+       } else if (cmd == QCMD_WRT_FM) {
                status_eof_detected = NO;
                ioctl_status.mt_fileno++;
-       } else if ((cmd==QCMD_REWIND) || (cmd==QCMD_ERASE) || (cmd==QCMD_RETEN)) {
+       } else if ((cmd == QCMD_REWIND) || (cmd == QCMD_ERASE)
+                  || (cmd == QCMD_RETEN)) {
                status_eof_detected = NO;
                status_eom_detected = NO;
                status_eot_detected = NO;
@@ -964,16 +979,19 @@ static int ll_do_qic_cmd(int cmd, time_t timeout)
                reported_write_eof = NO;
        }
        /* sense() will set eof/eom as required */
-       if (stat==TE_EX) {
-               if (tp_sense(TP_WRP|TP_BOM|TP_EOM|TP_FIL)!=TE_OK) {
-                       printk(TPQIC02_NAME ": Exception persist in ll_do_qic_cmd[1](%x, %ld)", cmd, (long) timeout);
+       if (stat == TE_EX) {
+               if (tp_sense(TP_WRP | TP_BOM | TP_EOM | TP_FIL) != TE_OK) {
+                       printk(TPQIC02_NAME
+                              ": Exception persist in ll_do_qic_cmd[1](%x, %ld)",
+                              cmd, (long) timeout);
                        status_dead = YES;
                        return -ENXIO;
                        /* if rdstatus fails too, we're in trouble */
                }
-       }
-       else if (stat!=TE_OK) {
-               printk(TPQIC02_NAME ": ll_do_qic_cmd: send_qic02_cmd failed, stat = 0x%x\n", stat);
+       } else if (stat != TE_OK) {
+               printk(TPQIC02_NAME
+                      ": ll_do_qic_cmd: send_qic02_cmd failed, stat = 0x%x\n",
+                      stat);
                return -EIO;    /*** -EIO is probably not always appropriate */
        }
 
@@ -983,23 +1001,27 @@ static int ll_do_qic_cmd(int cmd, time_t timeout)
        else
                stat = wait_for_ready(timeout);
 
-       if (stat==TE_EX) {
-               if (tp_sense((cmd==QCMD_SEEK_EOD ?              /*****************************/
-                     TP_EOR|TP_NDT|TP_UDA|TP_BNL|TP_WRP|TP_BOM|TP_EOM|TP_FIL :
-                     TP_WRP|TP_BOM|TP_EOM|TP_FIL))!=TE_OK) {
-                       printk(TPQIC02_NAME ": Exception persist in ll_do_qic_cmd[2](%x, %ld)\n", cmd, (long) timeout);
-                       if (cmd!=QCMD_RD_FM)
+       if (stat == TE_EX) {
+               if (tp_sense((cmd == QCMD_SEEK_EOD ?            /*****************************/
+                             TP_EOR | TP_NDT | TP_UDA | TP_BNL | TP_WRP |
+                             TP_BOM | TP_EOM | TP_FIL : TP_WRP | TP_BOM |
+                             TP_EOM | TP_FIL)) != TE_OK) {
+                       printk(TPQIC02_NAME
+                              ": Exception persist in ll_do_qic_cmd[2](%x, %ld)\n",
+                              cmd, (long) timeout);
+                       if (cmd != QCMD_RD_FM)
                                status_dead = YES;
                        return -ENXIO;
                        /* if rdstatus fails too, we're in trouble */
                }
-       }
-       else if (stat!=TE_OK) {
-               printk(TPQIC02_NAME ": ll_do_qic_cmd %x: wait failed, stat == 0x%x\n", cmd, stat);
+       } else if (stat != TE_OK) {
+               printk(TPQIC02_NAME
+                      ": ll_do_qic_cmd %x: wait failed, stat == 0x%x\n",
+                      cmd, stat);
                return -EIO;
        }
        return 0;
-} /* ll_do_qic_cmd */
+}                              /* ll_do_qic_cmd */
 
 
 /* 
@@ -1042,17 +1064,20 @@ static void terminate_read(int cmd)
                                /* Mountain reference says can terminate by de-asserting online */
                                ctlbits &= ~MTN_QIC02_CTL_ONLINE;
                        }
-                       if (tp_sense(TP_FIL|TP_EOM|TP_WRP) != TE_OK) {
-                               tpqputs(TPQD_ALWAYS, "finish_rw[read1]: ignore the 2 lines above");
+
+                       if (tp_sense(TP_FIL | TP_EOM | TP_WRP) != TE_OK) {
+                               tpqputs(TPQD_ALWAYS,
+                                       "finish_rw[read1]: ignore the 2 lines above");
                                if (is_exception()) {
-                                       if (tp_sense(TP_ILL|TP_FIL|TP_EOM|TP_WRP) != TE_OK)
-                                               tpqputs(TPQD_ALWAYS, "finish_rw[read2]: read cycle error");
+                                       if (tp_sense
+                                           (TP_ILL | TP_FIL | TP_EOM |
+                                            TP_WRP) != TE_OK)
+                                               tpqputs(TPQD_ALWAYS,"finish_rw[read2]: read cycle error");
                                }
                        }
                }
        }
-} /* terminate_read */
+}                              /* terminate_read */
 
 
 static void terminate_write(int cmd)
@@ -1066,28 +1091,30 @@ static void terminate_write(int cmd)
                        /* finish off write cycle */
                        stat = ll_do_qic_cmd(QCMD_WRT_FM, TIM_M);
                        if (stat != TE_OK)
-                               tpqputs(TPQD_ALWAYS, "Couldn't finish write cycle properly");
+                               tpqputs(TPQD_ALWAYS,
+                                       "Couldn't finish write cycle properly");
                        (void) tp_sense(0);
                }
                /* If there is an EOF token waiting to be returned to
                 * the (writing) application, discard it now.
                 * We could be at EOT, so don't reset return_write_eof.
                 */
-               reported_write_eof=YES;
+               reported_write_eof = YES;
        }
-} /* terminate_write */
+}                              /* terminate_write */
 
 
 /* terminate read or write cycle because of command `cmd' */
 static void finish_rw(int cmd)
 {
        if (wait_for_ready(TIM_S) != TE_OK) {
-               tpqputs(TPQD_ALWAYS, "error: drive not ready in finish_rw() !");
+               tpqputs(TPQD_ALWAYS,
+                       "error: drive not ready in finish_rw() !");
                return;
        }
        terminate_read(cmd);
        terminate_write(cmd);
-} /* finish_rw */
+}                              /* finish_rw */
 
 
 /* Perform a QIC command through ll_do_qic_cmd().
@@ -1109,12 +1136,12 @@ static int do_qic_cmd(int cmd, time_t timeout)
                        return stat;
                }
                need_rewind = NO;
-               if (cmd==QCMD_REWIND)   /* don't wind beyond BOT ;-) */
+               if (cmd == QCMD_REWIND) /* don't wind beyond BOT ;-) */
                        return 0;
        }
 
        return ll_do_qic_cmd(cmd, timeout);
-} /* do_qic_cmd */
+}                              /* do_qic_cmd */
 
 
 /* Not all ioctls are supported for all drives. Some rely on
@@ -1132,217 +1159,218 @@ static int do_ioctl_cmd(int cmd)
         */
 
        switch (cmd) {
-               case MTRESET:
-                       /* reset verbose */
-                       return (tape_reset(1)==TE_OK)? 0 : -EIO;
-
-               case MTFSF:
-                       tpqputs(TPQD_IOCTLS, "MTFSF forward searching filemark");
-                       if ((mode_access==WRITE) && status_bytes_wr)
+       case MTRESET:
+               /* reset verbose */
+               return (tape_reset(1) == TE_OK) ? 0 : -EIO;
+
+       case MTFSF:
+               tpqputs(TPQD_IOCTLS, "MTFSF forward searching filemark");
+               if ((mode_access == WRITE) && status_bytes_wr)
+                       return -EACCES;
+               return do_qic_cmd(QCMD_RD_FM, TIM_F);
+
+       case MTBSF:
+               if (TP_HAVE_BSF) {
+                       tpqputs(TPQD_IOCTLS,
+                               "MTBSF backward searching filemark -- optional command");
+                       if ((mode_access == WRITE) && status_bytes_wr)
                                return -EACCES;
-                       return do_qic_cmd(QCMD_RD_FM, TIM_F);
-
-               case MTBSF:
-                       if (TP_HAVE_BSF) {
-                               tpqputs(TPQD_IOCTLS, "MTBSF backward searching filemark -- optional command");
-                               if ((mode_access==WRITE) && status_bytes_wr)
-                                       return -EACCES;
-                               stat = do_qic_cmd(QCMD_RD_FM_BCK, TIM_F);
-                       } else {
-                               stat = -ENXIO;
-                       }
-                       status_eom_detected = status_eof_detected = NO;
-                       return stat;
-
-               case MTFSR:
-                       if (TP_HAVE_FSR) { /* This is an optional QIC-02 command */
-                               tpqputs(TPQD_IOCTLS, "MTFSR forward space record");
-                               if ((mode_access==WRITE) && status_bytes_wr)
-                                       return -EACCES;
-                               stat = do_qic_cmd(QCMD_SPACE_FWD, TIM_F);
-                       } else {
-                               /**** fake it by doing a read data block command? ******/
-                               tpqputs(TPQD_IOCTLS, "MTFSR not supported");
-                               stat = -ENXIO;
-                       }
-                       return stat;
-
-               case MTBSR:
-                       if (TP_HAVE_BSR) { /* This is an optional QIC-02 command */
-                               /* we need this for appending files with GNU tar!! */
-                               tpqputs(TPQD_IOCTLS, "MTFSR backward space record");
-                               if ((mode_access==WRITE) && status_bytes_wr)
-                                       return -EACCES;
-                               stat = do_qic_cmd(QCMD_SPACE_BCK, TIM_F);
-                       } else {
-                               tpqputs(TPQD_IOCTLS, "MTBSR not supported");
-                               stat = -ENXIO;
-                       }
-                       status_eom_detected = status_eof_detected = NO;
-                       return stat;
+                       stat = do_qic_cmd(QCMD_RD_FM_BCK, TIM_F);
+               } else {
+                       stat = -ENXIO;
+               }
+               status_eom_detected = status_eof_detected = NO;
+               return stat;
 
-               case MTWEOF:
-                       tpqputs(TPQD_IOCTLS, "MTWEOF write eof mark");
-                       /* Plain GNU mt(1) 2.2 uses read-only mode for writing FM. :-( */
-                       if (mode_access==READ)
+       case MTFSR:
+               if (TP_HAVE_FSR) {      /* This is an optional QIC-02 command */
+                       tpqputs(TPQD_IOCTLS, "MTFSR forward space record");
+                       if ((mode_access == WRITE) && status_bytes_wr)
                                return -EACCES;
+                       stat = do_qic_cmd(QCMD_SPACE_FWD, TIM_F);
+               } else {
+                               /**** fake it by doing a read data block command? ******/
+                       tpqputs(TPQD_IOCTLS, "MTFSR not supported");
+                       stat = -ENXIO;
+               }
+               return stat;
 
-                       /* allow tape movement after writing FM */
-                       status_bytes_rd = status_bytes_wr;      /* Kludge-O-Matic */
-                       status_bytes_wr = NO;
-                       return do_qic_cmd(QCMD_WRT_FM, TIM_M);
-                       /* not sure what to do with status_bytes when WFM should fail */
-
-               case MTREW:
-                       tpqputs(TPQD_IOCTLS, "MTREW rewinding tape");
-                       if ((mode_access==WRITE) && status_bytes_wr)
+       case MTBSR:
+               if (TP_HAVE_BSR) {      /* This is an optional QIC-02 command */
+                       /* we need this for appending files with GNU tar!! */
+                       tpqputs(TPQD_IOCTLS, "MTFSR backward space record");
+                       if ((mode_access == WRITE) && status_bytes_wr)
                                return -EACCES;
-                       status_eom_detected = status_eof_detected = NO;
-                       return do_qic_cmd(QCMD_REWIND, TIM_R);
+                       stat = do_qic_cmd(QCMD_SPACE_BCK, TIM_F);
+               } else {
+                       tpqputs(TPQD_IOCTLS, "MTBSR not supported");
+                       stat = -ENXIO;
+               }
+               status_eom_detected = status_eof_detected = NO;
+               return stat;
 
-               case MTOFFL:
-                       tpqputs(TPQD_IOCTLS, "MTOFFL rewinding & going offline");
-                       /* Doing a drive select will clear (unlock) the current drive.
-                        * But that requires support for multiple drives and locking.
-                        */
-                       if ((mode_access==WRITE) && status_bytes_wr)
-                               return -EACCES;
-                       status_eom_detected = status_eof_detected = NO;
+       case MTWEOF:
+               tpqputs(TPQD_IOCTLS, "MTWEOF write eof mark");
+               /* Plain GNU mt(1) 2.2 uses read-only mode for writing FM. :-( */
+               if (mode_access == READ)
+                       return -EACCES;
+
+               /* allow tape movement after writing FM */
+               status_bytes_rd = status_bytes_wr;      /* Kludge-O-Matic */
+               status_bytes_wr = NO;
+               return do_qic_cmd(QCMD_WRT_FM, TIM_M);
+               /* not sure what to do with status_bytes when WFM should fail */
+
+       case MTREW:
+               tpqputs(TPQD_IOCTLS, "MTREW rewinding tape");
+               if ((mode_access == WRITE) && status_bytes_wr)
+                       return -EACCES;
+               status_eom_detected = status_eof_detected = NO;
+               return do_qic_cmd(QCMD_REWIND, TIM_R);
+
+       case MTOFFL:
+               tpqputs(TPQD_IOCTLS, "MTOFFL rewinding & going offline");
+               /* Doing a drive select will clear (unlock) the current drive.
+                * But that requires support for multiple drives and locking.
+                */
+               if ((mode_access == WRITE) && status_bytes_wr)
+                       return -EACCES;
+               status_eom_detected = status_eof_detected = NO;
                        /**** do rewind depending on minor bits??? ***/
-                       stat = do_qic_cmd(QCMD_REWIND, TIM_R);
-                       return stat;
+               stat = do_qic_cmd(QCMD_REWIND, TIM_R);
+               return stat;
 
-               case MTNOP:
-                       tpqputs(TPQD_IOCTLS, "MTNOP setting status only");
+       case MTNOP:
+               tpqputs(TPQD_IOCTLS, "MTNOP setting status only");
                        /********** should do `read position' for drives that support it **********/
-                       return (tp_sense(-1)==TE_OK)? 0 : -EIO; /**** check return codes ****/
-
-               case MTRETEN:
-                       tpqputs(TPQD_IOCTLS, "MTRETEN retension tape");
-                       if ((mode_access==WRITE) && status_bytes_wr)
-                               return -EACCES;
-                       status_eom_detected = status_eof_detected = NO;
-                       return do_qic_cmd(QCMD_RETEN, TIM_R);
-
-               case MTBSFM:
-                       /* Think think is like MTBSF, except that
-                        * we shouldn't skip the FM. Tricky.
-                        * Maybe use RD_FM_BCK, then do a SPACE_FWD?
-                        */
-                       tpqputs(TPQD_IOCTLS, "MTBSFM not supported");
-                       if ((mode_access==WRITE) && status_bytes_wr)
-                               return -EACCES;
-                       return -ENXIO;
+               return (tp_sense(-1) == TE_OK) ? 0 : -EIO;      /**** check return codes ****/
+
+       case MTRETEN:
+               tpqputs(TPQD_IOCTLS, "MTRETEN retension tape");
+               if ((mode_access == WRITE) && status_bytes_wr)
+                       return -EACCES;
+               status_eom_detected = status_eof_detected = NO;
+               return do_qic_cmd(QCMD_RETEN, TIM_R);
+
+       case MTBSFM:
+               /* Think think is like MTBSF, except that
+                * we shouldn't skip the FM. Tricky.
+                * Maybe use RD_FM_BCK, then do a SPACE_FWD?
+                */
+               tpqputs(TPQD_IOCTLS, "MTBSFM not supported");
+               if ((mode_access == WRITE) && status_bytes_wr)
+                       return -EACCES;
+               return -ENXIO;
 
-               case MTFSFM:
-                       /* I think this is like MTFSF, except that
-                        * we shouldn't skip the FM. Tricky.
-                        * Maybe use QCMD_RD_DATA until we get a TP_FIL exception?
-                        * But then the FM will have been skipped...
-                        * Maybe use RD_FM, then RD_FM_BCK, but not all
-                        * drives will support that!
-                        */
-                       tpqputs(TPQD_IOCTLS, "MTFSFM not supported");
-                       if ((mode_access==WRITE) && status_bytes_wr)
-                               return -EACCES;
-                       return -ENXIO;
+       case MTFSFM:
+               /* I think this is like MTFSF, except that
+                * we shouldn't skip the FM. Tricky.
+                * Maybe use QCMD_RD_DATA until we get a TP_FIL exception?
+                * But then the FM will have been skipped...
+                * Maybe use RD_FM, then RD_FM_BCK, but not all
+                * drives will support that!
+                */
+               tpqputs(TPQD_IOCTLS, "MTFSFM not supported");
+               if ((mode_access == WRITE) && status_bytes_wr)
+                       return -EACCES;
+               return -ENXIO;
 
-               case MTEOM:
-                       /* This should leave the tape ready for appending
-                        * another file to the end, such that it would append
-                        * after the last FM on tape.
+       case MTEOM:
+               /* This should leave the tape ready for appending
+                * another file to the end, such that it would append
+                * after the last FM on tape.
+                */
+               tpqputs(TPQD_IOCTLS, "MTEOM search for End Of recorded Media");
+               if ((mode_access == WRITE) && status_bytes_wr)
+                       return -EACCES;
+               if (TP_HAVE_EOD) {
+                       /* Use faster seeking when possible.
+                        * This requires the absence of data beyond the EOM.
+                        * It seems that my drive does not always perform the
+                        * SEEK_EOD correctly, unless it is preceded by a
+                        * rewind command.
                         */
-                       tpqputs(TPQD_IOCTLS, "MTEOM search for End Of recorded Media");
-                       if ((mode_access==WRITE) && status_bytes_wr)
-                               return -EACCES;
-                       if (TP_HAVE_EOD) {
-                               /* Use faster seeking when possible.
-                                * This requires the absence of data beyond the EOM.
-                                * It seems that my drive does not always perform the
-                                * SEEK_EOD correctly, unless it is preceded by a
-                                * rewind command.
-                                */
 # if 0
-                               status_eom_detected = status_eof_detected = NO;
+                       status_eom_detected = status_eof_detected = NO;
 # endif
-                               stat = do_qic_cmd(QCMD_REWIND, TIM_R);
-                               if (stat)
-                                       return stat;
-                               stat = do_qic_cmd(QCMD_SEEK_EOD, TIM_F);
-                               /* After a successful seek, TP_EOR should be returned */
-                       } else {
-                               /* else just seek until the drive returns exception "No Data" */
-                               stat = 0;
-                               while ((stat==0) && (!status_eom_detected)) {
-                                       stat = do_qic_cmd(QCMD_RD_FM, TIM_F); /***** should use MTFSFM here???? ******/
-                               }
-                               if (tperror.exs & TP_NDT)
-                                       return 0;
+                       stat = do_qic_cmd(QCMD_REWIND, TIM_R);
+                       if (stat)
+                               return stat;
+                       stat = do_qic_cmd(QCMD_SEEK_EOD, TIM_F);
+                       /* After a successful seek, TP_EOR should be returned */
+               } else {
+                       /* else just seek until the drive returns exception "No Data" */
+                       stat = 0;
+                       while ((stat == 0) && (!status_eom_detected)) {
+                               stat = do_qic_cmd(QCMD_RD_FM, TIM_F);         /***** should use MTFSFM here???? ******/
                        }
-                       return stat;
-
-               case MTERASE:
-                       tpqputs(TPQD_IOCTLS, "MTERASE -- ERASE TAPE !");
-                       if  ((tperror.exs & TP_ST0) && (tperror.exs & TP_WRP)) {
-                               tpqputs(TPQD_ALWAYS, "Cartridge is write-protected.");
-                               return -EACCES;
-                       } else {
-                               time_t t = jiffies;
+                       if (tperror.exs & TP_NDT)
+                               return 0;
+               }
+               return stat;
 
-                               /* Plain GNU mt(1) 2.2 erases a tape in O_RDONLY. :-( */
-                               if (mode_access==READ) 
-                                       return -EACCES;
+       case MTERASE:
+               tpqputs(TPQD_IOCTLS, "MTERASE -- ERASE TAPE !");
+               if ((tperror.exs & TP_ST0) && (tperror.exs & TP_WRP)) {
+                       tpqputs(TPQD_ALWAYS, "Cartridge is write-protected.");
+                       return -EACCES;
+               } else {
+                       time_t t = jiffies;
 
-                               /* give user a few seconds to pull out tape */
-                               while (jiffies - t < 4*HZ)
-                                       schedule();
-                       }
+                       /* Plain GNU mt(1) 2.2 erases a tape in O_RDONLY. :-( */
+                       if (mode_access == READ)
+                               return -EACCES;
 
-                       /* don't bother writing filemark first */
-                       status_eom_detected = status_eof_detected = NO;
-                       return do_qic_cmd(QCMD_ERASE, TIM_R);
-
-               case MTRAS1:
-                       if (TP_HAVE_RAS1) {
-                               tpqputs(TPQD_IOCTLS, "MTRAS1: non-destructive self test");
-                               stat = do_qic_cmd(QCMD_SELF_TST1, TIM_R);
-                               if (stat != 0) {
-                                       tpqputs(TPQD_ALWAYS, "RAS1 failed");
-                                       return stat;
-                               }
-                               return (tp_sense(0)==TE_OK)? 0 : -EIO; /* get_ext_status3(); */
-                       }
-                       tpqputs(TPQD_IOCTLS, "RAS1 not supported");
-                       return -ENXIO;
+                       /* FIXME */
+                       /* give user a few seconds to pull out tape */
+                       while (jiffies - t < 4 * HZ)
+                               schedule();
+               }
 
-               case MTRAS2:
-                       if (TP_HAVE_RAS2) {
-                               tpqputs(TPQD_IOCTLS, "MTRAS2: destructive self test");
-                               stat = do_qic_cmd(QCMD_SELF_TST2, TIM_R);
-                               if (stat != 0) {
-                                       tpqputs(TPQD_ALWAYS, "RAS2 failed");
-                                       return stat;
-                               }
-                               return (tp_sense(0)==TE_OK)? 0 : -EIO; /* get_ext_status3(); */
+               /* don't bother writing filemark first */
+               status_eom_detected = status_eof_detected = NO;
+               return do_qic_cmd(QCMD_ERASE, TIM_R);
+
+       case MTRAS1:
+               if (TP_HAVE_RAS1) {
+                       tpqputs(TPQD_IOCTLS, "MTRAS1: non-destructive self test");
+                       stat = do_qic_cmd(QCMD_SELF_TST1, TIM_R);
+                       if (stat != 0) {
+                               tpqputs(TPQD_ALWAYS, "RAS1 failed");
+                               return stat;
                        }
-                       tpqputs(TPQD_IOCTLS, "RAS2 not supported");
-                       return -ENXIO;
+                       return (tp_sense(0) == TE_OK) ? 0 : -EIO;       /* get_ext_status3(); */
+               }
+               tpqputs(TPQD_IOCTLS, "RAS1 not supported");
+               return -ENXIO;
 
-               case MTSEEK:
-                       if (TP_HAVE_SEEK && (QIC02_TAPE_IFC==ARCHIVE)) {
-                               tpqputs(TPQD_IOCTLS, "MTSEEK seeking block");
-                               if ((mode_access==WRITE) && status_bytes_wr)
-                                       return -EACCES;
-                               /* NOTE: address (24 bits) is in seek_addr_buf[] */
-                               return do_qic_cmd(AR_QCMDV_SEEK_BLK, TIM_F);
+       case MTRAS2:
+               if (TP_HAVE_RAS2) {
+                       tpqputs(TPQD_IOCTLS, "MTRAS2: destructive self test");
+                       stat = do_qic_cmd(QCMD_SELF_TST2, TIM_R);
+                       if (stat != 0) {
+                               tpqputs(TPQD_ALWAYS, "RAS2 failed");
+                               return stat;
                        }
-                       else
-                               return -ENOTTY;
+                       return (tp_sense(0) == TE_OK) ? 0 : -EIO;       /* get_ext_status3(); */
+               }
+               tpqputs(TPQD_IOCTLS, "RAS2 not supported");
+               return -ENXIO;
 
-               default:
+       case MTSEEK:
+               if (TP_HAVE_SEEK && (QIC02_TAPE_IFC == ARCHIVE)) {
+                       tpqputs(TPQD_IOCTLS, "MTSEEK seeking block");
+                       if ((mode_access == WRITE) && status_bytes_wr)
+                               return -EACCES;
+                       /* NOTE: address (24 bits) is in seek_addr_buf[] */
+                       return do_qic_cmd(AR_QCMDV_SEEK_BLK, TIM_F);
+               } else
                        return -ENOTTY;
+
+       default:
+               return -ENOTTY;
        }
-} /* do_ioctl_cmd */
+}                              /* do_ioctl_cmd */
 
 
 /* dma_transfer(): This routine is called for every 512 bytes to be read
@@ -1362,40 +1390,43 @@ static int do_ioctl_cmd(int cmd)
  *     - adjust the timeout
  *     - tell the tape controller to start transferring
  * We assume the dma address and mode are, and remain, valid.
- */ 
+ */
 static inline void dma_transfer(void)
 {
        unsigned long flags;
 
-       if (QIC02_TAPE_IFC == WANGTEK) /* or EVEREX */
+       if (QIC02_TAPE_IFC == WANGTEK)  /* or EVEREX */
                outb_p(WT_CTL_ONLINE, QIC02_CTL_PORT);  /* back to normal */
        else if (QIC02_TAPE_IFC == ARCHIVE)
                outb_p(0, AR_RESET_DMA_PORT);
-       else /* QIC02_TAPE_IFC == MOUNTAIN */
+       else                    /* QIC02_TAPE_IFC == MOUNTAIN */
                outb_p(ctlbits, QIC02_CTL_PORT);
 
 
-       flags=claim_dma_lock();
+       flags = claim_dma_lock();
        clear_dma_ff(QIC02_TAPE_DMA);
        set_dma_mode(QIC02_TAPE_DMA, dma_mode);
-       set_dma_addr(QIC02_TAPE_DMA, virt_to_bus(buffaddr) + dma_bytes_done);
+       set_dma_addr(QIC02_TAPE_DMA,
+                    virt_to_bus(buffaddr) + dma_bytes_done);
        set_dma_count(QIC02_TAPE_DMA, TAPE_BLKSIZE);
 
        /* start tape DMA controller */
-       if (QIC02_TAPE_IFC == WANGTEK) /* or EVEREX */
-               outb_p(WT_CTL_DMA | WT_CTL_ONLINE, QIC02_CTL_PORT); /* trigger DMA transfer */
+       if (QIC02_TAPE_IFC == WANGTEK)  /* or EVEREX */
+               outb_p(WT_CTL_DMA | WT_CTL_ONLINE, QIC02_CTL_PORT);     /* trigger DMA transfer */
 
        else if (QIC02_TAPE_IFC == ARCHIVE) {
-               outb_p(AR_CTL_IEN | AR_CTL_DNIEN, QIC02_CTL_PORT);  /* enable interrupts again */
-               outb_p(0, AR_START_DMA_PORT);                     /* start DMA transfer */
+               outb_p(AR_CTL_IEN | AR_CTL_DNIEN, QIC02_CTL_PORT);      /* enable interrupts again */
+               outb_p(0, AR_START_DMA_PORT);   /* start DMA transfer */
                /* In dma_end() AR_RESET_DMA_PORT is written too. */
 
-       } else /* QIC02_TAPE_IFC == MOUNTAIN */ {
+       } else {                /* QIC02_TAPE_IFC == MOUNTAIN */
+
                inb(MTN_R_DESELECT_DMA_PORT);
-               outb_p(ctlbits | (MTN_CTL_EXC_IEN | MTN_CTL_DNIEN), QIC02_CTL_PORT);
-               outb_p(0, MTN_W_SELECT_DMA_PORT);        /* start DMA transfer */
+               outb_p(ctlbits | (MTN_CTL_EXC_IEN | MTN_CTL_DNIEN),
+                      QIC02_CTL_PORT);
+               outb_p(0, MTN_W_SELECT_DMA_PORT);       /* start DMA transfer */
                if (dma_mode == DMA_MODE_WRITE)
-                       outb_p(0, MTN_W_DMA_WRITE_PORT); /* start DMA transfer */
+                       outb_p(0, MTN_W_DMA_WRITE_PORT);        /* start DMA transfer */
        }
 
        /* start computer DMA controller */
@@ -1406,7 +1437,7 @@ static inline void dma_transfer(void)
        /* block transfer should start now, jumping to the 
         * interrupt routine when done or an exception was detected.
         */
-} /* dma_transfer */
+}                              /* dma_transfer */
 
 
 /* start_dma() sets a DMA transfer up between the tape controller and
@@ -1421,15 +1452,16 @@ static int start_dma(short mode, unsigned long bytes_todo)
 {
        int stat;
        unsigned long flags;
-       
+
        tpqputs(TPQD_DEBUG, "start_dma() enter");
-       TPQDEB({printk(TPQIC02_NAME ": doing_read==%d, doing_write==%d\n", doing_read, doing_write);})
+       TPQDEB( {printk(TPQIC02_NAME ": doing_read==%d, doing_write==%d\n",
+                     doing_read, doing_write);})
 
-       dma_bytes_done = 0;
+           dma_bytes_done = 0;
        dma_bytes_todo = bytes_todo;
        status_error = NO;
        /* dma_mode!=0 indicates that the dma controller is in use */
-       dma_mode = (mode == WRITE)? DMA_MODE_WRITE : DMA_MODE_READ;     
+       dma_mode = (mode == WRITE) ? DMA_MODE_WRITE : DMA_MODE_READ;
 
        /* Only give READ/WRITE DATA command to tape drive if we haven't
         * done that already. Otherwise the drive will rewind to the beginning
@@ -1443,22 +1475,25 @@ static int start_dma(short mode, unsigned long bytes_todo)
 
 #if 0
                /* Next dummy get status is to make sure CNI is valid,
-                   since we're only just starting a read/write it doesn't
-                   matter some exceptions are cleared by reading the status;
-                   we're only interested in CNI and WRP. -Eddy */
+                  since we're only just starting a read/write it doesn't
+                  matter some exceptions are cleared by reading the status;
+                  we're only interested in CNI and WRP. -Eddy */
                get_status(&tperror);
 #else
                /* TP_CNI should now be handled in open(). -Hennus */
 #endif
 
-               stat = tp_sense(((mode == WRITE)? 0 : TP_WRP) | TP_BOM | TP_FIL);
+               stat =
+                   tp_sense(((mode ==
+                              WRITE) ? 0 : TP_WRP) | TP_BOM | TP_FIL);
                if (stat != TE_OK)
                        return stat;
 
 #if OBSOLETE
                /************* not needed iff rd_status() would wait for ready!!!!!! **********/
                if (wait_for_ready(TIM_S) != TE_OK) {   /*** not sure this is needed ***/
-                       tpqputs(TPQD_ALWAYS, "wait_for_ready failed in start_dma");
+                       tpqputs(TPQD_ALWAYS,
+                               "wait_for_ready failed in start_dma");
                        return -EIO;
                }
 #endif
@@ -1471,10 +1506,11 @@ static int start_dma(short mode, unsigned long bytes_todo)
                /* Tell the controller the data direction */
 
                /* r/w, timeout medium, check exceptions, sets status_cmd_pending. */
-               stat = send_qic02_cmd((mode == WRITE)? QCMD_WRT_DATA : QCMD_RD_DATA, TIM_M, 0);
-               if (stat!=TE_OK) {
+               stat = send_qic02_cmd((mode == WRITE) 
+                                       ? QCMD_WRT_DATA : QCMD_RD_DATA, TIM_M, 0);
+               if (stat != TE_OK) {
                        printk(TPQIC02_NAME ": start_dma: init %s failed\n",
-                               (mode == WRITE)? "write" : "read");
+                              (mode == WRITE) ? "write" : "read");
                        (void) tp_sense(0);
                        return stat;
                }
@@ -1485,15 +1521,17 @@ static int start_dma(short mode, unsigned long bytes_todo)
                if (wait_for_ready(TIM_M) != TE_OK)
                        return -EIO;
                switch (mode) {
-                       case READ:
-                               doing_read = YES;
-                               break;
-                       case WRITE:
-                               doing_write = YES;
-                               break;
-                       default:
-                               printk(TPQIC02_NAME ": requested unknown mode %d\n", mode);
-                               panic(TPQIC02_NAME ": invalid mode in start_dma()");
+               case READ:
+                       doing_read = YES;
+                       break;
+               case WRITE:
+                       doing_write = YES;
+                       break;
+               default:
+                       printk(TPQIC02_NAME
+                              ": requested unknown mode %d\n", mode);
+                       panic(TPQIC02_NAME
+                             ": invalid mode in start_dma()");
                }
 
        } else if (is_exception()) {
@@ -1502,7 +1540,8 @@ static int start_dma(short mode, unsigned long bytes_todo)
                 *
                 * ******** this also affects EOF/EOT handling! ************
                 */
-               tpqputs(TPQD_ALWAYS, "detected exception in start_dma() while transfer in progress");
+               tpqputs(TPQD_ALWAYS,
+                       "detected exception in start_dma() while transfer in progress");
                status_error = YES;
                return TE_END;
        }
@@ -1513,7 +1552,7 @@ static int start_dma(short mode, unsigned long bytes_todo)
        /* This assumes tape is already positioned, but these
         * semi-'intelligent' drives are unpredictable...
         */
-       TIMERON(TIM_M*2);
+       TIMERON(TIM_M * 2);
 
        /* initiate first data block read from/write to the tape controller */
 
@@ -1524,7 +1563,7 @@ static int start_dma(short mode, unsigned long bytes_todo)
 
        TPQPUTS("start_dma() end");
        return TE_OK;
-} /* start_dma */
+}                              /* start_dma */
 
 
 /* This cleans up after the dma transfer has completed
@@ -1533,7 +1572,7 @@ static int start_dma(short mode, unsigned long bytes_todo)
  * sense() will set `status_eof_detected' and
  * `status_eom_detected', as required.
  */
-static void end_dma(unsigned long * bytes_done)
+static void end_dma(unsigned long *bytes_done)
 {
        int stat = TE_OK;
        unsigned long flags;
@@ -1542,35 +1581,37 @@ static void end_dma(unsigned long * bytes_done)
 
        TPQPUTS("end_dma() enter");
 
-       flags=claim_dma_lock();
-       
+       flags = claim_dma_lock();
+
        disable_dma(QIC02_TAPE_DMA);
        clear_dma_ff(QIC02_TAPE_DMA);
-       
+
        release_dma_lock(flags);
 
-       if (QIC02_TAPE_IFC == WANGTEK) /* or EVEREX */
+       if (QIC02_TAPE_IFC == WANGTEK)  /* or EVEREX */
                outb_p(WT_CTL_ONLINE, QIC02_CTL_PORT);  /* back to normal */
        else if (QIC02_TAPE_IFC == ARCHIVE)
                outb_p(0, AR_RESET_DMA_PORT);
-       else /* QIC02_TAPE_IFC == MOUNTAIN */ {
+       else {                  /* QIC02_TAPE_IFC == MOUNTAIN */
+
                /* Clear control bits, de-select ONLINE during tp_sense */
                ctlbits &= ~MTN_QIC02_CTL_ONLINE;
        }
 
        stat = wait_for_ready(TIM_M);
-       if (status_error || (stat!=TE_OK)) {
+       if (status_error || (stat != TE_OK)) {
                tpqputs(TPQD_DMAX, "DMA transfer exception");
-               stat = tp_sense((dma_mode==READ)? TP_WRP : 0);
+               stat = tp_sense((dma_mode == READ) ? TP_WRP : 0);
                /* no return here -- got to clean up first! */
-       } else /* if (QIC02_TAPE_IFC == MOUNTAIN) */ {
+       } else {                /* if (QIC02_TAPE_IFC == MOUNTAIN) */
+
                outb_p(ctlbits, QIC02_CTL_PORT);
        }
 
        if (QIC02_TAPE_IFC == MOUNTAIN)
                inb(MTN_R_DESELECT_DMA_PORT);
 
-       /* take the tape controller offline */
+       /* take the tape controller offline */
 
        /* finish off DMA stuff */
 
@@ -1588,7 +1629,7 @@ static void end_dma(unsigned long * bytes_done)
 
        TPQPUTS("end_dma() exit");
        /*** could return stat here ***/
-} /* end_dma */
+}                              /* end_dma */
 
 /*********** Below are the (public) OS-interface procedures ***********/
 
@@ -1602,7 +1643,7 @@ static void end_dma(unsigned long * bytes_done)
 static void qic02_tape_times_out(unsigned long dummy)
 {
        printk("time-out in %s driver\n", TPQIC02_NAME);
-       if ((status_cmd_pending>0) || dma_mode) {
+       if ((status_cmd_pending > 0) || dma_mode) {
                /* takes tooo long, shut it down */
                status_dead = YES;
                status_cmd_pending = 0;
@@ -1614,7 +1655,7 @@ static void qic02_tape_times_out(unsigned long dummy)
                        wake_up(&qic02_tape_transfer);
                }
        }
-} /* qic02_tape_times_out */
+}                              /* qic02_tape_times_out */
 
 /*
  * Interrupt handling:
@@ -1647,7 +1688,8 @@ static void qic02_tape_times_out(unsigned long dummy)
  * When we are finished, set flags to indicate end, disable timer.
  * NOTE: This *must* be fast! 
  */
-static void qic02_tape_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static void qic02_tape_interrupt(int irq, void *dev_id,
+                                struct pt_regs *regs)
 {
        int stat, r, i;
        unsigned long flags;
@@ -1662,20 +1704,21 @@ static void qic02_tape_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                stat = inb(QIC02_STAT_PORT);    /* Knock, knock */
                if (QIC02_TAPE_IFC == ARCHIVE) {        /* "Who's there?" */
                        if (((stat & (AR_STAT_DMADONE)) == 0) &&
-                             ((stat & (QIC02_STAT_EXCEPTION)) != 0)) {
+                           ((stat & (QIC02_STAT_EXCEPTION)) != 0)) {
                                TIMERCONT;
-                               return;                 /* "Linux with IRQ sharing" */
+                               return; /* "Linux with IRQ sharing" */
                        }
                }
 
                if ((stat & QIC02_STAT_EXCEPTION) == 0) {       /* exception occurred */
                        /* Possible causes for an exception during a transfer:
-                        *      - during a write-cycle: end of tape (EW) hole detected.
-                        *      - during a read-cycle: filemark or EOD detected.
-                        *      - something went wrong
+                        *      - during a write-cycle: end of tape (EW) hole detected.
+                        *      - during a read-cycle: filemark or EOD detected.
+                        *      - something went wrong
                         * So don't continue with the next block.
                         */
-                       tpqputs(TPQD_ALWAYS, "isr: exception on tape controller");
+                       tpqputs(TPQD_ALWAYS,
+                               "isr: exception on tape controller");
                        printk("      status %02x\n", stat);
                        status_error = TE_EX;
 
@@ -1691,25 +1734,27 @@ static void qic02_tape_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                 */
                r = 0;
 
-           /* Skip next ready check for Archive controller because
-            * it may be busy reading ahead. Weird. --hhb
-            */
+               /* Skip next ready check for Archive controller because
+                * it may be busy reading ahead. Weird. --hhb
+                */
                if (QIC02_TAPE_IFC == WANGTEK)  /* I think this is a drive-dependency, not IFC -- hhb */
-                       if (stat & QIC02_STAT_READY) {          /* not ready */
-                               tpqputs(TPQD_ALWAYS, "isr: ? Tape controller not ready");
+                       if (stat & QIC02_STAT_READY) {  /* not ready */
+                               tpqputs(TPQD_ALWAYS,
+                                       "isr: ? Tape controller not ready");
                                r = 1;
                        }
 
-               flags=claim_dma_lock();
-               
-               if ( (i = get_dma_residue(QIC02_TAPE_DMA)) != 0 ) {
-                       printk(TPQIC02_NAME ": dma_residue == %x !!!\n", i);
+               flags = claim_dma_lock();
+
+               if ((i = get_dma_residue(QIC02_TAPE_DMA)) != 0) {
+                       printk(TPQIC02_NAME ": dma_residue == %x !!!\n",
+                              i);
                        r = 1;  /* big trouble, but can't do much about it... */
                }
-               
+
                release_dma_lock(flags);
 
-               if (r) 
+               if (r)
                        return;
 
                /* finish DMA cycle */
@@ -1724,14 +1769,14 @@ static void qic02_tape_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                        wake_up(&qic02_tape_transfer);
                } else {
                        /* start next transfer, account for track-switching time */
-                       mod_timer(&tp_timer, jiffies + 6*HZ);
+                       mod_timer(&tp_timer, jiffies + 6 * HZ);
                        dma_transfer();
                }
        } else {
                printk(TPQIC02_NAME ": Unexpected interrupt, stat == %x\n",
                       inb(QIC02_STAT_PORT));
        }
-} /* qic02_tape_interrupt */
+}                              /* qic02_tape_interrupt */
 
 
 /* read/write routines:
@@ -1766,190 +1811,173 @@ static void qic02_tape_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  * request would return the EOF flag for the previous file.
  */
 
-static ssize_t qic02_tape_read(struct file * filp, char * buf, size_t count, loff_t *ppos)
+static ssize_t qic02_tape_read(struct file *filp, char *buf, size_t count,
+                              loff_t * ppos)
 {
-    int err;
-    kdev_t dev = filp->f_dentry->d_inode->i_rdev;
-    unsigned short flags = filp->f_flags;
-    unsigned long bytes_todo, bytes_done, total_bytes_done = 0;
-    int stat;
-
-    if (status_zombie==YES)
-    {
-       tpqputs(TPQD_ALWAYS, "configs not set");                
-       return -ENXIO;
-    }
-
-    if (TP_DIAGS(current_tape_dev))
-      /* can't print a ``long long'' (for filp->f_pos), so chop it */
-      printk(TPQIC02_NAME ": request READ, minor=%x, buf=%p, count=%lx"
-                         ", pos=%lx, flags=%x\n",
-            MINOR(dev), buf, (long) count,
-            (unsigned long) filp->f_pos, flags);
-    
-    if (count % TAPE_BLKSIZE)  /* Only allow mod 512 bytes at a time. */
-    {
-       tpqputs(TPQD_BLKSZ, "Wrong block size");
-       return -EINVAL;
-    }
-
-    /* Just assume everything is ok. Controller will scream if not. */
-
-    if (status_bytes_wr)       /* Once written, no more reads, 'till after WFM. */
-    {
-       return -EACCES;
-    }
-    
-    /* This is rather ugly because it has to implement a finite state
-     * machine in order to handle the EOF situations properly.
-     */
-    while ((signed)count>=0)
-    {
-       bytes_done = 0;
-       /* see how much fits in the kernel buffer */
-       bytes_todo = TPQBUF_SIZE;
-       if (bytes_todo>count)
-       {
-           bytes_todo = count;
+       int err;
+       kdev_t dev = filp->f_dentry->d_inode->i_rdev;
+       unsigned short flags = filp->f_flags;
+       unsigned long bytes_todo, bytes_done, total_bytes_done = 0;
+       int stat;
+
+       if (status_zombie == YES) {
+               tpqputs(TPQD_ALWAYS, "configs not set");
+               return -ENXIO;
        }
-       
-       /* Must ensure that user program sees exactly one EOF token (==0) */
-       if (return_read_eof==YES)
-       {
-           if (TPQDBG(DEBUG))
-           {
-               printk("read: return_read_eof==%d, reported_read_eof==%d, total_bytes_done==%lu\n", return_read_eof, reported_read_eof, total_bytes_done);
-           }
-           
-           if (reported_read_eof==NO)
-           {
-               /* have not yet returned EOF to user program */
-               if (total_bytes_done>0)
-               {
-                   return total_bytes_done; /* next time return EOF */
-               }
-               else
-               {
-                   reported_read_eof = YES; /* move on next time */
-                   return 0;            /* return EOF */
-               }                               
-           }
-           else
-           {
-               /* Application program has already received EOF
-                * (above), now continue with next file on tape,
-                * if possible.
-                * When the FM is reached, EXCEPTION is set,
-                * causing a sense(). Subsequent read/writes will
-                * continue after the FM.
-                */
-               /*********** ?????????? this should check for (EOD|NDT), not EOM, 'cause we can read past EW: ************/
-               if (status_eom_detected)
-               {
-                   /* If EOM, nothing left to read, so keep returning EOFs.
-                    *** should probably set some flag to avoid clearing
-                    *** status_eom_detected through ioctls or something
-                    */
-                   return 0;
+
+       if (TP_DIAGS(current_tape_dev))
+               /* can't print a ``long long'' (for filp->f_pos), so chop it */
+               printk(TPQIC02_NAME
+                      ": request READ, minor=%x, buf=%p, count=%lx"
+                      ", pos=%lx, flags=%x\n", MINOR(dev), buf,
+                      (long) count, (unsigned long) filp->f_pos, flags);
+
+       if (count % TAPE_BLKSIZE) {     /* Only allow mod 512 bytes at a time. */
+               tpqputs(TPQD_BLKSZ, "Wrong block size");
+               return -EINVAL;
+       }
+
+       /* Just assume everything is ok. Controller will scream if not. */
+
+       if (status_bytes_wr) {  /* Once written, no more reads, 'till after WFM. */
+               return -EACCES;
+       }
+
+       /* This is rather ugly because it has to implement a finite state
+        * machine in order to handle the EOF situations properly.
+        */
+       while ((signed) count >= 0) {
+               bytes_done = 0;
+               /* see how much fits in the kernel buffer */
+               bytes_todo = TPQBUF_SIZE;
+               if (bytes_todo > count) {
+                       bytes_todo = count;
                }
-               else
-               {
-                   /* just eof, there may be more files ahead... */
-                   return_read_eof = NO;
-                   reported_read_eof = NO;
-                   status_eof_detected = NO; /* reset this too */
-                   /*fall through*/
+
+               /* Must ensure that user program sees exactly one EOF token (==0) */
+               if (return_read_eof == YES) {
+                       if (TPQDBG(DEBUG)) {
+                               printk
+                                   ("read: return_read_eof==%d, reported_read_eof==%d, total_bytes_done==%lu\n",
+                                    return_read_eof, reported_read_eof,
+                                    total_bytes_done);
+                       }
+
+                       if (reported_read_eof == NO) {
+                               /* have not yet returned EOF to user program */
+                               if (total_bytes_done > 0) {
+                                       return total_bytes_done;        /* next time return EOF */
+                               } else {
+                                       reported_read_eof = YES;        /* move on next time */
+                                       return 0;       /* return EOF */
+                               }
+                       } else {
+                               /* Application program has already received EOF
+                                * (above), now continue with next file on tape,
+                                * if possible.
+                                * When the FM is reached, EXCEPTION is set,
+                                * causing a sense(). Subsequent read/writes will
+                                * continue after the FM.
+                                */
+               /*********** ?????????? this should check for (EOD|NDT), not EOM, 'cause we can read past EW: ************/
+                               if (status_eom_detected) {
+                                       /* If EOM, nothing left to read, so keep returning EOFs.
+                                        *** should probably set some flag to avoid clearing
+                                        *** status_eom_detected through ioctls or something
+                                        */
+                                       return 0;
+                               } else {
+                                       /* just eof, there may be more files ahead... */
+                                       return_read_eof = NO;
+                                       reported_read_eof = NO;
+                                       status_eof_detected = NO;       /* reset this too */
+                                       /*fall through */
+                               }
+                       }
                }
-           }
-       }
-       
+
        /*****************************/
-       if (bytes_todo==0)
-       {
-           return total_bytes_done;
-       }
-       
-       if (bytes_todo>0)
-       {
-           /* start reading data */
-           if (is_exception()) /****************************************/
-           {
-               tpqputs(TPQD_DMAX, "is_exception() before start_dma()!");
-           }
-           
+               if (bytes_todo == 0) {
+                       return total_bytes_done;
+               }
+
+               if (bytes_todo > 0) {
+                       /* start reading data */
+                       if (is_exception()) {
+/****************************************/
+                               tpqputs(TPQD_DMAX,
+                                       "is_exception() before start_dma()!");
+                       }
+
 /******************************************************************
  ***** if start_dma() fails because the head is positioned 0 bytes
  ***** before the FM, (causing EXCEPTION to be set) return_read_eof should
  ***** be set to YES, and we should return total_bytes_done, rather than -ENXIO.
  ***** The app should recognize this as an EOF condition.
  ***************************************************************************/
-           stat = start_dma(READ, bytes_todo);
-           if (stat == TE_OK)
-           {
-               /* Wait for transfer to complete, interrupt should wake us */
-               while (dma_mode != 0)
-               {
-                   sleep_on(&qic02_tape_transfer);
-               }
-               if (status_error)
-               {
-                   return_read_eof = YES;
-               }
-               
-           }
-           else if (stat != TE_END)
-           {
-               /* should do sense() on error here */
+                       stat = start_dma(READ, bytes_todo);
+                       if (stat == TE_OK) {
+                               /* Wait for transfer to complete, interrupt should wake us */
+                               while (dma_mode != 0) {
+                                       sleep_on(&qic02_tape_transfer);
+                               }
+                               if (status_error) {
+                                       return_read_eof = YES;
+                               }
+
+                       } else if (stat != TE_END) {
+                               /* should do sense() on error here */
 #if 0
-               return -ENXIO;
+                               return -ENXIO;
 #else
-               printk("Trouble: stat==%02x\n", stat);
-               return_read_eof = YES;
+                               printk("Trouble: stat==%02x\n", stat);
+                               return_read_eof = YES;
                /*************** check EOF/EOT handling!!!!!! **/
 #endif
-           }
-           end_dma(&bytes_done);
-           if (bytes_done>bytes_todo)
-           {
-               tpqputs(TPQD_ALWAYS, "read: Oops, read more bytes than requested");
-               return -EIO;
-           }
-           /* copy buffer to user-space in one go */
-           if (bytes_done>0)
-           {
-               err = copy_to_user(buf, buffaddr, bytes_done);
-               if (err)
-               {
-                   return -EFAULT;
-               }
-           }
+                       }
+                       end_dma(&bytes_done);
+                       if (bytes_done > bytes_todo) {
+                               tpqputs(TPQD_ALWAYS,
+                                       "read: Oops, read more bytes than requested");
+                               return -EIO;
+                       }
+                       /* copy buffer to user-space in one go */
+                       if (bytes_done > 0) {
+                               err =
+                                   copy_to_user(buf, buffaddr,
+                                                bytes_done);
+                               if (err) {
+                                       return -EFAULT;
+                               }
+                       }
 #if 1
-           /* Checks Ton's patch below */
-           if ((return_read_eof == NO) && (status_eof_detected == YES))
-           {
-               printk(TPQIC02_NAME ": read(): return_read_eof=%d, status_eof_detected=YES. return_read_eof:=YES\n", return_read_eof);
-           }
+                       /* Checks Ton's patch below */
+                       if ((return_read_eof == NO)
+                           && (status_eof_detected == YES)) {
+                               printk(TPQIC02_NAME
+                                      ": read(): return_read_eof=%d, status_eof_detected=YES. return_read_eof:=YES\n",
+                                      return_read_eof);
+                       }
 #endif
-           if ((bytes_todo != bytes_done) || (status_eof_detected == YES))
-           {
-               /* EOF or EOM detected. return EOF next time. */
-               return_read_eof = YES;
-           }
-           
-       } /* else: ignore read request for 0 bytes */
-
-       if (bytes_done>0)
-       {
-           status_bytes_rd = YES;
-           buf += bytes_done;
-           *ppos += bytes_done;
-           total_bytes_done += bytes_done;
-           count -= bytes_done;
+                       if ((bytes_todo != bytes_done)
+                           || (status_eof_detected == YES)) {
+                               /* EOF or EOM detected. return EOF next time. */
+                               return_read_eof = YES;
+                       }
+
+               }
+               /* else: ignore read request for 0 bytes */
+               if (bytes_done > 0) {
+                       status_bytes_rd = YES;
+                       buf += bytes_done;
+                       *ppos += bytes_done;
+                       total_bytes_done += bytes_done;
+                       count -= bytes_done;
+               }
        }
-    }
-    tpqputs(TPQD_ALWAYS, "read request for <0 bytes");
-    return -EINVAL;
-} /* qic02_tape_read */
+       tpqputs(TPQD_ALWAYS, "read request for <0 bytes");
+       return -EINVAL;
+}                              /* qic02_tape_read */
 
 
 
@@ -1981,100 +2009,85 @@ static ssize_t qic02_tape_read(struct file * filp, char * buf, size_t count, lof
  * tape device again. The driver will detect an exception status in (No Cartridge)
  * and force a rewind. After that tar may continue writing.
  */
-static ssize_t qic02_tape_write( struct file * filp,  const char * buf, 
-               size_t count, loff_t *ppos)
+static ssize_t qic02_tape_write(struct file *filp, const char *buf,
+                               size_t count, loff_t * ppos)
 {
-    int err;
-    kdev_t dev = filp->f_dentry->d_inode->i_rdev;
-    unsigned short flags = filp->f_flags;
-    unsigned long bytes_todo, bytes_done, total_bytes_done = 0;
-    
-    if (status_zombie==YES)
-    {
-       tpqputs(TPQD_ALWAYS, "configs not set");                
-       return -ENXIO;
-    }
-
-    if (TP_DIAGS(current_tape_dev))
-    {
-       /* can't print a ``long long'' (for filp->f_pos), so chop it */
-       printk(TPQIC02_NAME ": request WRITE, minor=%x, buf=%p"
-                           ", count=%lx, pos=%lx, flags=%x\n",
-              MINOR(dev), buf,
-              (long) count, (unsigned long) filp->f_pos, flags);
-    }
-    
-    if (count % TAPE_BLKSIZE)  /* only allow mod 512 bytes at a time */
-    {
-       tpqputs(TPQD_BLKSZ, "Wrong block size");
-       return -EINVAL;
-    }
-
-    if (mode_access==READ)
-    {
-       tpqputs(TPQD_ALWAYS, "Not in write mode");
-       return -EACCES;
-    }
-
-    /* open() does a sense() and we can assume the tape isn't changed
-     * between open() and release(), so the tperror.exs bits will still
-     * be valid.
-     */
-    if ((tperror.exs & TP_ST0) && (tperror.exs & TP_WRP))
-    {
-       tpqputs(TPQD_ALWAYS, "Cartridge is write-protected.");
-       return -EACCES; /* don't even try when write protected */
-    }
-      
-    if (doing_read == YES)
-    {
-       terminate_read(0);
-    }
-    
-    while ((signed)count>=0)
-    {
-       /* see how much fits in the kernel buffer */
-       bytes_done = 0;
-       bytes_todo = TPQBUF_SIZE;
-       if (bytes_todo>count)
-       {
-           bytes_todo = count;
+       int err;
+       kdev_t dev = filp->f_dentry->d_inode->i_rdev;
+       unsigned short flags = filp->f_flags;
+       unsigned long bytes_todo, bytes_done, total_bytes_done = 0;
+
+       if (status_zombie == YES) {
+               tpqputs(TPQD_ALWAYS, "configs not set");
+               return -ENXIO;
        }
-       
-       if (return_write_eof == YES)
-       {
-           /* return_write_eof should be reset on reverse tape movements. */
-           
-           if (reported_write_eof==NO)
-           {
-               if (bytes_todo>0)
-               {
-                   tpqputs(TPQD_ALWAYS, "partial write");
-                   /* partial write signals EOF to user program */
-               }
-               reported_write_eof = YES;
-               return total_bytes_done;
-           }
-           else
-           {
-               return -ENOSPC;          /* return error */
-           }   
-       }
-       
-       /* Quit when done. */
-       if (bytes_todo==0)
-       {
-           return total_bytes_done;
+
+       if (TP_DIAGS(current_tape_dev)) {
+               /* can't print a ``long long'' (for filp->f_pos), so chop it */
+               printk(TPQIC02_NAME ": request WRITE, minor=%x, buf=%p"
+                      ", count=%lx, pos=%lx, flags=%x\n",
+                      MINOR(dev), buf,
+                      (long) count, (unsigned long) filp->f_pos, flags);
+       }
+
+       if (count % TAPE_BLKSIZE) {     /* only allow mod 512 bytes at a time */
+               tpqputs(TPQD_BLKSZ, "Wrong block size");
+               return -EINVAL;
+       }
+
+       if (mode_access == READ) {
+               tpqputs(TPQD_ALWAYS, "Not in write mode");
+               return -EACCES;
+       }
+
+       /* open() does a sense() and we can assume the tape isn't changed
+        * between open() and release(), so the tperror.exs bits will still
+        * be valid.
+        */
+       if ((tperror.exs & TP_ST0) && (tperror.exs & TP_WRP)) {
+               tpqputs(TPQD_ALWAYS, "Cartridge is write-protected.");
+               return -EACCES; /* don't even try when write protected */
+       }
+
+       if (doing_read == YES) {
+               terminate_read(0);
        }
-       
-       /* copy from user to DMA buffer and initiate transfer. */
-       if (bytes_todo>0)
-       {
-           err = copy_from_user(buffaddr, buf, bytes_todo);
-           if (err)
-           {
-               return -EFAULT;
-           }
+
+       while ((signed) count >= 0) {
+               /* see how much fits in the kernel buffer */
+               bytes_done = 0;
+               bytes_todo = TPQBUF_SIZE;
+               if (bytes_todo > count) {
+                       bytes_todo = count;
+               }
+
+               if (return_write_eof == YES) {
+                       /* return_write_eof should be reset on reverse tape movements. */
+
+                       if (reported_write_eof == NO) {
+                               if (bytes_todo > 0) {
+                                       tpqputs(TPQD_ALWAYS,
+                                               "partial write");
+                                       /* partial write signals EOF to user program */
+                               }
+                               reported_write_eof = YES;
+                               return total_bytes_done;
+                       } else {
+                               return -ENOSPC; /* return error */
+                       }
+               }
+
+               /* Quit when done. */
+               if (bytes_todo == 0) {
+                       return total_bytes_done;
+               }
+
+               /* copy from user to DMA buffer and initiate transfer. */
+               if (bytes_todo > 0) {
+                       err = copy_from_user(buffaddr, buf, bytes_todo);
+                       if (err) {
+                               return -EFAULT;
+                       }
 
 /****************** similar problem with read() at FM could happen here at EOT.
  ******************/
@@ -2082,78 +2095,74 @@ static ssize_t qic02_tape_write( struct file * filp,  const char * buf,
 /***** if at EOT, 0 bytes can be written. start_dma() will
  ***** fail and write() will return ENXIO error
  *****/
-           if (start_dma(WRITE, bytes_todo) != TE_OK)
-           {
-               tpqputs(TPQD_ALWAYS, "write: start_dma() failed");
-               /* should do sense() on error here */
-               return -ENXIO;  /*********** FIXTHIS **************/
-           }
-
-           /* Wait for write to complete, interrupt should wake us. */
-           while ((status_error == 0) && (dma_mode != 0))
-           {
-               sleep_on(&qic02_tape_transfer);
-           }
-
-           end_dma(&bytes_done);
-           if (bytes_done>bytes_todo)
-           {
-               tpqputs(TPQD_ALWAYS, "write: Oops, wrote more bytes than requested");
-               return -EIO;
-           }
-           /* If the dma-transfer was aborted because of an exception,
-            * status_error will have been set in the interrupt handler.
-            * Then end_dma() will do a sense().
-            * If the exception was EXC_EOM, the EW-hole was encountered
-            * and two more blocks could be written. For the time being we'll
-            * just consider this to be the EOT.
-            * Otherwise, something Bad happened, such as the maximum number
-            * of block-rewrites was exceeded. [e.g. A very bad spot on tape was
-            * encountered. Normally short dropouts are compensated for by
-            * rewriting the block in error, up to 16 times. I'm not sure
-            * QIC-24 drives can do this.]
-            */
-           if (status_error)
-           {
-               if (status_eom_detected == YES)
-               {
-                   tpqputs(TPQD_ALWAYS, "write: EW detected");
-                   return_write_eof = YES;
-               }
-               else
-               {
-                   /* probably EXC_RWA */
-                   tpqputs(TPQD_ALWAYS, "write: dma: error in writing");
-                   return -EIO;
-               }
-           }
-           if (bytes_todo != bytes_done)
-           {
-               /* EOF or EOM detected. return EOT next time. */
-               return_write_eof = YES;
-           }
-       }
-       /* else: ignore write request for 0 bytes. */
-       
-       if (bytes_done>0)
-       {
-           status_bytes_wr = YES;
-           buf += bytes_done;
-           *ppos += bytes_done;
-           total_bytes_done += bytes_done;
-           count -= bytes_done;
-       }
-    }
-    
-    tpqputs(TPQD_ALWAYS, "write request for <0 bytes");
-    if (TPQDBG(DEBUG))
-    {
-       printk(TPQIC02_NAME ": status_bytes_wr %x, buf %p"
-                           ", total_bytes_done %lx, count %lx\n",
-              status_bytes_wr, buf, total_bytes_done, (long) count);
-    }
-    return -EINVAL;
-} /* qic02_tape_write */
+                       if (start_dma(WRITE, bytes_todo) != TE_OK) {
+                               tpqputs(TPQD_ALWAYS,
+                                       "write: start_dma() failed");
+                               /* should do sense() on error here */
+                               return -ENXIO;
+                               /*********** FIXTHIS **************/
+                       }
+
+                       /* Wait for write to complete, interrupt should wake us. */
+                       while ((status_error == 0) && (dma_mode != 0)) {
+                               sleep_on(&qic02_tape_transfer);
+                       }
+
+                       end_dma(&bytes_done);
+                       if (bytes_done > bytes_todo) {
+                               tpqputs(TPQD_ALWAYS,
+                                       "write: Oops, wrote more bytes than requested");
+                               return -EIO;
+                       }
+                       /* If the dma-transfer was aborted because of an exception,
+                        * status_error will have been set in the interrupt handler.
+                        * Then end_dma() will do a sense().
+                        * If the exception was EXC_EOM, the EW-hole was encountered
+                        * and two more blocks could be written. For the time being we'll
+                        * just consider this to be the EOT.
+                        * Otherwise, something Bad happened, such as the maximum number
+                        * of block-rewrites was exceeded. [e.g. A very bad spot on tape was
+                        * encountered. Normally short dropouts are compensated for by
+                        * rewriting the block in error, up to 16 times. I'm not sure
+                        * QIC-24 drives can do this.]
+                        */
+                       if (status_error) {
+                               if (status_eom_detected == YES) {
+                                       tpqputs(TPQD_ALWAYS,
+                                               "write: EW detected");
+                                       return_write_eof = YES;
+                               } else {
+                                       /* probably EXC_RWA */
+                                       tpqputs(TPQD_ALWAYS,
+                                               "write: dma: error in writing");
+                                       return -EIO;
+                               }
+                       }
+                       if (bytes_todo != bytes_done) {
+                               /* EOF or EOM detected. return EOT next time. */
+                               return_write_eof = YES;
+                       }
+               }
+               /* else: ignore write request for 0 bytes. */
+
+               if (bytes_done > 0) {
+                       status_bytes_wr = YES;
+                       buf += bytes_done;
+                       *ppos += bytes_done;
+                       total_bytes_done += bytes_done;
+                       count -= bytes_done;
+               }
+       }
+
+       tpqputs(TPQD_ALWAYS, "write request for <0 bytes");
+       if (TPQDBG(DEBUG)) {
+               printk(TPQIC02_NAME ": status_bytes_wr %x, buf %p"
+                      ", total_bytes_done %lx, count %lx\n",
+                      status_bytes_wr, buf, total_bytes_done,
+                      (long) count);
+       }
+       return -EINVAL;
+}                              /* qic02_tape_write */
 
 
 
@@ -2169,846 +2178,810 @@ static ssize_t qic02_tape_write( struct file * filp,  const char * buf,
  * Don't rewind if the minor bits specify density 0.
  */
 
-static int qic02_tape_open(struct inode * inode, struct file * filp)
+static int qic02_tape_open(struct inode *inode, struct file *filp)
 {
-    static int qic02_tape_open_no_use_count(struct inode *, struct file *);
-    int open_error;
+       static int qic02_tape_open_no_use_count(struct inode *,
+                                               struct file *);
+       int open_error;
 
-    open_error = qic02_tape_open_no_use_count(inode, filp);
-    return open_error;
+       open_error = qic02_tape_open_no_use_count(inode, filp);
+       return open_error;
 }
 
-static int qic02_tape_open_no_use_count(struct inode * inode, struct file * filp)
+static int qic02_tape_open_no_use_count(struct inode *inode,
+                                       struct file *filp)
 {
-    kdev_t dev = inode->i_rdev;
-    unsigned short flags = filp->f_flags;
-    unsigned short dens = 0;
-    int s;
+       kdev_t dev = inode->i_rdev;
+       unsigned short flags = filp->f_flags;
+       unsigned short dens = 0;
+       int s;
 
 
-    if (TP_DIAGS(dev))
-    {
-       printk("qic02_tape_open: dev=%s, flags=%x     ",
-              kdevname(dev), flags);
-    }
+       if (TP_DIAGS(dev)) {
+               printk("qic02_tape_open: dev=%s, flags=%x     ",
+                      kdevname(dev), flags);
+       }
 
-    if (MINOR(dev)==255)       /* special case for resetting */
-    {
-       if (capable(CAP_SYS_ADMIN))
-       {
-           return (tape_reset(1)==TE_OK) ? -EAGAIN : -ENXIO;
+       if (MINOR(dev) == 255) {        /* special case for resetting */
+               if (capable(CAP_SYS_ADMIN)) {
+                       return (tape_reset(1) == TE_OK) ? -EAGAIN : -ENXIO;
+               } else {
+                       return -EPERM;
+               }
        }
-       else
-       {
-           return -EPERM;
+
+       if (status_dead == YES) {
+               /* Allow `mt reset' ioctl() even when already open()ed. */
+               return 0;
        }
-    }
-    
-    if (status_dead==YES)
-    {
-       /* Allow `mt reset' ioctl() even when already open()ed. */
-       return 0;
-    }
-    
+
        /* Only one at a time from here on... */
-    if (file_count(filp)>1)    /* filp->f_count==1 for the first open() */
-    {
-       return -EBUSY;
-    }
-
-    if (status_zombie==YES)
-    {
-       /* no irq/dma/port stuff allocated yet, no reset done
-        * yet, so return until MTSETCONFIG has been done.
+       if (file_count(filp) > 1) {     /* filp->f_count==1 for the first open() */
+               return -EBUSY;
+       }
+
+       if (status_zombie == YES) {
+               /* no irq/dma/port stuff allocated yet, no reset done
+                * yet, so return until MTSETCONFIG has been done.
+                */
+               return 0;
+       }
+
+       status_bytes_rd = NO;
+       status_bytes_wr = NO;
+
+       return_read_eof = NO;   /********????????????????*****/
+       return_write_eof = (status_eot_detected) ? YES : NO;
+
+       /* Clear this in case user app close()d before reading EOF token */
+       status_eof_detected = NO;
+
+       reported_read_eof = NO;
+       reported_write_eof = NO;
+
+
+       switch (flags & O_ACCMODE) {
+       case O_RDONLY:
+               mode_access = READ;
+               break;
+       case O_WRONLY:          /* Fallthru... Strictly speaking this is not correct... */
+       case O_RDWR:            /* Reads are allowed as long as nothing is written */
+               mode_access = WRITE;
+               break;
+       }
+
+       /* This is to avoid tape-changed problems (TP_CNI exception).
+        *
+        * Since removing the cartridge will not raise an exception,
+        * we always do a tp_sense() to make sure we have the proper
+        * CNI status, the 2150L may need an additional sense.... - Eddy
         */
-       return 0;
-    }
-    
-    status_bytes_rd = NO;
-    status_bytes_wr = NO;
-    
-    return_read_eof = NO;      /********????????????????*****/
-    return_write_eof = (status_eot_detected)? YES : NO;
-
-    /* Clear this in case user app close()d before reading EOF token */
-    status_eof_detected = NO;
-
-    reported_read_eof = NO;
-    reported_write_eof = NO;
-
-
-    switch (flags & O_ACCMODE)
-    {
-     case O_RDONLY:
-       mode_access = READ;
-       break;
-     case O_WRONLY:    /* Fallthru... Strictly speaking this is not correct... */
-     case O_RDWR:      /* Reads are allowed as long as nothing is written */
-       mode_access = WRITE;
-       break;
-    }
-    
-    /* This is to avoid tape-changed problems (TP_CNI exception).
-     *
-     * Since removing the cartridge will not raise an exception,
-     * we always do a tp_sense() to make sure we have the proper
-     * CNI status, the 2150L may need an additional sense.... - Eddy
-     */
-    s = tp_sense(TP_WRP|TP_EOM|TP_BOM|TP_CNI|TP_EOR);
-    
-    if (s == TE_OK)
-    {
-       /* Try to clear cartridge-changed status for Archive-2150L */
-       if ((tperror.exs & TP_ST0) && (tperror.exs & TP_CNI))
-       {
-           s = tp_sense(TP_WRP|TP_EOM|TP_BOM|TP_CNI|TP_EOR);
-       }
-    }
-    
-    if (s != TE_OK)
-    {
-       tpqputs(TPQD_ALWAYS, "open: sense() failed");
-       return -EIO;
-    }
-
-    /* exception bits should be up-to-date now, so check for
-     * tape presence and exit if absent.
-     * Even `mt stat' will fail without a tape.
-     */
-    if ((tperror.exs & TP_ST0) && (tperror.exs & TP_CNI))
-    {
-       tpqputs(TPQD_ALWAYS, "No tape present.");
-       return -EIO;
-    }
-
-    /* At this point we can assume that a tape is present and
-     * that it will remain present until release() is called.
-     */
-
-    /* not allowed to do QCMD_DENS_* unless tape is rewound */
-    if ((TP_DENS(dev)!=0) && (TP_DENS(current_tape_dev) != TP_DENS(dev)))
-    {
-       /* force rewind if minor bits have changed,
-        * i.e. user wants to use tape in different format.
-        * [assuming single drive operation]
+       s = tp_sense(TP_WRP | TP_EOM | TP_BOM | TP_CNI | TP_EOR);
+
+       if (s == TE_OK) {
+               /* Try to clear cartridge-changed status for Archive-2150L */
+               if ((tperror.exs & TP_ST0) && (tperror.exs & TP_CNI)) {
+                       s = tp_sense(TP_WRP | TP_EOM | TP_BOM | TP_CNI |
+                                    TP_EOR);
+               }
+       }
+
+       if (s != TE_OK) {
+               tpqputs(TPQD_ALWAYS, "open: sense() failed");
+               return -EIO;
+       }
+
+       /* exception bits should be up-to-date now, so check for
+        * tape presence and exit if absent.
+        * Even `mt stat' will fail without a tape.
         */
-       if (TP_HAVE_DENS)
-       {
-           tpqputs(TPQD_REWIND, "Density minor bits have changed. Forcing rewind.");
-           need_rewind = YES;
-       }
-    }
-    else
-    {
-       /* density bits still the same, but TP_DIAGS bit 
-        * may have changed.
+       if ((tperror.exs & TP_ST0) && (tperror.exs & TP_CNI)) {
+               tpqputs(TPQD_ALWAYS, "No tape present.");
+               return -EIO;
+       }
+
+       /* At this point we can assume that a tape is present and
+        * that it will remain present until release() is called.
         */
-       current_tape_dev = dev;
-    }
-    
-    if (need_rewind == YES)  /***************** CHECK THIS!!!!!!!! **********/
-    {
-       s = do_qic_cmd(QCMD_REWIND, TIM_R);
-       if (s != 0)
-       {
-           tpqputs(TPQD_ALWAYS, "open: rewind failed");
-           return -EIO;
+
+       /* not allowed to do QCMD_DENS_* unless tape is rewound */
+       if ((TP_DENS(dev) != 0)
+           && (TP_DENS(current_tape_dev) != TP_DENS(dev))) {
+               /* force rewind if minor bits have changed,
+                * i.e. user wants to use tape in different format.
+                * [assuming single drive operation]
+                */
+               if (TP_HAVE_DENS) {
+                       tpqputs(TPQD_REWIND,
+                               "Density minor bits have changed. Forcing rewind.");
+                       need_rewind = YES;
+               }
+       } else {
+               /* density bits still the same, but TP_DIAGS bit 
+                * may have changed.
+                */
+               current_tape_dev = dev;
+       }
+
+       if (need_rewind == YES) {
+/***************** CHECK THIS!!!!!!!! **********/
+               s = do_qic_cmd(QCMD_REWIND, TIM_R);
+               if (s != 0) {
+                       tpqputs(TPQD_ALWAYS, "open: rewind failed");
+                       return -EIO;
+               }
        }
-    }
 
 
 /* Note: After a reset command, the controller will rewind the tape
  *      just before performing any tape movement operation! ************ SO SET need_rewind flag!!!!!
- */ 
-    if (status_dead==YES)
-    {
-       tpqputs(TPQD_ALWAYS, "open: tape dead, attempting reset");
-       if (tape_reset(1)!=TE_OK)
-       {
-           return -ENXIO;
+ */
+       if (status_dead == YES) {
+               tpqputs(TPQD_ALWAYS, "open: tape dead, attempting reset");
+               if (tape_reset(1) != TE_OK) {
+                       return -ENXIO;
+               } else {
+                       status_dead = NO;
+                       if (tp_sense(~(TP_ST1 | TP_ILL)) != TE_OK) {
+                               tpqputs(TPQD_ALWAYS,
+                                       "open: tp_sense() failed\n");
+                               status_dead = YES;      /* try reset next time */
+                               return -EIO;
+                       }
+               }
        }
-       else
-       {
-           status_dead = NO;
-           if (tp_sense(~(TP_ST1|TP_ILL)) != TE_OK)
-           {
-               tpqputs(TPQD_ALWAYS, "open: tp_sense() failed\n");
-               status_dead = YES;      /* try reset next time */
+
+       /* things should be ok, once we get here */
+
+
+       /* set density: only allowed when TP_BOM status bit is set,
+        * so we must have done a rewind by now. If not, just skip over.
+        * Only give set density command when minor bits have changed.
+        */
+       if (TP_DENS(current_tape_dev) == TP_DENS(dev)) {
+               return 0;
+       }
+
+       current_tape_dev = dev;
+       need_rewind = NO;
+       if (TP_HAVE_DENS) {
+               dens = TP_DENS(dev);
+       }
+
+       if (dens < sizeof(format_names) / sizeof(char *)) {
+               printk(TPQIC02_NAME ": format: %s%s\n",
+                      (dens != 0) ? "QIC-" : "", format_names[dens]);
+       } else {
+               tpqputs(TPQD_REWIND, "Wait for retensioning...");
+       }
+
+       switch (TP_DENS(dev)) {
+       case 0:         /* Minor 0 is for drives without set-density support */
+               s = 0;
+               break;
+       case 1:
+               s = do_qic_cmd(QCMD_DENS_11, TIM_S);
+               break;
+       case 2:
+               s = do_qic_cmd(QCMD_DENS_24, TIM_S);
+               break;
+       case 3:
+               s = do_qic_cmd(QCMD_DENS_120, TIM_S);
+               break;
+       case 4:
+               s = do_qic_cmd(QCMD_DENS_150, TIM_S);
+               break;
+       case 5:
+               s = do_qic_cmd(QCMD_DENS_300, TIM_S);
+               break;
+       case 6:
+               s = do_qic_cmd(QCMD_DENS_600, TIM_S);
+               break;
+       default:                /* otherwise do a retension before anything else */
+               s = do_qic_cmd(QCMD_RETEN, TIM_R);
+       }
+       if (s != 0) {
+               status_dead = YES;      /* force reset */
+               current_tape_dev = 0;   /* earlier 0xff80 */
                return -EIO;
-           }
-       }
-    }
-    
-    /* things should be ok, once we get here */
-    
-
-    /* set density: only allowed when TP_BOM status bit is set,
-     * so we must have done a rewind by now. If not, just skip over.
-     * Only give set density command when minor bits have changed.
-     */
-    if (TP_DENS(current_tape_dev) == TP_DENS(dev) )
-    {
+       }
+
        return 0;
-    }
-    
-    current_tape_dev = dev;
-    need_rewind = NO;
-    if (TP_HAVE_DENS)
-    {
-       dens = TP_DENS(dev);
-    }
-    
-    if (dens < sizeof(format_names)/sizeof(char *))
-    {
-       printk(TPQIC02_NAME ": format: %s%s\n", (dens!=0)? "QIC-" : "", format_names[dens]);
-    }
-    else
-    {
-       tpqputs(TPQD_REWIND, "Wait for retensioning...");
-    }
-    
-    switch (TP_DENS(dev))
-    {
-     case 0: /* Minor 0 is for drives without set-density support */
-       s = 0;
-       break;
-     case 1:
-       s = do_qic_cmd(QCMD_DENS_11, TIM_S);
-       break;
-     case 2:
-       s = do_qic_cmd(QCMD_DENS_24, TIM_S);
-       break;
-     case 3:
-       s = do_qic_cmd(QCMD_DENS_120, TIM_S);
-       break;
-     case 4:
-       s = do_qic_cmd(QCMD_DENS_150, TIM_S);
-       break;
-     case 5:
-       s = do_qic_cmd(QCMD_DENS_300, TIM_S);
-       break;
-     case 6:
-       s = do_qic_cmd(QCMD_DENS_600, TIM_S);
-       break;
-     default:  /* otherwise do a retension before anything else */
-       s = do_qic_cmd(QCMD_RETEN, TIM_R);
-    }
-    if (s != 0)
-    {
-       status_dead = YES;      /* force reset */
-       current_tape_dev = 0; /* earlier 0xff80 */
-       return -EIO;
-    }
-    
-    return 0;
-} /* qic02_tape_open */
-
-
-static int qic02_tape_release(struct inode * inode, struct file * filp)
+}                              /* qic02_tape_open */
+
+
+static int qic02_tape_release(struct inode *inode, struct file *filp)
 {
-    kdev_t dev = inode->i_rdev;
-
-    lock_kernel();
-    if (TP_DIAGS(dev))
-    {
-       printk("qic02_tape_release: dev=%s\n",  kdevname(dev));
-    }
-    
-    if (status_zombie==NO)             /* don't rewind in zombie mode */
-    {
-       /* Terminate any pending write cycle. Terminating the read-cycle
-        * is delayed until it is required to do so for a new command.
-        */
-       terminate_write(-1);
-       
-       if (status_dead==YES)
-       {
-           tpqputs(TPQD_ALWAYS, "release: device dead!?");
+       kdev_t dev = inode->i_rdev;
+
+       lock_kernel();
+       if (TP_DIAGS(dev)) {
+               printk("qic02_tape_release: dev=%s\n", kdevname(dev));
        }
-       
-       /* Rewind only if minor number requires it AND 
-        * read/writes have been done. ************* IS THIS CORRECT??????????
-        */
-       if ((TP_REWCLOSE(dev)) && (status_bytes_rd | status_bytes_wr))
-       {
-           tpqputs(TPQD_REWIND, "release: Doing rewind...");
-           (void) do_qic_cmd(QCMD_REWIND, TIM_R);
+
+       if (status_zombie == NO) {      /* don't rewind in zombie mode */
+               /* Terminate any pending write cycle. Terminating the read-cycle
+                * is delayed until it is required to do so for a new command.
+                */
+               terminate_write(-1);
+
+               if (status_dead == YES) {
+                       tpqputs(TPQD_ALWAYS, "release: device dead!?");
+               }
+
+               /* Rewind only if minor number requires it AND 
+                * read/writes have been done. ************* IS THIS CORRECT??????????
+                */
+               if ((TP_REWCLOSE(dev))
+                   && (status_bytes_rd | status_bytes_wr)) {
+                       tpqputs(TPQD_REWIND, "release: Doing rewind...");
+                       (void) do_qic_cmd(QCMD_REWIND, TIM_R);
+               }
        }
-    }
-    unlock_kernel();
-    return 0;
-} /* qic02_tape_release */
+       unlock_kernel();
+       return 0;
+}                              /* qic02_tape_release */
 
 
 #ifdef CONFIG_QIC02_DYNCONF
 /* Set masks etc. based on the interface card type. */
 static int update_ifc_masks(int ifc)
 {
-    QIC02_TAPE_IFC = ifc;
-
-    if ((QIC02_TAPE_IFC == WANGTEK) || (QIC02_TAPE_IFC == EVEREX))
-    {
-       QIC02_STAT_PORT = QIC02_TAPE_PORT;
-       QIC02_CTL_PORT = QIC02_TAPE_PORT;
-       QIC02_CMD_PORT = QIC02_TAPE_PORT+1;
-       QIC02_DATA_PORT = QIC02_TAPE_PORT+1;
-       QIC02_STAT_READY = WT_QIC02_STAT_READY;
-       QIC02_STAT_EXCEPTION = WT_QIC02_STAT_EXCEPTION;
-       QIC02_STAT_MASK = WT_QIC02_STAT_MASK;
-       
-       QIC02_STAT_RESETMASK = WT_QIC02_STAT_RESETMASK;
-       QIC02_STAT_RESETVAL = WT_QIC02_STAT_RESETVAL;
-       
-       QIC02_CTL_RESET = WT_QIC02_CTL_RESET;
-       QIC02_CTL_REQUEST = WT_QIC02_CTL_REQUEST;
-       if (QIC02_TAPE_DMA == 3)
-       {
-           WT_CTL_DMA = WT_CTL_DMA3;
-       }
-       else if (QIC02_TAPE_DMA == 1)
-       {
-           WT_CTL_DMA = WT_CTL_DMA1;
-       }
-       else
-       {
-           tpqputs(TPQD_ALWAYS, "Unsupported or incorrect DMA channel");
-           return -EIO;
-       } 
+       QIC02_TAPE_IFC = ifc;
+
+       if ((QIC02_TAPE_IFC == WANGTEK) || (QIC02_TAPE_IFC == EVEREX)) {
+               QIC02_STAT_PORT = QIC02_TAPE_PORT;
+               QIC02_CTL_PORT = QIC02_TAPE_PORT;
+               QIC02_CMD_PORT = QIC02_TAPE_PORT + 1;
+               QIC02_DATA_PORT = QIC02_TAPE_PORT + 1;
+               QIC02_STAT_READY = WT_QIC02_STAT_READY;
+               QIC02_STAT_EXCEPTION = WT_QIC02_STAT_EXCEPTION;
+               QIC02_STAT_MASK = WT_QIC02_STAT_MASK;
+
+               QIC02_STAT_RESETMASK = WT_QIC02_STAT_RESETMASK;
+               QIC02_STAT_RESETVAL = WT_QIC02_STAT_RESETVAL;
+
+               QIC02_CTL_RESET = WT_QIC02_CTL_RESET;
+               QIC02_CTL_REQUEST = WT_QIC02_CTL_REQUEST;
+
+               if (QIC02_TAPE_DMA == 3) {
+                       WT_CTL_DMA = WT_CTL_DMA3;
+               } else if (QIC02_TAPE_DMA == 1) {
+                       WT_CTL_DMA = WT_CTL_DMA1;
+               } else {
+                       tpqputs(TPQD_ALWAYS,
+                               "Unsupported or incorrect DMA channel");
+                       return -EIO;
+               }
 
-       if (QIC02_TAPE_IFC == EVEREX)
-       {
-           /* Everex is a special case for Wangtek (actually
-            * it's the other way 'round, but I saw Wangtek first)
-            */
-           if (QIC02_TAPE_DMA==3)
-           {
-               WT_CTL_DMA = WT_CTL_DMA1;
-           }
-           
-           /* Fixup the kernel copy of the IFC type to that
-            * we don't have to distinguish between Wangtek and
-            * and Everex at runtime.
-            */
-           QIC02_TAPE_IFC = WANGTEK;
-       }
-    }
-    else if (QIC02_TAPE_IFC == ARCHIVE)
-    {
-       QIC02_STAT_PORT = QIC02_TAPE_PORT+1;
-       QIC02_CTL_PORT = QIC02_TAPE_PORT+1;
-       QIC02_CMD_PORT = QIC02_TAPE_PORT;
-       QIC02_DATA_PORT = QIC02_TAPE_PORT;
-       QIC02_STAT_READY = AR_QIC02_STAT_READY;
-       QIC02_STAT_EXCEPTION  = AR_QIC02_STAT_EXCEPTION;
-       QIC02_STAT_MASK = AR_QIC02_STAT_MASK;
-       
-       QIC02_STAT_RESETMASK = AR_QIC02_STAT_RESETMASK;
-       QIC02_STAT_RESETVAL = AR_QIC02_STAT_RESETVAL;
-       
-       QIC02_CTL_RESET = AR_QIC02_CTL_RESET;
-       QIC02_CTL_REQUEST = AR_QIC02_CTL_REQUEST;
-       
-       if (QIC02_TAPE_DMA > 3)
-       {
-           tpqputs(TPQD_ALWAYS, "Unsupported or incorrect DMA channel");
-           return -EIO;
-       } 
-    }
-    else if (QIC02_TAPE_IFC == MOUNTAIN)
-    {
-       QIC02_STAT_PORT = QIC02_TAPE_PORT+1;
-       QIC02_CTL_PORT = QIC02_TAPE_PORT+1;
-       QIC02_CMD_PORT = QIC02_TAPE_PORT;
-       QIC02_DATA_PORT = QIC02_TAPE_PORT;
-       
-       QIC02_STAT_READY = MTN_QIC02_STAT_READY;
-       QIC02_STAT_EXCEPTION  = MTN_QIC02_STAT_EXCEPTION;
-       QIC02_STAT_MASK = MTN_QIC02_STAT_MASK;
-       
-       QIC02_STAT_RESETMASK = MTN_QIC02_STAT_RESETMASK;
-       QIC02_STAT_RESETVAL = MTN_QIC02_STAT_RESETVAL;
-       
-       QIC02_CTL_RESET = MTN_QIC02_CTL_RESET;
-       QIC02_CTL_REQUEST = MTN_QIC02_CTL_REQUEST;
-       
-       if (QIC02_TAPE_DMA > 3)
-       {
-           tpqputs(TPQD_ALWAYS, "Unsupported or incorrect DMA channel");
-           return -EIO;
-       } 
-    }
-    else
-    {
-       tpqputs(TPQD_ALWAYS, "Invalid interface type");
-       return -ENXIO;
-    }
-    return qic02_get_resources();
-} /* update_ifc_masks */
+               if (QIC02_TAPE_IFC == EVEREX) {
+                       /* Everex is a special case for Wangtek (actually
+                        * it's the other way 'round, but I saw Wangtek first)
+                        */
+                       if (QIC02_TAPE_DMA == 3) {
+                               WT_CTL_DMA = WT_CTL_DMA1;
+                       }
+
+                       /* Fixup the kernel copy of the IFC type to that
+                        * we don't have to distinguish between Wangtek and
+                        * and Everex at runtime.
+                        */
+                       QIC02_TAPE_IFC = WANGTEK;
+               }
+       } else if (QIC02_TAPE_IFC == ARCHIVE) {
+               QIC02_STAT_PORT = QIC02_TAPE_PORT + 1;
+               QIC02_CTL_PORT = QIC02_TAPE_PORT + 1;
+               QIC02_CMD_PORT = QIC02_TAPE_PORT;
+               QIC02_DATA_PORT = QIC02_TAPE_PORT;
+               QIC02_STAT_READY = AR_QIC02_STAT_READY;
+               QIC02_STAT_EXCEPTION = AR_QIC02_STAT_EXCEPTION;
+               QIC02_STAT_MASK = AR_QIC02_STAT_MASK;
+
+               QIC02_STAT_RESETMASK = AR_QIC02_STAT_RESETMASK;
+               QIC02_STAT_RESETVAL = AR_QIC02_STAT_RESETVAL;
+
+               QIC02_CTL_RESET = AR_QIC02_CTL_RESET;
+               QIC02_CTL_REQUEST = AR_QIC02_CTL_REQUEST;
+
+               if (QIC02_TAPE_DMA > 3) {
+                       tpqputs(TPQD_ALWAYS,
+                               "Unsupported or incorrect DMA channel");
+                       return -EIO;
+               }
+       } else if (QIC02_TAPE_IFC == MOUNTAIN) {
+               QIC02_STAT_PORT = QIC02_TAPE_PORT + 1;
+               QIC02_CTL_PORT = QIC02_TAPE_PORT + 1;
+               QIC02_CMD_PORT = QIC02_TAPE_PORT;
+               QIC02_DATA_PORT = QIC02_TAPE_PORT;
+
+               QIC02_STAT_READY = MTN_QIC02_STAT_READY;
+               QIC02_STAT_EXCEPTION = MTN_QIC02_STAT_EXCEPTION;
+               QIC02_STAT_MASK = MTN_QIC02_STAT_MASK;
+
+               QIC02_STAT_RESETMASK = MTN_QIC02_STAT_RESETMASK;
+               QIC02_STAT_RESETVAL = MTN_QIC02_STAT_RESETVAL;
+
+               QIC02_CTL_RESET = MTN_QIC02_CTL_RESET;
+               QIC02_CTL_REQUEST = MTN_QIC02_CTL_REQUEST;
+
+               if (QIC02_TAPE_DMA > 3) {
+                       tpqputs(TPQD_ALWAYS,
+                               "Unsupported or incorrect DMA channel");
+                       return -EIO;
+               }
+       } else {
+               tpqputs(TPQD_ALWAYS, "Invalid interface type");
+               return -ENXIO;
+       }
+       return qic02_get_resources();
+}                              /* update_ifc_masks */
 #endif
 
 
 /* ioctl allows user programs to rewind the tape and stuff like that */
-static int qic02_tape_ioctl(struct inode * inode, struct file * filp, 
-                    unsigned int iocmd, unsigned long ioarg)
+static int qic02_tape_ioctl(struct inode *inode, struct file *filp,
+                           unsigned int iocmd, unsigned long ioarg)
 {
-    int error;
-    int dev_maj = MAJOR(inode->i_rdev);
-    int c;
-    struct mtop operation;
-    unsigned char blk_addr[6];
-    struct mtpos ioctl_tell;
-    
-
-    if (TP_DIAGS(current_tape_dev))
-    {
-       printk(TPQIC02_NAME ": ioctl(%4x, %4x, %4lx)\n", dev_maj, iocmd, ioarg);
-    }
-    
-    if (!inode || !ioarg)
-    {
-       return -EINVAL;
-    }
-    
-    /* check iocmd first */
+       int error;
+       int dev_maj = MAJOR(inode->i_rdev);
+       int c;
+       struct mtop operation;
+       unsigned char blk_addr[6];
+       struct mtpos ioctl_tell;
 
-    if (dev_maj != QIC02_TAPE_MAJOR)
-    {
-       printk(TPQIC02_NAME ": Oops! Wrong device?\n");
-       /* A panic() would be appropriate here */
-       return -ENODEV;
-    }
 
-    c = _IOC_NR(iocmd);
-
-#ifdef CONFIG_QIC02_DYNCONF
-    if (c == _IOC_NR(MTIOCGETCONFIG))
-    {
-       CHECK_IOC_SIZE(mtconfiginfo);
+       if (TP_DIAGS(current_tape_dev)) {
+               printk(TPQIC02_NAME ": ioctl(%4x, %4x, %4lx)\n", dev_maj,
+                      iocmd, ioarg);
+       }
 
-       if (copy_to_user((char *) ioarg, (char *) &qic02_tape_dynconf, sizeof(qic02_tape_dynconf)))
-       {
-           return -EFAULT;
+       if (!inode || !ioarg) {
+               return -EINVAL;
        }
-       return 0;
 
-    }
-    else if (c == _IOC_NR(MTIOCSETCONFIG))
-    {
-       /* One should always do a MTIOCGETCONFIG first, then update
-        * user-settings, then write back with MTIOCSETCONFIG.
-        * The qic02conf program should re-open() the device before actual
-        * use, to make sure everything is initialized.
-        */
-       
-       CHECK_IOC_SIZE(mtconfiginfo);
-       
-       if (!capable(CAP_SYS_ADMIN))
-       {
-           return -EPERM;
+       /* check iocmd first */
+
+       if (dev_maj != QIC02_TAPE_MAJOR) {
+               printk(TPQIC02_NAME ": Oops! Wrong device?\n");
+               /* A panic() would be appropriate here */
+               return -ENODEV;
        }
-       
-       if ((doing_read!=NO) || (doing_write!=NO))
-       {
-           return -EBUSY;
+
+       c = _IOC_NR(iocmd);
+
+#ifdef CONFIG_QIC02_DYNCONF
+       if (c == _IOC_NR(MTIOCGETCONFIG)) {
+               CHECK_IOC_SIZE(mtconfiginfo);
+
+               if (copy_to_user
+                   ((char *) ioarg, (char *) &qic02_tape_dynconf,
+                    sizeof(qic02_tape_dynconf))) {
+                       return -EFAULT;
+               }
+               return 0;
+
+       } else if (c == _IOC_NR(MTIOCSETCONFIG)) {
+               /* One should always do a MTIOCGETCONFIG first, then update
+                * user-settings, then write back with MTIOCSETCONFIG.
+                * The qic02conf program should re-open() the device before actual
+                * use, to make sure everything is initialized.
+                */
+
+               CHECK_IOC_SIZE(mtconfiginfo);
+
+               if (!capable(CAP_SYS_ADMIN)) {
+                       return -EPERM;
+               }
+
+               if ((doing_read != NO) || (doing_write != NO)) {
+                       return -EBUSY;
+               }
+
+               if (status_zombie == NO) {
+                       qic02_release_resources();      /* and go zombie */
+               }
+
+               /* copy struct from user space to kernel space */
+               if (copy_from_user
+                   ((char *) &qic02_tape_dynconf, (char *) ioarg,
+                    sizeof(qic02_tape_dynconf))) {
+                       return -EFAULT;
+               }
+               return update_ifc_masks(qic02_tape_dynconf.ifc_type);
        }
-       
-       if (status_zombie==NO)
-       {
-           qic02_release_resources();  /* and go zombie */
+       if (status_zombie == YES) {
+               tpqputs(TPQD_ALWAYS, "Configs not set");
+               return -ENXIO;
        }
-       
-       /* copy struct from user space to kernel space */
-       if (copy_from_user((char *) &qic02_tape_dynconf, (char *) ioarg, sizeof(qic02_tape_dynconf)))
-       {
-           return -EFAULT;
-       }
-       return update_ifc_masks(qic02_tape_dynconf.ifc_type);
-    }
-    if (status_zombie==YES)
-    {
-       tpqputs(TPQD_ALWAYS, "Configs not set");
-       return -ENXIO;
-    }
 #endif
-    if (c == _IOC_NR(MTIOCTOP))
-    {
-       CHECK_IOC_SIZE(mtop);
+       if (c == _IOC_NR(MTIOCTOP)) {
+               CHECK_IOC_SIZE(mtop);
+
+               /* copy mtop struct from user space to kernel space */
+               if (copy_from_user
+                   ((char *) &operation, (char *) ioarg,
+                    sizeof(operation))) {
+                       return -EFAULT;
+               }
 
-       /* copy mtop struct from user space to kernel space */
-       if (copy_from_user((char *) &operation, (char *) ioarg, sizeof(operation)))
-       {
-           return -EFAULT;
-       }
+               /* ---note: mt_count is signed, negative seeks must be
+                * ---      translated to seeks in opposite direction!
+                * (only needed for Sun-programs, I think.)
+                */
+               /* ---note: MTFSF with count 0 should position the
+                * ---      tape at the beginning of the current file.
+                */
 
-       /* ---note: mt_count is signed, negative seeks must be
-        * ---      translated to seeks in opposite direction!
-        * (only needed for Sun-programs, I think.)
-        */
-       /* ---note: MTFSF with count 0 should position the
-        * ---      tape at the beginning of the current file.
-        */
+               if (TP_DIAGS(current_tape_dev)) {
+                       printk("OP op=%4x, count=%4x\n", operation.mt_op,
+                              operation.mt_count);
+               }
+
+               if (operation.mt_count < 0) {
+                       tpqputs(TPQD_ALWAYS,
+                               "Warning: negative mt_count ignored");
+               }
 
-       if (TP_DIAGS(current_tape_dev))
-       {
-           printk("OP op=%4x, count=%4x\n", operation.mt_op, operation.mt_count);
-       }
-       
-       if (operation.mt_count < 0)
-       {
-           tpqputs(TPQD_ALWAYS, "Warning: negative mt_count ignored");
-       }
-       
-       ioctl_status.mt_resid = operation.mt_count;
-       if (operation.mt_op == MTSEEK)
-       {
-           if (!TP_HAVE_SEEK)
-           {
-               return -ENOTTY;
-           }
-           
-           seek_addr_buf[0] = (operation.mt_count>>16)&0xff;
-           seek_addr_buf[1] = (operation.mt_count>>8)&0xff;
-           seek_addr_buf[2] = (operation.mt_count)&0xff;
-           if (operation.mt_count>>24)
-           {
-               return -EINVAL;
-           }
-           if ((error = do_ioctl_cmd(operation.mt_op)) != 0)
-           {
-               return error;
-           }
-           
-           ioctl_status.mt_resid = 0;
-       }
-       else
-       {
-           while (operation.mt_count > 0)
-           {
-               operation.mt_count--;
-               if ((error = do_ioctl_cmd(operation.mt_op)) != 0)
-               {
-                   return error;
-               }
-               
                ioctl_status.mt_resid = operation.mt_count;
-           }
-       }
-       return 0;
-       
-    }
-    else if (c == _IOC_NR(MTIOCGET))
-    {
-       if (TP_DIAGS(current_tape_dev))
-       {
-           printk("GET ");
-       }
-       
-       CHECK_IOC_SIZE(mtget);
+               if (operation.mt_op == MTSEEK) {
+                       if (!TP_HAVE_SEEK) {
+                               return -ENOTTY;
+                       }
 
-       /* It appears (gmt(1)) that it is normal behaviour to
-        * first set the status with MTNOP, and then to read
-        * it out with MTIOCGET
-        */
+                       seek_addr_buf[0] =
+                           (operation.mt_count >> 16) & 0xff;
+                       seek_addr_buf[1] =
+                           (operation.mt_count >> 8) & 0xff;
+                       seek_addr_buf[2] = (operation.mt_count) & 0xff;
+                       if (operation.mt_count >> 24) {
+                               return -EINVAL;
+                       }
+                       if ((error = do_ioctl_cmd(operation.mt_op)) != 0) {
+                               return error;
+                       }
 
-       /* copy results to user space */
-       if (copy_to_user((char *) ioarg, (char *) &ioctl_status, sizeof(ioctl_status)))
-       {
-           return -EFAULT;
-       }       
-       return 0;
-    }
-    else if (TP_HAVE_TELL && (c == _IOC_NR(MTIOCPOS)))
-    {
-       if (TP_DIAGS(current_tape_dev))
-       {
-           printk("POS ");
-       }
-       
-       CHECK_IOC_SIZE(mtpos);
-       
-       tpqputs(TPQD_IOCTLS, "MTTELL reading block address");
-       if ((doing_read==YES) || (doing_write==YES))
-       {
-           finish_rw(AR_QCMDV_TELL_BLK);
-       }
-       
-       c = rdstatus((char *) blk_addr, sizeof(blk_addr), AR_QCMDV_TELL_BLK);
-       if (c!=TE_OK)
-       {
-           return -EIO;
-       }
-       
-       ioctl_tell.mt_blkno = (blk_addr[3] << 16) | (blk_addr[4] << 8) | blk_addr[5];
+                       ioctl_status.mt_resid = 0;
+               } else {
+                       while (operation.mt_count > 0) {
+                               operation.mt_count--;
+                               if ((error =
+                                    do_ioctl_cmd(operation.mt_op)) != 0) {
+                                       return error;
+                               }
 
-       /* copy results to user space */
-       if (copy_to_user((char *) ioarg, (char *) &ioctl_tell, sizeof(ioctl_tell)))
-       {
-           return -EFAULT;
-       }
-       return 0;
+                               ioctl_status.mt_resid = operation.mt_count;
+                       }
+               }
+               return 0;
+
+       } else if (c == _IOC_NR(MTIOCGET)) {
+               if (TP_DIAGS(current_tape_dev)) {
+                       printk("GET ");
+               }
+
+               CHECK_IOC_SIZE(mtget);
+
+               /* It appears (gmt(1)) that it is normal behaviour to
+                * first set the status with MTNOP, and then to read
+                * it out with MTIOCGET
+                */
+
+               /* copy results to user space */
+               if (copy_to_user
+                   ((char *) ioarg, (char *) &ioctl_status,
+                    sizeof(ioctl_status))) {
+                       return -EFAULT;
+               }
+               return 0;
+       } else if (TP_HAVE_TELL && (c == _IOC_NR(MTIOCPOS))) {
+               if (TP_DIAGS(current_tape_dev)) {
+                       printk("POS ");
+               }
+
+               CHECK_IOC_SIZE(mtpos);
+
+               tpqputs(TPQD_IOCTLS, "MTTELL reading block address");
+               if ((doing_read == YES) || (doing_write == YES)) {
+                       finish_rw(AR_QCMDV_TELL_BLK);
+               }
+
+               c = rdstatus((char *) blk_addr, sizeof(blk_addr),
+                            AR_QCMDV_TELL_BLK);
+               if (c != TE_OK) {
+                       return -EIO;
+               }
 
-    }
-    else
-    {
-       return -ENOTTY; /* Other cmds not supported. */
-    }
-} /* qic02_tape_ioctl */
+               ioctl_tell.mt_blkno =
+                   (blk_addr[3] << 16) | (blk_addr[4] << 8) | blk_addr[5];
+
+               /* copy results to user space */
+               if (copy_to_user
+                   ((char *) ioarg, (char *) &ioctl_tell,
+                    sizeof(ioctl_tell))) {
+                       return -EFAULT;
+               }
+               return 0;
+
+       } else {
+               return -ENOTTY; /* Other cmds not supported. */
+       }
+}                              /* qic02_tape_ioctl */
 
 
 
 /* These are (most) of the interface functions: */
 static struct file_operations qic02_tape_fops = {
-       owner:          THIS_MODULE,
-       llseek:         no_llseek,
-       read:           qic02_tape_read,
-       write:          qic02_tape_write,
-       ioctl:          qic02_tape_ioctl,
-       open:           qic02_tape_open,
-       release:        qic02_tape_release,
+       owner:THIS_MODULE,
+       llseek:no_llseek,
+       read:qic02_tape_read,
+       write:qic02_tape_write,
+       ioctl:qic02_tape_ioctl,
+       open:qic02_tape_open,
+       release:qic02_tape_release,
 };
 
 
 static void qic02_release_resources(void)
 {
-    free_irq(QIC02_TAPE_IRQ, NULL);
-    free_dma(QIC02_TAPE_DMA);
-    release_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE);
-    if (buffaddr)
-    {
-       free_pages((unsigned long)buffaddr, get_order(TPQBUF_SIZE));
-    }
-    buffaddr = 0; /* Better to cause a panic than overwite someone else */
-    status_zombie = YES;
-} /* qic02_release_resources */
+       free_irq(QIC02_TAPE_IRQ, NULL);
+       free_dma(QIC02_TAPE_DMA);
+       release_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE);
+       if (buffaddr) {
+               free_pages((unsigned long) buffaddr,
+                          get_order(TPQBUF_SIZE));
+       }
+       buffaddr = 0;           /* Better to cause a panic than overwite someone else */
+       status_zombie = YES;
+}                              /* qic02_release_resources */
 
 
 static int qic02_get_resources(void)
 {
-    /* First perform some checks. If one of them fails,
-     * the tape driver will not be registered to the system.
-     */
-    if (QIC02_TAPE_IRQ>16)
-    {
-       tpqputs(TPQD_ALWAYS, "Bogus interrupt number.");
-       return -ENXIO;
-    }
-
-    /* for DYNCONF, allocating IO, DMA and IRQ should not be done until 
-     * the config parameters have been set using MTSETCONFIG.
-     */
-
-    if (check_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE))
-    {
-       printk(TPQIC02_NAME ": IO space at 0x%x [%d ports] already reserved\n",
-              QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE);
-       return -ENXIO;
-    }
-
-    /* get IRQ */
-    if (request_irq(QIC02_TAPE_IRQ, qic02_tape_interrupt, SA_INTERRUPT, "QIC-02", NULL))
-    {
-       printk(TPQIC02_NAME ": can't allocate IRQ%d for QIC-02 tape\n",
-              QIC02_TAPE_IRQ);
-       return -EBUSY;
-    }
-
-    /* After IRQ, allocate DMA channel */
-    if (request_dma(QIC02_TAPE_DMA,"QIC-02"))
-    {
-       printk(TPQIC02_NAME ": can't allocate DMA%d for QIC-02 tape\n",
-              QIC02_TAPE_DMA);
-       free_irq(QIC02_TAPE_IRQ, NULL);
-       return -EBUSY;
-    }
-
-    /* Grab the IO region. We already made sure it's available. */
-    request_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE, TPQIC02_NAME);
-    
-    /* Setup the page-address for the dma transfer. */
-    buffaddr = (void *)__get_dma_pages(GFP_KERNEL, get_order(TPQBUF_SIZE));
-    
-    if (!buffaddr)
-    {
-       qic02_release_resources();
-       return -EBUSY; /* Not ideal, EAGAIN perhaps? */
-    }
-    
-    memset(buffaddr, 0, TPQBUF_SIZE);
-    
-    printk(TPQIC02_NAME ": Settings: IRQ %d, DMA %d, IO 0x%x, IFC %s\n",
-          QIC02_TAPE_IRQ, QIC02_TAPE_DMA,
-          ((QIC02_TAPE_IFC==ARCHIVE) || (QIC02_TAPE_IFC==MOUNTAIN))?
-          QIC02_CMD_PORT : QIC02_STAT_PORT,
-          (QIC02_TAPE_IFC==MOUNTAIN)? "Mountain" :
-          ((QIC02_TAPE_IFC==ARCHIVE)? "Archive" : "Wangtek"));
-    
-    if (tape_reset(0)!=TE_OK || tp_sense(TP_WRP|TP_POR|TP_CNI)!=TE_OK)
-    {
-       /* No drive detected, so vanish */
-       tpqputs(TPQD_ALWAYS, "No drive detected -- releasing IO/IRQ/DMA.");
-       status_dead = YES;
-       qic02_release_resources();
-       return -EIO;
-    }
-
-    /* All should be ok now */
-    status_zombie = NO;
-    return 0;
-} /* qic02_get_resources */
+       /* First perform some checks. If one of them fails,
+        * the tape driver will not be registered to the system.
+        */
+       if (QIC02_TAPE_IRQ > 16) {
+               tpqputs(TPQD_ALWAYS, "Bogus interrupt number.");
+               return -ENXIO;
+       }
+
+       /* for DYNCONF, allocating IO, DMA and IRQ should not be done until 
+        * the config parameters have been set using MTSETCONFIG.
+        */
+
+       if (check_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE)) {
+               printk(TPQIC02_NAME
+                      ": IO space at 0x%x [%d ports] already reserved\n",
+                      QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE);
+               return -ENXIO;
+       }
+
+       /* get IRQ */
+       if (request_irq
+           (QIC02_TAPE_IRQ, qic02_tape_interrupt, SA_INTERRUPT, "QIC-02",
+            NULL)) {
+               printk(TPQIC02_NAME
+                      ": can't allocate IRQ%d for QIC-02 tape\n",
+                      QIC02_TAPE_IRQ);
+               return -EBUSY;
+       }
+
+       /* After IRQ, allocate DMA channel */
+       if (request_dma(QIC02_TAPE_DMA, "QIC-02")) {
+               printk(TPQIC02_NAME
+                      ": can't allocate DMA%d for QIC-02 tape\n",
+                      QIC02_TAPE_DMA);
+               free_irq(QIC02_TAPE_IRQ, NULL);
+               return -EBUSY;
+       }
+
+       /* Grab the IO region. We already made sure it's available. */
+       request_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE,
+                      TPQIC02_NAME);
+
+       /* Setup the page-address for the dma transfer. */
+       buffaddr =
+           (void *) __get_dma_pages(GFP_KERNEL, get_order(TPQBUF_SIZE));
+
+       if (!buffaddr) {
+               qic02_release_resources();
+               return -EBUSY;  /* Not ideal, EAGAIN perhaps? */
+       }
+
+       memset(buffaddr, 0, TPQBUF_SIZE);
+
+       printk(TPQIC02_NAME
+              ": Settings: IRQ %d, DMA %d, IO 0x%x, IFC %s\n",
+              QIC02_TAPE_IRQ, QIC02_TAPE_DMA, ((QIC02_TAPE_IFC == ARCHIVE)
+                                               || (QIC02_TAPE_IFC ==
+                                                   MOUNTAIN)) ?
+              QIC02_CMD_PORT : QIC02_STAT_PORT,
+              (QIC02_TAPE_IFC ==
+               MOUNTAIN) ? "Mountain" : ((QIC02_TAPE_IFC ==
+                                          ARCHIVE) ? "Archive" :
+                                         "Wangtek"));
+
+       if (tape_reset(0) != TE_OK
+           || tp_sense(TP_WRP | TP_POR | TP_CNI) != TE_OK) {
+               /* No drive detected, so vanish */
+               tpqputs(TPQD_ALWAYS,
+                       "No drive detected -- releasing IO/IRQ/DMA.");
+               status_dead = YES;
+               qic02_release_resources();
+               return -EIO;
+       }
+
+       /* All should be ok now */
+       status_zombie = NO;
+       return 0;
+}                              /* qic02_get_resources */
 
 int __init qic02_tape_init(void)
 {
-    if (TPSTATSIZE != 6)
-    {
-       printk(TPQIC02_NAME ": internal error: tpstatus struct incorrect!\n");
-       return -ENODEV;
-    }
-    if ((TPQBUF_SIZE<512) || (TPQBUF_SIZE>=0x10000))
-    {
-       printk(TPQIC02_NAME ": internal error: DMA buffer size out of range\n");
-       return -ENODEV;
-    }
-
-    current_tape_dev = MKDEV(QIC02_TAPE_MAJOR, 0);
+       if (TPSTATSIZE != 6) {
+               printk(TPQIC02_NAME
+                      ": internal error: tpstatus struct incorrect!\n");
+               return -ENODEV;
+       }
+       if ((TPQBUF_SIZE < 512) || (TPQBUF_SIZE >= 0x10000)) {
+               printk(TPQIC02_NAME
+                      ": internal error: DMA buffer size out of range\n");
+               return -ENODEV;
+       }
+
+       current_tape_dev = MKDEV(QIC02_TAPE_MAJOR, 0);
 
 #ifndef CONFIG_QIC02_DYNCONF
-    printk(TPQIC02_NAME ": IRQ %d, DMA %d, IO 0x%x, IFC %s, %s, %s\n",
-          QIC02_TAPE_IRQ, QIC02_TAPE_DMA,
+       printk(TPQIC02_NAME ": IRQ %d, DMA %d, IO 0x%x, IFC %s, %s, %s\n",
+              QIC02_TAPE_IRQ, QIC02_TAPE_DMA,
 # if QIC02_TAPE_IFC == WANGTEK
-          QIC02_STAT_PORT, "Wangtek",
+              QIC02_STAT_PORT, "Wangtek",
 # elif QIC02_TAPE_IFC == ARCHIVE
-          QIC02_CMD_PORT, "Archive",
+              QIC02_CMD_PORT, "Archive",
 # elif QIC02_TAPE_IFC == MOUNTAIN
-          QIC02_CMD_PORT, "Mountain",
+              QIC02_CMD_PORT, "Mountain",
 # else
 #  error
 # endif
-          rcs_revision, rcs_date);
-    if (qic02_get_resources())
-    {
-       return -ENODEV;
-    }
+              rcs_revision, rcs_date);
+       if (qic02_get_resources()) {
+               return -ENODEV;
+       }
 #else
-    printk(TPQIC02_NAME ": Runtime config, %s, %s\n", 
-          rcs_revision, rcs_date);
+       printk(TPQIC02_NAME ": Runtime config, %s, %s\n",
+              rcs_revision, rcs_date);
 #endif
-    printk(TPQIC02_NAME ": DMA buffers: %u blocks\n", NR_BLK_BUF);
-    /* If we got this far, install driver functions */
-    if (devfs_register_chrdev(QIC02_TAPE_MAJOR, TPQIC02_NAME, &qic02_tape_fops))
-    {
-       printk(TPQIC02_NAME ": Unable to get chrdev major %d\n", QIC02_TAPE_MAJOR);
+       printk(TPQIC02_NAME ": DMA buffers: %u blocks\n", NR_BLK_BUF);
+       /* If we got this far, install driver functions */
+       if (devfs_register_chrdev
+           (QIC02_TAPE_MAJOR, TPQIC02_NAME, &qic02_tape_fops)) {
+               printk(TPQIC02_NAME ": Unable to get chrdev major %d\n",
+                      QIC02_TAPE_MAJOR);
 #ifndef CONFIG_QIC02_DYNCONF
-       qic02_release_resources();
+               qic02_release_resources();
 #endif
-       return -ENODEV;
-    }
-    devfs_register (NULL, "ntpqic11", DEVFS_FL_DEFAULT,
-                   QIC02_TAPE_MAJOR, 2,
-                   S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
-                   &qic02_tape_fops, NULL);
-    devfs_register (NULL, "tpqic11", DEVFS_FL_DEFAULT,
-                   QIC02_TAPE_MAJOR, 3,
-                   S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
-                   &qic02_tape_fops, NULL);
-    devfs_register (NULL, "ntpqic24", DEVFS_FL_DEFAULT,
-                   QIC02_TAPE_MAJOR, 4,
-                   S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
-                   &qic02_tape_fops, NULL);
-    devfs_register (NULL, "tpqic24", DEVFS_FL_DEFAULT,
-                   QIC02_TAPE_MAJOR, 5,
-                   S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
-                   &qic02_tape_fops, NULL);
-    devfs_register (NULL, "ntpqic120", DEVFS_FL_DEFAULT,
-                   QIC02_TAPE_MAJOR, 6,
-                   S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
-                   &qic02_tape_fops, NULL);
-    devfs_register (NULL, "tpqic120", DEVFS_FL_DEFAULT,
-                   QIC02_TAPE_MAJOR, 7,
-                   S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
-                   &qic02_tape_fops, NULL);
-    devfs_register (NULL, "ntpqic150", DEVFS_FL_DEFAULT,
-                   QIC02_TAPE_MAJOR, 8,
-                   S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
-                   &qic02_tape_fops, NULL);
-    devfs_register (NULL, "tpqic150", DEVFS_FL_DEFAULT,
-                   QIC02_TAPE_MAJOR, 9,
-                   S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
-                   &qic02_tape_fops, NULL);
-    init_waitqueue_head(&qic02_tape_transfer);
-    /* prepare timer */
-    TIMEROFF;
-    init_timer(&tp_timer);
-    tp_timer.function = qic02_tape_times_out;
-    
+               return -ENODEV;
+       }
+       devfs_register(NULL, "ntpqic11", DEVFS_FL_DEFAULT,
+                      QIC02_TAPE_MAJOR, 2,
+                      S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+                      &qic02_tape_fops, NULL);
+       devfs_register(NULL, "tpqic11", DEVFS_FL_DEFAULT,
+                      QIC02_TAPE_MAJOR, 3,
+                      S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+                      &qic02_tape_fops, NULL);
+       devfs_register(NULL, "ntpqic24", DEVFS_FL_DEFAULT,
+                      QIC02_TAPE_MAJOR, 4,
+                      S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+                      &qic02_tape_fops, NULL);
+       devfs_register(NULL, "tpqic24", DEVFS_FL_DEFAULT,
+                      QIC02_TAPE_MAJOR, 5,
+                      S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+                      &qic02_tape_fops, NULL);
+       devfs_register(NULL, "ntpqic120", DEVFS_FL_DEFAULT,
+                      QIC02_TAPE_MAJOR, 6,
+                      S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+                      &qic02_tape_fops, NULL);
+       devfs_register(NULL, "tpqic120", DEVFS_FL_DEFAULT,
+                      QIC02_TAPE_MAJOR, 7,
+                      S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+                      &qic02_tape_fops, NULL);
+       devfs_register(NULL, "ntpqic150", DEVFS_FL_DEFAULT,
+                      QIC02_TAPE_MAJOR, 8,
+                      S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+                      &qic02_tape_fops, NULL);
+       devfs_register(NULL, "tpqic150", DEVFS_FL_DEFAULT,
+                      QIC02_TAPE_MAJOR, 9,
+                      S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+                      &qic02_tape_fops, NULL);
+       init_waitqueue_head(&qic02_tape_transfer);
+       /* prepare timer */
+       TIMEROFF;
+       init_timer(&tp_timer);
+       tp_timer.function = qic02_tape_times_out;
+
 #ifndef CONFIG_QIC02_DYNCONF
-    if (tape_reset(0)!=TE_OK || tp_sense(TP_WRP|TP_POR|TP_CNI)!=TE_OK)
-    {
-       /* No drive detected, so vanish */
-       tpqputs(TPQD_ALWAYS, "No drive detected -- driver going on vacation...");
-       qic02_release_resources();
-       status_dead = YES;
-       return -ENODEV;
-    }
-    else
-    {
-       if (is_exception())
-       {
-           tpqputs(TPQD_ALWAYS, "exception detected\n");
-           (void) tp_sense(TP_WRP|TP_POR|TP_CNI);
+       if (tape_reset(0) != TE_OK
+           || tp_sense(TP_WRP | TP_POR | TP_CNI) != TE_OK) {
+               /* No drive detected, so vanish */
+               tpqputs(TPQD_ALWAYS,
+                       "No drive detected -- driver going on vacation...");
+               qic02_release_resources();
+               status_dead = YES;
+               return -ENODEV;
+       } else {
+               if (is_exception()) {
+                       tpqputs(TPQD_ALWAYS, "exception detected\n");
+                       (void) tp_sense(TP_WRP | TP_POR | TP_CNI);
+               }
        }
-    }
 #endif
 
-    /* initialize generic status for ioctl requests */
-    
-    ioctl_status.mt_type       = QIC02_TAPE_DRIVE;     /* MT_IS* id nr */
-    
-    ioctl_status.mt_resid      = 0;    /* ---residual count */
-    ioctl_status.mt_gstat      = 0;    /* ---generic status */
-    ioctl_status.mt_erreg      = 0;    /* not used */
-    ioctl_status.mt_fileno     = 0;    /* number of current file on tape */
-    ioctl_status.mt_blkno      = 0;    /* number of current (logical) block */
+       /* initialize generic status for ioctl requests */
+
+       ioctl_status.mt_type = QIC02_TAPE_DRIVE;        /* MT_IS* id nr */
 
-    return 0;
-} /* qic02_tape_init */
+       ioctl_status.mt_resid = 0;      /* ---residual count */
+       ioctl_status.mt_gstat = 0;      /* ---generic status */
+       ioctl_status.mt_erreg = 0;      /* not used */
+       ioctl_status.mt_fileno = 0;     /* number of current file on tape */
+       ioctl_status.mt_blkno = 0;      /* number of current (logical) block */
+
+       return 0;
+}                              /* qic02_tape_init */
 
 #ifdef MODULE
 
 void cleanup_module(void)
 {
-    if (status_zombie == NO)
-    {
-       qic02_release_resources();
-    }
-    devfs_unregister_chrdev(QIC02_TAPE_MAJOR, TPQIC02_NAME);
-    devfs_unregister(devfs_find_handle(NULL, "ntpqic11", QIC02_TAPE_MAJOR, 2, DEVFS_SPECIAL_CHR, 0));
-    devfs_unregister(devfs_find_handle(NULL, "tpqic11", QIC02_TAPE_MAJOR, 3, DEVFS_SPECIAL_CHR, 0));
-    devfs_unregister(devfs_find_handle(NULL, "ntpqic24", QIC02_TAPE_MAJOR, 4, DEVFS_SPECIAL_CHR, 0));
-    devfs_unregister(devfs_find_handle(NULL, "tpqic24", QIC02_TAPE_MAJOR, 5, DEVFS_SPECIAL_CHR, 0));
-    devfs_unregister(devfs_find_handle(NULL, "ntpqic120", QIC02_TAPE_MAJOR, 6, DEVFS_SPECIAL_CHR, 0));
-    devfs_unregister(devfs_find_handle(NULL, "tpqic120", QIC02_TAPE_MAJOR, 7, DEVFS_SPECIAL_CHR, 0));
-    devfs_unregister(devfs_find_handle(NULL, "ntpqic150", QIC02_TAPE_MAJOR, 8, DEVFS_SPECIAL_CHR, 0));
-    devfs_unregister(devfs_find_handle(NULL, "tpqic150", QIC02_TAPE_MAJOR, 9, DEVFS_SPECIAL_CHR, 0));
+       if (status_zombie == NO) {
+               qic02_release_resources();
+       }
+       devfs_unregister_chrdev(QIC02_TAPE_MAJOR, TPQIC02_NAME);
+       devfs_unregister(devfs_find_handle
+                        (NULL, "ntpqic11", QIC02_TAPE_MAJOR, 2,
+                         DEVFS_SPECIAL_CHR, 0));
+       devfs_unregister(devfs_find_handle
+                        (NULL, "tpqic11", QIC02_TAPE_MAJOR, 3,
+                         DEVFS_SPECIAL_CHR, 0));
+       devfs_unregister(devfs_find_handle
+                        (NULL, "ntpqic24", QIC02_TAPE_MAJOR, 4,
+                         DEVFS_SPECIAL_CHR, 0));
+       devfs_unregister(devfs_find_handle
+                        (NULL, "tpqic24", QIC02_TAPE_MAJOR, 5,
+                         DEVFS_SPECIAL_CHR, 0));
+       devfs_unregister(devfs_find_handle
+                        (NULL, "ntpqic120", QIC02_TAPE_MAJOR, 6,
+                         DEVFS_SPECIAL_CHR, 0));
+       devfs_unregister(devfs_find_handle
+                        (NULL, "tpqic120", QIC02_TAPE_MAJOR, 7,
+                         DEVFS_SPECIAL_CHR, 0));
+       devfs_unregister(devfs_find_handle
+                        (NULL, "ntpqic150", QIC02_TAPE_MAJOR, 8,
+                         DEVFS_SPECIAL_CHR, 0));
+       devfs_unregister(devfs_find_handle
+                        (NULL, "tpqic150", QIC02_TAPE_MAJOR, 9,
+                         DEVFS_SPECIAL_CHR, 0));
 }
 
 int init_module(void)
 {
-    int retval;
-    retval=qic02_tape_init();
+       int retval;
+       retval = qic02_tape_init();
 # ifdef CONFIG_QIC02_DYNCONF
-    /* This allows the dynamic config program to setup the card
-     * by presetting qic02_tape_dynconf via insmod
-     */
-    if (!retval && qic02_tape_dynconf.ifc_type)
-    {
-       retval=update_ifc_masks(qic02_tape_dynconf.ifc_type);
-       if (retval)
-       {
-         cleanup_module();
+       /* This allows the dynamic config program to setup the card
+        * by presetting qic02_tape_dynconf via insmod
+        */
+       if (!retval && qic02_tape_dynconf.ifc_type) {
+               retval = update_ifc_masks(qic02_tape_dynconf.ifc_type);
+               if (retval) {
+                       cleanup_module();
+               }
        }
-    }
 # endif
-    return retval;
+       return retval;
 }
 #endif
+
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
index 9d8a1f27f9226d6c32adc626d73907fe363c4537..c50db6cf9f52dfaa5fc6b375be80f51ee7e8e294 100644 (file)
@@ -442,8 +442,6 @@ void do_tty_hangup(void *data)
        file_list_lock();
        for (l = tty->tty_files.next; l != &tty->tty_files; l = l->next) {
                struct file * filp = list_entry(l, struct file, f_list);
-               if (!filp->f_dentry)
-                       continue;
                if (filp->f_dentry->d_inode->i_rdev == CONSOLE_DEV ||
                    filp->f_dentry->d_inode->i_rdev == SYSCONS_DEV) {
                        cons_filp = filp;
diff --git a/drivers/char/vino.h b/drivers/char/vino.h
deleted file mode 100644 (file)
index 5bde398..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/* $Id: vino.h,v 1.2 1999/02/09 23:03:53 ulfc Exp $
- * drivers/sgi/vino.h
- *
- * Copyright (C) 1999 Ulf Carlsson (ulfc@bun.falkenberg.se)
- */
-
-#define VINO_BASE              0x0008000
-
-#define VINO_REVID             0x0000
-#define VINO_CTRL              0x0008
-#define VINO_INTSTAT           0x0010  /* Interrupt status */
-#define VINO_I2C_CTRL          0x0018
-#define VINO_I2C_DATA          0x0020
-#define VINO_A_ALPHA           0x0028  /* Channel A ... */
-#define VINO_A_CLIPS           0x0030  /* Clipping start */
-#define VINO_A_CLIPE           0x0038  /* Clipping end */
-#define VINO_A_FRAMERT         0x0040  /* Framerate */
-#define VINO_A_FLDCNT          0x0048  /* Field counter */
-#define VINO_A_LNSZ            0x0050
-#define VINO_A_LNCNT           0x0058
-#define VINO_A_PGIX            0x0060  /* Page index */
-#define VINO_A_DESC_PTR                0x0068  /* Ptr to next four descriptors */
-#define VINO_A_DESC_TLB_PTR    0x0070  /* Ptr to start of descriptor table */
-#define VINO_A_DESC_DATA0      0x0078  /* Descriptor data 0 */
-#define VINO_A_DESC_DATA1      0x0080  /* ... */
-#define VINO_A_DESC_DATA2      0x0088
-#define VINO_A_DESC_DATA3      0x0090
-#define VINO_A_FIFO_THRESHOLD  0x0098  /* FIFO threshold */
-#define VINO_A_FIFO_RP         0x00a0
-#define VINO_A_FIFO_WP         0x00a8
-#define VINO_B_ALPHA           0x00b0  /* Channel B ... */
-#define VINO_B_CLIPS           0x00b8
-#define VINO_B_CLIPE           0x00c0
-#define VINO_B_FRAMERT         0x00c8
-#define VINO_B_FLDCNT          0x00d0
-#define VINO_B_LNSZ            0x00d8
-#define VINO_B_LNCNT           0x00e0
-#define VINO_B_PGIX            0x00e8
-#define VINO_B_DESC_PTR                0x00f0
-#define VINO_B_DESC_TLB_PTR    0x00f8
-#define VINO_B_DESC_DATA0      0x0100
-#define VINO_B_DESC_DATA1      0x0108
-#define VINO_B_DESC_DATA2      0x0110
-#define VINO_B_DESC_DATA3      0x0118
-#define VINO_B_FIFO_THRESHOLD  0x0120
-#define VINO_B_FIFO_RP         0x0128
-#define VINO_B_FIFO_WP         0x0130
-
-/* Bits in the VINO_REVID register */
-
-#define VINO_REVID_REV_MASK            0x000f  /* bits 0:3 */
-#define VINO_REVID_ID_MASK             0x00f0  /* bits 4:7 */
-
-/* Bits in the VINO_CTRL register */
-
-#define VINO_CTRL_LITTLE_ENDIAN                (1<<0)
-#define VINO_CTRL_A_FIELD_TRANS_INT    (1<<1)  /* Field transferred int */
-#define VINO_CTRL_A_FIFO_OF_INT                (1<<2)  /* FIFO overflow int */
-#define VINO_CTRL_A_END_DESC_TBL_INT   (1<<3)  /* End of desc table int */
-#define VINO_CTRL_B_FIELD_TRANS_INT    (1<<4)  /* Field transferred int */
-#define VINO_CTRL_B_FIFO_OF_INT                (1<<5)  /* FIFO overflow int */
-#define VINO_CTRL_B_END_DESC_TLB_INT   (1<<6)  /* End of desc table int */
-#define VINO_CTRL_A_DMA_ENBL           (1<<7)
-#define VINO_CTRL_A_INTERLEAVE_ENBL    (1<<8)
-#define VINO_CTRL_A_SYNC_ENBL          (1<<9)
-#define VINO_CTRL_A_SELECT             (1<<10) /* 1=D1 0=Philips */
-#define VINO_CTRL_A_RGB                        (1<<11) /* 1=RGB 0=YUV */
-#define VINO_CTRL_A_LUMA_ONLY          (1<<12)
-#define VINO_CTRL_A_DEC_ENBL           (1<<13) /* Decimation */
-#define VINO_CTRL_A_DEC_SCALE_MASK     0x1c000 /* bits 14:17 */
-#define VINO_CTRL_A_DEC_HOR_ONLY       (1<<17) /* Horizontal only */
-#define VINO_CTRL_A_DITHER             (1<<18) /* 24 -> 8 bit dither */
-#define VINO_CTRL_B_DMA_ENBL           (1<<19)
-#define VINO_CTRL_B_INTERLEAVE_ENBL    (1<<20)
-#define VINO_CTRL_B_SYNC_ENBL          (1<<21)
-#define VINO_CTRL_B_SELECT             (1<<22) /* 1=D1 0=Philips */
-#define VINO_CTRL_B_RGB                        (1<<22) /* 1=RGB 0=YUV */
-#define VINO_CTRL_B_LUMA_ONLY          (1<<23)
-#define VINO_CTRL_B_DEC_ENBL           (1<<24) /* Decimation */
-#define VINO_CTRL_B_DEC_SCALE_MASK     0x1c000000      /* bits 25:28 */
-#define VINO_CTRL_B_DEC_HOR_ONLY       (1<<29) /* Decimation horizontal only */
-#define VINO_CTRL_B_DITHER             (1<<30) /* ChanB 24 -> 8 bit dither */
-
-/* Bits in the Interrupt and Status register */
-
-#define VINO_INTSTAT_A_FIELD_TRANS     (1<<0)  /* Field transferred int */
-#define VINO_INTSTAT_A_FIFO_OF         (1<<1)  /* FIFO overflow int */
-#define VINO_INTSTAT_A_END_DESC_TBL    (1<<2)  /* End of desc table int */
-#define VINO_INTSTAT_B_FIELD_TRANS     (1<<3)  /* Field transferred int */
-#define VINO_INTSTAT_B_FIFO_OF         (1<<4)  /* FIFO overflow int */
-#define VINO_INTSTAT_B_END_DESC_TBL    (1<<5)  /* End of desc table int */
-
-/* Bits in the Clipping Start register */
-
-#define VINO_CLIPS_START               0x3ff           /* bits 0:9 */
-#define VINO_CLIPS_ODD_MASK            0x7fc00         /* bits 10:18 */
-#define VINO_CLIPS_EVEN_MASK           0xff80000       /* bits 19:27 */
-
-/* Bits in the Clipping End register */
-
-#define VINO_CLIPE_END                 0x3ff           /* bits 0:9 */
-#define VINO_CLIPE_ODD_MASK            0x7fc00         /* bits 10:18 */
-#define VINO_CLIPE_EVEN_MASK           0xff80000       /* bits 19:27 */
-
-/* Bits in the Frame Rate register */
-
-#define VINO_FRAMERT_PAL               (1<<0)  /* 0=NTSC 1=PAL */
-#define VINO_FRAMERT_RT_MASK           0x1ffe          /* bits 1:12 */
-
-/* Bits in the VINO_I2C_CTRL */
-
-#define VINO_CTRL_I2C_IDLE             (1<<0)  /* write: 0=force idle
-                                                * read: 0=idle 1=not idle */
-#define VINO_CTRL_I2C_DIR              (1<<1)  /* 0=read 1=write */
-#define VINO_CTRL_I2C_MORE_BYTES       (1<<2)  /* 0=last byte 1=more bytes */
-#define VINO_CTRL_I2C_TRANS_BUSY       (1<<4)  /* 0=trans done 1=trans busy */
-#define VINO_CTRL_I2C_ACK              (1<<5)  /* 0=ack received 1=ack not */
-#define VINO_CTRL_I2C_BUS_ERROR                (1<<7)  /* 0=no bus err 1=bus err */
index 893cf5dfc1c3ab2e3004804a5cb0569c106acca7..7ff3e7d3dcedb4eb5fe822806aece5413ff0ec27 100644 (file)
@@ -538,3 +538,7 @@ outmisc:
 module_init(wdt_init);
 module_exit(wdt_exit);
 
+MODULE_AUTHOR("Alan Cox");
+MODULE_DESCRIPTION("Driver for ISA ICS watchdog cards (WDT500/501)");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
index b7baec1fa99ff2163298b7ce11c0c3ed5eef34cd..ca1b7632876999c4d8f9892f13e8cdd98d9eed58 100644 (file)
@@ -190,6 +190,7 @@ EXPORT_NO_SYMBOLS;
 
 MODULE_AUTHOR("Phil Blundell <pb@nexus.co.uk>");
 MODULE_DESCRIPTION("21285 watchdog driver");
+MODULE_LICENSE("GPL");
 
 MODULE_PARM(soft_margin,"i");
 MODULE_PARM_DESC(soft_margin,"Watchdog timeout in seconds");
index 1767fbf3baa0af2e32481fa41cdccd366082a815..74f1fcdbbce75c3ce09b80b6241c7293556f8759 100644 (file)
@@ -199,3 +199,5 @@ EXPORT_NO_SYMBOLS;
 
 module_init(nwwatchdog_init);
 module_exit(nwwatchdog_exit);
+
+MODULE_LICENSE("GPL");
index fae768d3101db6e11305fe57a44aa87a3b052ec6..e4c8e99509b31ef25705dbda0f009f89ff5efcf8 100644 (file)
@@ -626,3 +626,9 @@ static int __init wdtpci_init(void)
 
 module_init(wdtpci_init);
 module_exit(wdtpci_cleanup);
+
+MODULE_AUTHOR("JP Nollmann, Alan Cox");
+MODULE_DESCRIPTION("Driver for the ICS PCI watchdog cards");
+MODULE_LICENSE("GPL");
+
+EXPORT_NO_SYMBOLS;
index c1a7fed6b78bab7d54a381470f51bd5c40938496..6b18bb68902f4a60eaa6b6875d93dd3e4104787d 100644 (file)
@@ -135,7 +135,7 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
         if [ "$CONFIG_BLK_DEV_IDEDISK" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
            bool '    PROMISE DC4030 support (EXPERIMENTAL)' CONFIG_BLK_DEV_PDC4030
         fi
-        bool '    QDI QD6580 support' CONFIG_BLK_DEV_QD6580
+        bool '    QDI QD65xx support' CONFIG_BLK_DEV_QD65XX
         bool '    UMC-8672 support' CONFIG_BLK_DEV_UMC8672
       fi
    fi
index 99ff842635ec38c4078a1b7975355f61625ed802..5362682d271dbd8990a7a65cf37cf0aa56703845 100644 (file)
@@ -56,7 +56,7 @@ ide-obj-$(CONFIG_BLK_DEV_PDC202XX)    += pdc202xx.o
 ide-obj-$(CONFIG_BLK_DEV_PDC4030)      += pdc4030.o
 ide-obj-$(CONFIG_BLK_DEV_PDC_ADMA)     += pdcadma.o
 ide-obj-$(CONFIG_BLK_DEV_PIIX)         += piix.o
-ide-obj-$(CONFIG_BLK_DEV_QD6580)       += qd6580.o
+ide-obj-$(CONFIG_BLK_DEV_QD65XX)       += qd65xx.o
 ide-obj-$(CONFIG_BLK_DEV_IDE_RAPIDE)   += rapide.o
 ide-obj-$(CONFIG_BLK_DEV_RZ1000)       += rz1000.o
 ide-obj-$(CONFIG_BLK_DEV_SIS5513)      += sis5513.o
index 9570f519bfe9dd52e04364c9c1eb47db0dae9632..235298181e3d45dbae31b064dd05f701cfea7c48 100644 (file)
@@ -1,7 +1,8 @@
 /*
- * linux/drivers/ide/ide-floppy.c      Version 0.9.sv  Jan 6 2001
+ * linux/drivers/ide/ide-floppy.c      Version 0.97.sv Jan 14 2001
  *
  * Copyright (C) 1996 - 1999 Gadi Oxman <gadio@netvision.net.il>
+ * Copyright (C) 2000 - 2001 Paul Bristow <paul@paulbristow.net>
  */
 
 /*
  * The driver currently doesn't have any fancy features, just the bare
  * minimum read/write support.
  *
+ * This driver supports the following IDE floppy drives:
+ *
+ * LS-120 SuperDisk
+ * Iomega Zip 100/250
+ * Iomega PC Card Clik!/PocketZip
+ *
  * Many thanks to Lode Leroy <Lode.Leroy@www.ibase.be>, who tested so many
  * ALPHA patches to this driver on an EASYSTOR LS-120 ATAPI floppy drive.
  *
  *                       mode page.  Implemented four IOCTLs in order to
  *                       implement formatting.  IOCTls begin with 0x4600,
  *                       0x46 is 'F' as in Format.
+ *            Jan 9 01   Userland option to select format verify.
+ *                       Added PC_SUPPRESS_ERROR flag - some idefloppy drives
+ *                       do not implement IDEFLOPPY_CAPABILITIES_PAGE, and
+ *                       return a sense error.  Suppress error reporting in
+ *                       this particular case in order to avoid spurious
+ *                       errors in syslog.  The culprit is
+ *                       idefloppy_get_capability_page(), so move it to
+ *                       idefloppy_begin_format() so that it's not used
+ *                       unless absolutely necessary.
+ *                       If drive does not support format progress indication
+ *                       monitor the dsc bit in the status register.
+ *                       Also, O_NDELAY on open will allow the device to be
+ *                       opened without a disk available.  This can be used to
+ *                       open an unformatted disk, or get the device capacity.
  * Ver 0.91  Dec 11 99   Added IOMEGA Clik! drive support by 
  *                        <paul@paulbristow.net>
  * Ver 0.92  Oct 22 00   Paul Bristow became official maintainer for this 
  * Ver 0.96  Jan  7 01   Actually in line with release version of 2.4.0
  *                       including set_bit patch from Rusty Russel
  * Ver 0.97  Jul 22 01   Merge 0.91-0.96 onto 0.9.sv for ac series
+ * Ver 0.97.sv Aug 3 01  Backported from 2.4.7-ac3
  */
 
-#define IDEFLOPPY_VERSION "0.97"
+#define IDEFLOPPY_VERSION "0.97.sv"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -140,6 +162,8 @@ typedef struct idefloppy_packet_command_s {
 #define        PC_DMA_ERROR                    4       /* 1 when encountered problem during DMA */
 #define        PC_WRITING                      5       /* Data direction */
 
+#define        PC_SUPPRESS_ERROR               6       /* Suppress error reporting */
+
 /*
  *     Removable Block Access Capabilities Page
  */
@@ -1022,8 +1046,11 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p
                 *      a legitimate error code was received.
                 */
                if (!test_bit (PC_ABORT, &pc->flags)) {
-                       printk (KERN_ERR "ide-floppy: %s: I/O error, pc = %2x, key = %2x, asc = %2x, ascq = %2x\n",
+                       if (!test_bit (PC_SUPPRESS_ERROR, &pc->flags)) {
+                               ;
+      printk( KERN_ERR "ide-floppy: %s: I/O error, pc = %2x, key = %2x, asc = %2x, ascq = %2x\n",
                                drive->name, pc->c[0], floppy->sense_key, floppy->asc, floppy->ascq);
+                       }
                        pc->error = IDEFLOPPY_ERROR_GENERAL;            /* Giving up */
                }
                floppy->failed_pc=NULL;
@@ -1101,14 +1128,19 @@ static void idefloppy_create_read_capacity_cmd (idefloppy_pc_t *pc)
        pc->request_transfer = 255;
 }
 
-static void idefloppy_create_format_unit_cmd (idefloppy_pc_t *pc, int b, int l)
+static void idefloppy_create_format_unit_cmd (idefloppy_pc_t *pc, int b, int l,
+                                             int flags)
 {
        idefloppy_init_pc (pc);
        pc->c[0] = IDEFLOPPY_FORMAT_UNIT_CMD;
        pc->c[1] = 0x17;
 
        memset(pc->buffer, 0, 12);
-       pc->buffer[1] = 0xA2;   /* Format list header, byte 1: FOV/DCRT/IMM */
+       pc->buffer[1] = 0xA2;
+       /* Default format list header, byte 1: FOV/DCRT/IMM bits set */
+
+       if (flags & 1)                          /* Verify bit on... */
+               pc->buffer[1] ^= 0x20;          /* ... turn off DCRT bit */
        pc->buffer[3] = 8;
 
        put_unaligned(htonl(b), (unsigned int *)(&pc->buffer[4]));
@@ -1300,9 +1332,12 @@ static int idefloppy_get_capability_page(ide_drive_t *drive)
        floppy->srfp=0;
        idefloppy_create_mode_sense_cmd (&pc, IDEFLOPPY_CAPABILITIES_PAGE,
                                                 MODE_SENSE_CURRENT);
+
+       set_bit(PC_SUPPRESS_ERROR, &pc.flags);
        if (idefloppy_queue_pc_tail (drive,&pc)) {
                return 1;
        }
+
        header = (idefloppy_mode_parameter_header_t *) pc.buffer;
        page= (idefloppy_capabilities_page_t *)(header+1);
        floppy->srfp=page->srfp;
@@ -1378,7 +1413,6 @@ static int idefloppy_get_capacity (ide_drive_t *drive)
         if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags))
        {
                (void) idefloppy_get_flexible_disk_page (drive);
-               (void) idefloppy_get_capability_page (drive);
        }
 
        drive->part[0].nr_sects = floppy->blocks * floppy->bs_factor;
@@ -1478,7 +1512,12 @@ static int idefloppy_get_format_capacities (ide_drive_t *drive,
 ** struct idefloppy_format_command {
 **        int nblocks;
 **        int blocksize;
+**        int flags;
 **        } ;
+**
+** flags is a bitmask, currently, the only defined flag is:
+**
+**        0x01 - verify media after format.
 */
 
 static int idefloppy_begin_format(ide_drive_t *drive,
@@ -1488,15 +1527,18 @@ static int idefloppy_begin_format(ide_drive_t *drive,
 {
        int blocks;
        int length;
+       int flags;
        idefloppy_pc_t pc;
 
        if (get_user(blocks, arg)
-           || get_user(length, arg+1))
+           || get_user(length, arg+1)
+           || get_user(flags, arg+2))
        {
                return (-EFAULT);
        }
 
-       idefloppy_create_format_unit_cmd(&pc, blocks, length);
+       (void) idefloppy_get_capability_page (drive);   /* Get the SFRP bit */
+       idefloppy_create_format_unit_cmd(&pc, blocks, length, flags);
        if (idefloppy_queue_pc_tail (drive, &pc))
        {
                 return (-EIO);
@@ -1510,8 +1552,8 @@ static int idefloppy_begin_format(ide_drive_t *drive,
 ** Userland gives a pointer to an int.  The int is set to a progresss
 ** indicator 0-65536, with 65536=100%.
 **
-** If the drive does not support format progress indication, we just return
-** a 65536, screw it.
+** If the drive does not support format progress indication, we just check
+** the dsc bit, and return either 0 or 65536.
 */
 
 static int idefloppy_get_format_progress(ide_drive_t *drive,
@@ -1536,8 +1578,21 @@ static int idefloppy_get_format_progress(ide_drive_t *drive,
                {
                        progress_indication=floppy->progress_indication;
                }
+               /* Else assume format_unit has finished, and we're
+               ** at 0x10000 */
        }
+       else
+       {
+               idefloppy_status_reg_t status;
+               unsigned long flags;
 
+               __save_flags(flags);
+               __cli();
+               status.all=GET_STAT();
+               __restore_flags(flags);
+
+               progress_indication= !status.b.dsc ? 0:0x10000;
+       }
        if (put_user(progress_indication, arg))
                return (-EFAULT);
 
@@ -1587,8 +1642,6 @@ static int idefloppy_ioctl (ide_drive_t *drive, struct inode *inode, struct file
                {
                        idefloppy_floppy_t *floppy = drive->driver_data;
 
-                       set_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
-
                        if (drive->usage > 1)
                        {
                                /* Don't format if someone is using the disk */
@@ -1599,7 +1652,12 @@ static int idefloppy_ioctl (ide_drive_t *drive, struct inode *inode, struct file
                        }
                        else
                        {
-                               int rc=idefloppy_begin_format(drive, inode,
+                               int rc;
+
+                               set_bit(IDEFLOPPY_FORMAT_IN_PROGRESS,
+                                       &floppy->flags);
+
+                               rc=idefloppy_begin_format(drive, inode,
                                                              file,
                                                              (int *)arg);
 
@@ -1637,7 +1695,6 @@ static int idefloppy_open (struct inode *inode, struct file *filp, ide_drive_t *
 
        MOD_INC_USE_COUNT;
        if (drive->usage == 1) {
-
                clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
                /* Just in case */
 
@@ -1647,7 +1704,14 @@ static int idefloppy_open (struct inode *inode, struct file *filp, ide_drive_t *
                        (void) idefloppy_queue_pc_tail (drive, &pc);
                }
 
-               if (idefloppy_get_capacity (drive)) {
+               if (idefloppy_get_capacity (drive)
+                  && (filp->f_flags & O_NDELAY) == 0
+                   /*
+                   ** Allow O_NDELAY to open a drive without a disk, or with
+                   ** an unreadable disk, so that we can get the format
+                   ** capacity of the drive or begin the format - Sam
+                   */
+                   ) {
                        drive->usage--;
                        MOD_DEC_USE_COUNT;
                        return -EIO;
@@ -1893,6 +1957,17 @@ static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy)
                for (i = 0; i < 1 << PARTN_BITS; i++)
                        max_sectors[major][minor + i] = 64;
        }
+  /*
+   *      Guess what?  The IOMEGA Clik! drive also needs the
+   *      above fix.  It makes nasty clicking noises without
+   *      it, so please don't remove this.
+   */
+  if (strcmp(drive->id->model, "IOMEGA Clik! 40 CZ ATAPI") == 0)
+  {
+    for (i = 0; i < 1 << PARTN_BITS; i++)
+      max_sectors[major][minor + i] = 64;
+    set_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags);
+  }
 
        /*
        *      Guess what?  The IOMEGA Clik! drive also needs the
index 950746722b1eb0df0bb0ba8cac875fa87ced1fe2..3d642f17b648695368f1c77cc46311bbb3086453 100644 (file)
@@ -404,7 +404,7 @@ static int proc_ide_read_imodel
                case ide_cmd640:        name = "cmd640";        break;
                case ide_dtc2278:       name = "dtc2278";       break;
                case ide_ali14xx:       name = "ali14xx";       break;
-               case ide_qd6580:        name = "qd6580";        break;
+               case ide_qd65xx:        name = "qd65xx";        break;
                case ide_umc8672:       name = "umc8672";       break;
                case ide_ht6560b:       name = "ht6560b";       break;
                case ide_pdc4030:       name = "pdc4030";       break;
index 4a1b3fce70a29b6e9dc508621cf4ce7448de920c..9cb992d6c3747853866d91cbf3ec31e177f4a49b 100644 (file)
@@ -2989,7 +2989,7 @@ static int __init match_parm (char *s, const char *keywords[], int vals[], int m
  * "ide0=ht6560b"      : probe/support HT6560B interface
  * "ide0=cmd640_vlb"   : *REQUIRED* for VLB cards with the CMD640 chip
  *                       (not for PCI -- automatically detected)
- * "ide0=qd6580"       : probe/support qd6580 interface
+ * "ide0=qd65xx"       : probe/support qd65xx interface
  * "ide0=ali14xx"      : probe/support ali14xx chipsets (ALI M1439, M1443, M1445)
  * "ide0=umc8672"      : probe/support umc8672 chipsets
  * "idex=dc4030"       : probe/support Promise DC4030VL interface
@@ -3157,7 +3157,7 @@ int __init ide_setup (char *s)
                const char *ide_words[] = {
                        "noprobe", "serialize", "autotune", "noautotune", "reset", "dma", "ata66",
                        "minus8", "minus9", "minus10",
-                       "four", "qd6580", "ht6560b", "cmd640_vlb", "dtc2278", "umc8672", "ali14xx", "dc4030", NULL };
+                       "four", "qd65xx", "ht6560b", "cmd640_vlb", "dtc2278", "umc8672", "ali14xx", "dc4030", NULL };
                hw = s[3] - '0';
                hwif = &ide_hwifs[hw];
                i = match_parm(&s[4], ide_words, vals, 3);
@@ -3224,14 +3224,14 @@ int __init ide_setup (char *s)
                                goto done;
                        }
 #endif /* CONFIG_BLK_DEV_HT6560B */
-#if CONFIG_BLK_DEV_QD6580
-                       case -12: /* "qd6580" */
+#if CONFIG_BLK_DEV_QD65XX
+                       case -12: /* "qd65xx" */
                        {
-                               extern void init_qd6580 (void);
-                               init_qd6580();
+                               extern void init_qd65xx (void);
+                               init_qd65xx();
                                goto done;
                        }
-#endif /* CONFIG_BLK_DEV_QD6580 */
+#endif /* CONFIG_BLK_DEV_QD65XX */
 #ifdef CONFIG_BLK_DEV_4DRIVES
                        case -11: /* "four" drives on one set of ports */
                        {
index 937d3e6d10839a23506ccf645ea0b01b5ec0a358..e40952e085a96faf2c5b30a6de9742cfd98ef1e2 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Copyright 2000 MontaVista Software Inc.
  * Author: MontaVista Software, Inc.
- *              stevel@mvista.com or support@mvista.com
+ *              stevel@mvista.com or source@mvista.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
@@ -57,50 +57,41 @@ unsigned int __init pci_init_it8172 (struct pci_dev *dev, const char *name);
 void __init ide_init_it8172 (ide_hwif_t *hwif);
 
 
-/*
- *  Based on settings done by AMI BIOS
- *  (might be usefull if drive is not registered in CMOS for any reason).
- */
 static void it8172_tune_drive (ide_drive_t *drive, byte pio)
 {
     unsigned long flags;
     u16 master_data;
-    byte slave_data;
+    u32 slave_data;
     int is_slave       = (&HWIF(drive)->drives[1] == drive);
-    int master_port    = HWIF(drive)->index ? 0x42 : 0x40;
-    int slave_port     = 0x44;
-    /* ISP  RTC */
-    byte timings[][2]  = { { 0, 0 },
-                           { 0, 0 },
-                           { 1, 0 },
-                           { 2, 1 },
-                           { 2, 3 }, };
-
+    int master_port    = 0x40;
+    int slave_port      = 0x44;
+    
     pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
     pci_read_config_word(HWIF(drive)->pci_dev, master_port, &master_data);
+    pci_read_config_dword(HWIF(drive)->pci_dev, slave_port, &slave_data);
+
+    /*
+     * FIX! The DIOR/DIOW pulse width and recovery times in port 0x44
+     * are being left at the default values of 8 PCI clocks (242 nsec
+     * for a 33 MHz clock). These can be safely shortened at higher
+     * PIO modes.
+     */
+    
     if (is_slave) {
-       master_data = master_data | 0x4000;
+       master_data |= 0x4000;
        if (pio > 1)
-           /* enable PPE, IE and TIME */
-           master_data = master_data | 0x0070;
-       pci_read_config_byte(HWIF(drive)->pci_dev, slave_port, &slave_data);
-       slave_data = slave_data & (HWIF(drive)->index ? 0x0f : 0xf0);
-       slave_data = slave_data |
-           ((timings[pio][0] << 2) | (timings[pio][1]
-                                      << (HWIF(drive)->index ? 4 : 0)));
+           /* enable PPE and IE */
+           master_data |= 0x0060;
     } else {
-       master_data = master_data & 0xccf8;
+       master_data &= 0xc060;
        if (pio > 1)
-           /* enable PPE, IE and TIME */
-           master_data = master_data | 0x0007;
-       master_data = master_data | (timings[pio][0] << 12) |
-           (timings[pio][1] << 8);
+           /* enable PPE and IE */
+           master_data |= 0x0006;
     }
+
     save_flags(flags);
     cli();
     pci_write_config_word(HWIF(drive)->pci_dev, master_port, master_data);
-    if (is_slave)
-       pci_write_config_byte(HWIF(drive)->pci_dev, slave_port, slave_data);
     restore_flags(flags);
 }
 
@@ -150,12 +141,22 @@ static int it8172_tune_chipset (ide_drive_t *drive, byte speed)
     pci_read_config_byte(dev, 0x48, &reg48);
     pci_read_config_byte(dev, 0x4a, &reg4a);
 
+    /*
+     * Setting the DMA cycle time to 2 or 3 PCI clocks (60 and 91 nsec
+     * at 33 MHz PCI clock) seems to cause BadCRC errors during DMA
+     * transfers on some drives, even though both numbers meet the minimum
+     * ATAPI-4 spec of 73 and 54 nsec for UDMA 1 and 2 respectively.
+     * So the faster times are just commented out here. The good news is
+     * that the slower cycle time has very little affect on transfer
+     * performance.
+     */
+    
     switch(speed) {
     case XFER_UDMA_4:
-    case XFER_UDMA_2:  u_speed = 2 << (drive->dn * 4); break;
+    case XFER_UDMA_2:  //u_speed = 2 << (drive->dn * 4); break;
     case XFER_UDMA_5:
     case XFER_UDMA_3:
-    case XFER_UDMA_1:  u_speed = 1 << (drive->dn * 4); break;
+    case XFER_UDMA_1:  //u_speed = 1 << (drive->dn * 4); break;
     case XFER_UDMA_0:  u_speed = 0 << (drive->dn * 4); break;
     case XFER_MW_DMA_2:
     case XFER_MW_DMA_1:
@@ -164,25 +165,16 @@ static int it8172_tune_chipset (ide_drive_t *drive, byte speed)
     }
 
     if (speed >= XFER_UDMA_0) {
-       if (!(reg48 & u_flag))
-           pci_write_config_byte(dev, 0x48, reg48|u_flag);
-       if (!(reg4a & u_speed)) {
-           pci_write_config_byte(dev, 0x4a, reg4a & ~a_speed);
-           pci_write_config_byte(dev, 0x4a, reg4a|u_speed);
-       }
-    }
-    if (speed < XFER_UDMA_0) {
-       if (reg48 & u_flag)
-           pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
-       if (reg4a & a_speed)
-           pci_write_config_byte(dev, 0x4a, reg4a & ~a_speed);
+       pci_write_config_byte(dev, 0x48, reg48 | u_flag);
+       reg4a &= ~a_speed;
+       pci_write_config_byte(dev, 0x4a, reg4a | u_speed);
+    } else {
+       pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
+       pci_write_config_byte(dev, 0x4a, reg4a & ~a_speed);
     }
 
     it8172_tune_drive(drive, it8172_dma_2_pio(speed));
 
-#if IT8172_DEBUG
-    printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive->dn);
-#endif
     if (!drive->init_speed)
        drive->init_speed = speed;
     err = ide_config_drive_speed(drive, speed);
@@ -236,8 +228,10 @@ static int it8172_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
     /* Other cases are done by generic IDE-DMA code. */
     return ide_dmaproc(func, drive);
 }
+
 #endif /* defined(CONFIG_BLK_DEV_IDEDMA) && (CONFIG_IT8172_TUNING) */
 
+
 unsigned int __init pci_init_it8172 (struct pci_dev *dev, const char *name)
 {
     unsigned char progif;
index f8cba2df9612858b0fa3d02803e21d1d40c66fd2..31e30032901cbfc76bdba5f4b5284e6f0f92746b 100644 (file)
@@ -133,6 +133,7 @@ static char * pdc202xx_info (char *buf, struct pci_dev *dev)
 
        switch(dev->device) {
                case PCI_DEVICE_ID_PROMISE_20268:
+               case PCI_DEVICE_ID_PROMISE_20268R:
                        p += sprintf(p, "\n                                PDC20268 TX2 Chipset.\n");
                        invalid_data_set = 1;
                        break;
diff --git a/drivers/ide/qd6580.c b/drivers/ide/qd6580.c
deleted file mode 100644 (file)
index 5787b73..0000000
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- *  linux/drivers/ide/qd6580.c         Version 0.04    June 4, 2000
- *
- *  Copyright (C) 1996-2000  Linus Torvalds & author (see below)
- */
-
-/*
- *  Version 0.03       Cleaned auto-tune, added probe
- *  Version 0.04       Added second channel tuning
- *
- * QDI QD6580 EIDE controller fast support
- *
- * To activate controller support use kernel parameter "ide0=qd6580"
- * To enable tuning use kernel parameter "ide0=autotune"
- * To enable tuning second channel (not really tested),
- *    use parameter "ide1=autotune"
- */
-
-/* 
- * Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by
- * Samuel Thibault <samuel.thibault@fnac.net>
- */
-
-#undef REALLY_SLOW_IO           /* most systems can safely undef this */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/blkdev.h>
-#include <linux/hdreg.h>
-#include <linux/ide.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-
-#include "ide_modes.h"
-
-/*
- * I/O ports are 0xb0-0xb3
- *            or 0x30-0x33
- *     -- this is a dual IDE interface with I/O chips
- *
- * More research on qd6580 being done by willmore@cig.mot.com (David)
- * More Information given by Petr Sourcek (petr@ryston.cz)
- * http://www.ryston.cz/petr/vlb
- */
-
-/*
- * 0xb0: Timer1
- *
- *
- * 0xb1: Config
- *
- * bit 0: ide baseport: 1 = 0x1f0 ; 0 = 0x170
- *   (? Strange: the Dos driver uses it, and then forces baseport to 0x1f0 ?)
- * bit 1: qd baseport: 1 = 0xb0 ; 0 = 0x30
- * bit 2: ID3: bus speed: 1 = <=33MHz ; 0 = >33MHz
- * bit 3: 1 for qd6580
- * upper nibble is either 1010 or 0101, or else it isn't a qd6580
- *
- *
- * 0xb2: Timer2
- *
- *
- * 0xb3: Control
- *
- * bits 0-3 must always be set 1
- * bit 4 must be set 1, but is set 0 by dos driver while measuring vlb clock
- * bit 0 : 1 = Only primary port enabled : channel 0 for hda, channel 1 for hdb
- *         0 = Primary and Secondary ports enabled : channel 0 for hda & hdb
- *                                                   channel 1 for hdc & hdd
- * bit 1 : 1 = only disks on primary port
- *         0 = disks & ATAPI devices on primary port
- * bit 2-4 : always 0
- * bit 5 : status, but of what ?
- * bit 6 : always set 1 by dos driver
- * bit 7 : set 1 for non-ATAPI devices (read-ahead and post-write buffer ?)
- */
-
-/* truncates a in [b,c] */
-#define IDE_IN(a,b,c)   ( ((a)<(b)) ? (b) : ( (a)>(c) ? (c) : (a)) )
-
-typedef struct ide_hd_timings_s {
-       int active_time;                /* Active pulse (ns) minimum */
-       int recovery_time;              /* Recovery pulse (ns) minimum */
-} ide_hd_timings_t;
-
-static int basePort;           /* base port address (0x30 or 0xb0) */
-static byte config;                    /* config register of qd6580 */
-static byte control;           /* control register of qd6580 */
-
-static int bus_clock;          /* Vesa local bus clock (ns) */
-static int tuned=0;                    /* to remember whether we've already been tuned */
-static int snd_tuned=0;                /* to remember whether we've already been tuned */
-static int nb_disks_prim=0;    /* number of disk drives on primary port */
-
-/*
- * write_reg
- *
- * writes the specified byte on the specified register
- */
-
-static void write_reg ( byte content, byte reg )
-{
-       unsigned long flags;
-
-       save_flags(flags);              /* all CPUs */
-       cli();                                  /* all CPUs */
-       outb_p(content,reg);
-       inb(0x3f6);
-       restore_flags(flags);   /* all CPUs */
-}
-
-/*
- * tune_drive
- *
- * Finds timings for the specified drive, returns it in struct t
- */
-
-static void tune_drive ( ide_drive_t *drive, byte pio, ide_hd_timings_t *t )
-{
-       ide_pio_data_t d;
-
-       t->active_time   = 175;
-       t->recovery_time = 415; /* worst cases values from the dos driver */
-
-       if (!drive->present) {  /* not present : free to give any timing */
-               t->active_time = 0;
-               t->recovery_time = 0;
-               return;
-       }
-
-       pio = ide_get_best_pio_mode(drive, pio, 255, &d);
-       pio = IDE_MIN(pio,4);
-
-       switch (pio) {
-               case 0: break;
-               case 3:
-                       if (d.cycle_time >= 110) {
-                               t->active_time = 86;
-                               t->recovery_time = d.cycle_time-102;
-                       } else {
-                               printk("%s: Strange recovery time !\n",drive->name);
-                               return;
-                       }
-                       break;
-               case 4:
-                       if (d.cycle_time >= 69) {
-                               t->active_time = 70;
-                               t->recovery_time = d.cycle_time-61;
-                       } else {
-                               printk("%s: Strange recovery time !\n",drive->name);
-                               return;
-                       }
-                       break;
-               default:
-                       if (d.cycle_time >= 180) {
-                               t->active_time = 110;
-                               t->recovery_time = d.cycle_time - 120;
-                       } else {
-                               t->active_time = ide_pio_timings[pio].active_time;
-                               t->recovery_time = d.cycle_time
-                                               -t->active_time;
-                       }
-       }
-       printk("%s: PIO mode%d, tim1=%dns tim2=%dns\n", drive->name, pio, t->active_time, t->recovery_time);
-
-       if (drive->media == ide_disk)
-               nb_disks_prim++;
-       else {
-/* need to disable read-ahead FIFO and post-write buffer for ATAPI drives*/
-               write_reg(0x5f,basePort+0x03);
-               printk("%s: Warning: please try to connect this drive to secondary IDE port\nto improve data transfer rate on primary IDE port.\n",drive->name);
-       }
-}
-
-/*
- * tune_snd_drive
- *
- * Finds timings for the specified drive, using second channel rules
- */
-
-static void tune_snd_drive ( ide_drive_t *drive, byte pio, ide_hd_timings_t *t )
-{
-       ide_pio_data_t d;
-
-       t->active_time   = 175;
-       t->recovery_time = 415;
-
-       if (!drive->present) {  /* not present : free to give any timing */
-               t->active_time = 0;
-               t->recovery_time = 0;
-               return;
-       }
-
-       pio = ide_get_best_pio_mode(drive, pio, 255, &d);
-
-       if ((pio) && (d.cycle_time >= 180)) {
-               t->active_time = 115;
-               t->recovery_time = d.cycle_time - 115;
-       }
-       printk("%s: PIO mode%d, tim1=%dns tim2=%dns\n", drive->name, pio, t->active_time, t->recovery_time);
-
-       if ((drive->media == ide_disk) && (nb_disks_prim<2)) {
-/* a disk drive on secondary port while there's room on primary, which is the
- * only one that has read-ahead fifo and post-write buffer ? What a waste !*/
-               printk("%s: Warning: please try to connect this drive to primary IDE port\nto improve data transfer rate.\n",drive->name);
-       }
-}
-
-/*
- * compute_timing
- *
- * computes the timing value where
- *    lower nibble is active time,   in count of VLB clocks, 17-(from 2 to 17)
- *    upper nibble is recovery time, in count of VLB clocks, 15-(from 2 to 15)
- */
-
-static byte compute_timing ( char name[6], ide_hd_timings_t *t )
-{
-       byte active_cycle;
-       byte recovery_cycle;
-       byte parameter;
-
-       active_cycle   = 17-IDE_IN(t->active_time   / bus_clock + 1, 2, 17);
-       recovery_cycle = 15-IDE_IN(t->recovery_time / bus_clock + 1, 2, 15);
-
-       parameter = active_cycle | (recovery_cycle<<4);
-
-       printk("%s: tim1=%dns tim2=%dns => %#x\n", name, t[0].active_time, t[0].recovery_time, parameter);
-       return(parameter);
-}
-
-/*
- * tune_ide
- *
- * Tunes the whole hwif, ie tunes each drives, and in case we have to share,
- * takes the worse timings to tune qd6580
- */
-
-static void tune_ide ( ide_hwif_t *hwif, byte pio )
-{
-       unsigned long flags;
-       ide_hd_timings_t t[2]={{0,0},{0,0}};
-       int bus_speed = ide_system_bus_speed ();
-
-       bus_clock = 1000 / bus_speed;
-
-       save_flags(flags);              /* all CPUs */
-       cli();                                  /* all CPUs */
-       outb( (bus_clock<30) ? 0x0 : 0x0a, basePort + 0x02);
-       outb( 0x40 | ((control & 0x02) ? 0x9f:0x1f), basePort+0x03);
-       restore_flags(flags);
-
-       tune_drive (&hwif->drives[0], pio, &t[0]);
-       tune_drive (&hwif->drives[1], pio, &t[1]);
-
-       if (control & 0x01) { /* only primary port enabled, can tune separately */
-               write_reg(compute_timing (hwif->drives[0].name, &t[0]),basePort);
-               write_reg(compute_timing (hwif->drives[1].name, &t[1]),basePort+0x02);
-       } else {                          /* both ports enabled, we have to share */
-
-               t[0].active_time   = IDE_MAX(t[0].active_time,  t[1].active_time);
-               t[0].recovery_time = IDE_MAX(t[0].recovery_time,t[1].recovery_time);
-               write_reg(compute_timing (hwif->name, &t[0]),basePort);
-       }
-}
-
-/*
- * tune_snd_ide
- *
- * Tunes the whole secondary hwif, ie tunes each drives, and takes the worse
- * timings to tune qd6580
- */
-
-static void tune_snd_ide ( ide_hwif_t *hwif, byte pio )
-{
-       ide_hd_timings_t t[2]={{0,0},{0,0}};
-
-       tune_snd_drive (&hwif->drives[0], pio, &t[0]);
-       tune_snd_drive (&hwif->drives[1], pio, &t[1]);
-
-       t[0].active_time   = IDE_MAX(t[0].active_time,  t[1].active_time);
-       t[0].recovery_time = IDE_MAX(t[0].recovery_time,t[1].recovery_time);
-
-       write_reg(compute_timing (hwif->name, &t[0]),basePort+0x02);
-}
-
-/*
- * tune_qd6580
- *
- * tunes the hwif if not tuned
- */
-
-static void tune_qd6580 (ide_drive_t *drive, byte pio)
-{
-       if (! tuned) {
-               tune_ide(HWIF(drive), pio);
-               tuned = 1;
-       }
-}
-
-/*
- * tune_snd_qd6580
- *
- * tunes the second hwif if not tuned
- */
-
-static void tune_snd_qd6580 (ide_drive_t *drive, byte pio)
-{
-       if (! snd_tuned) {
-               tune_snd_ide(HWIF(drive), pio);
-               snd_tuned = 1;
-       }
-}
-
-/*
- * testreg
- *
- * tests if the given port is a register
- */
-
-static int __init testreg(int port)
-{
-       byte savereg;
-       byte readreg;
-       unsigned long flags;
-
-       save_flags(flags);              /* all CPUs */
-       cli();                                  /* all CPUs */
-       savereg = inb(port);
-       outb_p(0x15,port);              /* safe value */
-       readreg = inb_p(port);
-       outb(savereg,port);
-       restore_flags(flags);   /* all CPUs */
-
-       if (savereg == 0x15) {
-               printk("Outch ! the probe for qd6580 isn't reliable !\n");
-               printk("Please contact maintainers to tell about your hardware\n");
-               printk("Assuming qd6580 is not present.\n");
-               return 0;
-       }
-
-       return (readreg == 0x15);
-}
-
-/*
- * trybase:
- *
- * tries to find a qd6580 at the given base and save it if found
- */
-
-static int __init trybase (int base)
-{
-       unsigned long flags;
-
-       save_flags(flags);              /* all CPUs */
-       cli();                                  /* all CPUs */
-       config = inb(base+0x01);
-       control = inb(base+0x03);
-       restore_flags(flags);   /* all CPUs */
-
-       if (((config & 0xf0) != 0x50) && ((config & 0xf0) != 0xa0)) return(0);
-       if (! ( ((config & 0x02) == 0x0) == (base == 0x30) ) ) return (0);
-
-       /* Seems to be OK, let's use it */
-
-       basePort = base;
-       return(testreg(base));
-}
-
-/*
- * probe:
- *
- * probes qd6580 at 0xb0 (the default) or 0x30
- */
-
-static int __init probe (void)
-{
-       return (trybase(0xb0) ? 1 : trybase(0x30));
-}
-
-/*
- * init_qd6580:
- *
- * called at the very beginning of initialization ; should just probe and link
- */
-
-void __init init_qd6580 (void)
-{
-       if (! probe()) {
-               printk("qd6580: not found\n");
-               return;
-       }
-
-       printk("qd6580: base=%#x, config=%#x, control=%#x\n", basePort, config, control);
-
-       ide_hwifs[0].chipset = ide_qd6580;
-       ide_hwifs[0].tuneproc = &tune_qd6580;
-       if (!(control & 0x01)) {
-               ide_hwifs[1].chipset = ide_qd6580;
-               ide_hwifs[1].tuneproc = &tune_snd_qd6580;
-               ide_hwifs[0].mate = &ide_hwifs[1];
-               ide_hwifs[1].mate = &ide_hwifs[0];
-               ide_hwifs[1].channel = 1;
-       }
-}
diff --git a/drivers/ide/qd65xx.c b/drivers/ide/qd65xx.c
new file mode 100644 (file)
index 0000000..b0ab4eb
--- /dev/null
@@ -0,0 +1,453 @@
+/*
+ *  linux/drivers/ide/qd65xx.c         Version 0.06    Aug 3, 2000
+ *
+ *  Copyright (C) 1996-2000  Linus Torvalds & author (see below)
+ */
+
+/*
+ *  Version 0.03       Cleaned auto-tune, added probe
+ *  Version 0.04       Added second channel tuning
+ *  Version 0.05       Enhanced tuning ; added qd6500 support
+ *  Version 0.06       added dos driver's list
+ *
+ * QDI QD6500/QD6580 EIDE controller fast support
+ *
+ * Please set local bus speed using kernel parameter idebus
+ *     for example, "idebus=33" stands for 33Mhz VLbus
+ * To activate controller support, use "ide0=qd65xx"
+ * To enable tuning, use "ide0=autotune"
+ * To enable second channel tuning (qd6580 only), use "ide1=autotune"
+ */
+
+/*
+ * Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by
+ * Samuel Thibault <samuel.thibault@fnac.net>
+ */
+
+#undef REALLY_SLOW_IO          /* most systems can safely undef this */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/ioport.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <linux/ide.h>
+#include <linux/init.h>
+#include <asm/io.h>
+
+#include "ide_modes.h"
+#include "qd65xx.h"
+
+/*
+ * I/O ports are 0x30-0x31 (and 0x32-0x33 for qd6580)
+ *            or 0xb0-0xb1 (and 0xb2-0xb3 for qd6580)
+ *     -- qd6500 is a single IDE interface
+ *     -- qd6580 is a dual IDE interface
+ *
+ * More research on qd6580 being done by willmore@cig.mot.com (David)
+ * More Information given by Petr Soucek (petr@ryston.cz)
+ * http://www.ryston.cz/petr/vlb
+ */
+
+/*
+ * base: Timer1
+ *
+ *
+ * base+0x01: Config (R/O)
+ *
+ * bit 0: ide baseport: 1 = 0x1f0 ; 0 = 0x170 (only useful for qd6500)
+ * bit 1: qd65xx baseport: 1 = 0xb0 ; 0 = 0x30
+ * bit 2: ID3: bus speed: 1 = <=33MHz ; 0 = >33MHz
+ * bit 3: qd6500: 1 = disabled, 0 = enabled
+ *        qd6580: 1
+ * upper nibble:
+ *        qd6500: 1100
+ *        qd6580: either 1010 or 0101
+ *
+ * base+0x02: Timer2 (qd6580 only)
+ *
+ *
+ * base+0x03: Control (qd6580 only)
+ *
+ * bits 0-3 must always be set 1
+ * bit 4 must be set 1, but is set 0 by dos driver while measuring vlb clock
+ * bit 0 : 1 = Only primary port enabled : channel 0 for hda, channel 1 for hdb
+ *         0 = Primary and Secondary ports enabled : channel 0 for hda & hdb
+ *                                                   channel 1 for hdc & hdd
+ * bit 1 : 1 = only disks on primary port
+ *         0 = disks & ATAPI devices on primary port
+ * bit 2-4 : always 0
+ * bit 5 : status, but of what ?
+ * bit 6 : always set 1 by dos driver
+ * bit 7 : set 1 for non-ATAPI devices on primary port
+ *     (maybe read-ahead and post-write buffer ?)
+ */
+
+static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */
+
+static void qd_write_reg (byte content, byte reg)
+{
+       unsigned long flags;
+
+       save_flags(flags);      /* all CPUs */
+       cli();                  /* all CPUs */
+       outb(content,reg);
+       restore_flags(flags);   /* all CPUs */
+}
+
+byte __init qd_read_reg (byte reg)
+{
+       unsigned long flags;
+       byte read;
+
+       save_flags(flags);      /* all CPUs */
+       cli();                  /* all CPUs */
+       read = inb(reg);
+       restore_flags(flags);   /* all CPUs */
+       return read;
+}
+
+/*
+ * qd_select:
+ *
+ * This routine is invoked from ide.c to prepare for access to a given drive.
+ */
+
+static void qd_select (ide_drive_t *drive)
+{
+       byte index = (( (QD_TIMREG(drive)) & 0x80 ) >> 7) |
+                       (QD_TIMREG(drive) & 0x02);
+
+       if (timings[index] != QD_TIMING(drive))
+               qd_write_reg(timings[index] = QD_TIMING(drive), QD_TIMREG(drive));
+}
+
+/*
+ * qd6500_compute_timing
+ *
+ * computes the timing value where
+ *     lower nibble represents active time,   in count of VLB clocks
+ *     upper nibble represents recovery time, in count of VLB clocks
+ */
+
+static byte qd6500_compute_timing (ide_hwif_t *hwif, int active_time, int recovery_time)
+{
+       byte active_cycle,recovery_cycle;
+
+       if (system_bus_clock()<=33) {
+               active_cycle =   9  - IDE_IN(active_time   * system_bus_clock() / 1000 + 1, 2, 9);
+               recovery_cycle = 15 - IDE_IN(recovery_time * system_bus_clock() / 1000 + 1, 0, 15);
+       } else {
+               active_cycle =   8  - IDE_IN(active_time   * system_bus_clock() / 1000 + 1, 1, 8);
+               recovery_cycle = 18 - IDE_IN(recovery_time * system_bus_clock() / 1000 + 1, 3, 18);
+       }
+
+       return((recovery_cycle<<4) | 0x08 | active_cycle);
+}
+
+/*
+ * qd6580_compute_timing
+ *
+ * idem for qd6580
+ */
+
+static byte qd6580_compute_timing (int active_time, int recovery_time)
+{
+       byte active_cycle   = 17-IDE_IN(active_time   * system_bus_clock() / 1000 + 1, 2, 17);
+       byte recovery_cycle = 15-IDE_IN(recovery_time * system_bus_clock() / 1000 + 1, 2, 15);
+
+       return((recovery_cycle<<4) | active_cycle);
+}
+
+/*
+ * qd_find_disk_type
+ *
+ * tries to find timing from dos driver's table
+ */
+
+static int qd_find_disk_type (ide_drive_t *drive,
+               int *active_time, int *recovery_time)
+{
+       struct qd65xx_timing_s *p;
+       char model[40];
+
+       if (!*drive->id->model) return 0;
+
+       strncpy(model,drive->id->model,40);
+       ide_fixstring(model,40,1); /* byte-swap */
+
+       for (p = qd65xx_timing ; p->offset != -1 ; p++) {
+               if (!strncmp(p->model, model+p->offset,4)) {
+                       printk(KERN_DEBUG "%s: listed !\n",drive->name);
+                       *active_time = p->active;
+                       *recovery_time = p->recovery;
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+/*
+ * qd_timing_ok:
+ *
+ * check whether timings don't conflict
+ */
+
+static int qd_timing_ok (ide_drive_t drives[])
+{
+       return (IDE_IMPLY(drives[0].present && drives[1].present,
+                       IDE_IMPLY(QD_TIMREG(drives) == QD_TIMREG(drives+1),
+                                 QD_TIMING(drives) == QD_TIMING(drives+1))));
+       /* if same timing register, must be same timing */
+}
+
+/*
+ * qd_set_timing:
+ *
+ * records the timing, and enables selectproc as needed
+ */
+
+static void qd_set_timing (ide_drive_t *drive, byte timing)
+{
+       ide_hwif_t *hwif = HWIF(drive);
+
+       drive->drive_data &= 0xff00;
+       drive->drive_data |= timing;
+       if (qd_timing_ok(hwif->drives)) {
+               qd_select(drive); /* selects once */
+               hwif->selectproc = NULL;
+       } else
+               hwif->selectproc = &qd_select;
+
+       printk(KERN_DEBUG "%s: %#x\n",drive->name,timing);
+}
+
+/*
+ * qd6500_tune_drive
+ */
+
+static void qd6500_tune_drive (ide_drive_t *drive, byte pio)
+{
+       int active_time   = 175;
+       int recovery_time = 415; /* worst case values from the dos driver */
+
+       if (drive->id && !qd_find_disk_type(drive,&active_time,&recovery_time)
+               && drive->id->tPIO && (drive->id->field_valid & 0x02)
+               && drive->id->eide_pio >= 240) {
+
+               printk(KERN_INFO "%s: PIO mode%d\n", drive->name,
+                               drive->id->tPIO);
+               active_time = 110;
+               recovery_time = drive->id->eide_pio - 120;
+       }
+
+       qd_set_timing(drive,qd6500_compute_timing(HWIF(drive),active_time,recovery_time));
+}
+
+/*
+ * qd6580_tune_drive
+ */
+
+static void qd6580_tune_drive (ide_drive_t *drive, byte pio)
+{
+       ide_pio_data_t d;
+       int base = HWIF(drive)->select_data;
+       int active_time   = 175;
+       int recovery_time = 415; /* worst case values from the dos driver */
+
+       if (drive->id && !qd_find_disk_type(drive,&active_time,&recovery_time)) {
+               pio = ide_get_best_pio_mode(drive, pio, 255, &d);
+               pio = IDE_MIN(pio,4);
+
+               switch (pio) {
+                       case 0: break;
+                       case 3:
+                               if (d.cycle_time >= 110) {
+                                       active_time = 86;
+                                       recovery_time = d.cycle_time-102;
+                               } else
+                                       printk(KERN_WARNING "%s: Strange recovery time !\n",drive->name);
+                               break;
+                       case 4:
+                               if (d.cycle_time >= 69) {
+                                       active_time = 70;
+                                       recovery_time = d.cycle_time-61;
+                               } else
+                                       printk(KERN_WARNING "%s: Strange recovery time !\n",drive->name);
+                               break;
+                       default:
+                               if (d.cycle_time >= 180) {
+                                       active_time = 110;
+                                       recovery_time = d.cycle_time - 120;
+                               } else {
+                                       active_time = ide_pio_timings[pio].active_time;
+                                       recovery_time = d.cycle_time
+                                                       -active_time;
+                               }
+               }
+               printk(KERN_INFO "%s: PIO mode%d\n",drive->name,pio);
+       }
+
+       if (!HWIF(drive)->channel && drive->media != ide_disk) {
+               qd_write_reg(0x5f,QD_CONTROL_PORT);
+               printk(KERN_WARNING "%s: ATAPI: disabled read-ahead FIFO and post-write buffer on %s.\n",drive->name,HWIF(drive)->name);
+       }
+
+       qd_set_timing(drive,qd6580_compute_timing(active_time,recovery_time));
+}
+
+/*
+ * qd_testreg
+ *
+ * tests if the given port is a register
+ */
+
+static int __init qd_testreg(int port)
+{
+       byte savereg;
+       byte readreg;
+       unsigned long flags;
+
+       save_flags(flags);      /* all CPUs */
+       cli();                  /* all CPUs */
+       savereg = inb_p(port);
+       outb_p(QD_TESTVAL,port);        /* safe value */
+       readreg = inb_p(port);
+       outb(savereg,port);
+       restore_flags(flags);   /* all CPUs */
+
+       if (savereg == QD_TESTVAL) {
+               printk(KERN_ERR "Outch ! the probe for qd65xx isn't reliable !\n");
+               printk(KERN_ERR "Please contact maintainers to tell about your hardware\n");
+               printk(KERN_ERR "Assuming qd65xx is not present.\n");
+               return 1;
+       }
+
+       return (readreg != QD_TESTVAL);
+}
+
+/*
+ * probe:
+ *
+ * looks at the specified baseport, and if qd found, registers & initialises it
+ * return 1 if another qd may be probed
+ */
+
+int __init probe (int base)
+{
+       byte config;
+       byte index;
+
+       config = qd_read_reg(QD_CONFIG_PORT);
+
+       if (! ((config & QD_CONFIG_BASEPORT) >> 1 == (base == 0xb0)) ) return 1;
+
+       index = ! (config & QD_CONFIG_IDE_BASEPORT);
+
+       if ((config & 0xf0) == QD_CONFIG_QD6500) {
+               ide_hwif_t *hwif = &ide_hwifs[index];
+
+               if (qd_testreg(base)) return 1;         /* bad register */
+
+                       /* qd6500 found */
+
+               printk(KERN_NOTICE "%s: qd6500 at %#x\n",
+                       ide_hwifs[index].name, base);
+               
+               printk(KERN_DEBUG "qd6500: config=%#x, ID3=%u\n",
+                       config, QD_ID3);
+               
+               if (config & QD_CONFIG_DISABLED) {
+                       printk(KERN_WARNING "qd6500 is disabled !\n");
+                       return 1;
+               }
+
+               hwif->chipset = ide_qd65xx;
+               hwif->select_data = base;
+               hwif->config_data = config;
+               hwif->drives[0].drive_data =
+               hwif->drives[1].drive_data = QD6500_DEF_DATA;
+               hwif->drives[0].io_32bit =
+               hwif->drives[1].io_32bit = 1;
+               hwif->tuneproc = &qd6500_tune_drive;
+               return 1;
+       }
+
+       if (((config & 0xf0) == QD_CONFIG_QD6580_A) || ((config & 0xf0) == QD_CONFIG_QD6580_B)) {
+
+               byte control;
+
+               if (qd_testreg(base) || qd_testreg(base+0x02)) return 1;
+                       /* bad registers */
+
+                       /* qd6580 found */
+
+               control = qd_read_reg(QD_CONTROL_PORT);
+
+               printk(KERN_NOTICE "qd6580 at %#x\n", base);
+               printk(KERN_DEBUG "qd6580: config=%#x, control=%#x, ID3=%u\n",
+                       config, control, QD_ID3);
+
+               if (control & QD_CONTR_SEC_DISABLED) {
+                       ide_hwif_t *hwif = &ide_hwifs[index];
+
+                       /* secondary disabled */
+                       printk(KERN_INFO "%s: qd6580: single IDE board\n",
+                                       ide_hwifs[index].name);
+
+                       hwif->chipset = ide_qd65xx;
+                       hwif->select_data = base;
+                       hwif->config_data = config | (control <<8);
+                       hwif->drives[0].drive_data =
+                       hwif->drives[1].drive_data = QD6580_DEF_DATA;
+                       hwif->drives[0].io_32bit =
+                       hwif->drives[1].io_32bit = 1;
+                       hwif->tuneproc = &qd6580_tune_drive;
+
+                       qd_write_reg(QD_DEF_CONTR,QD_CONTROL_PORT);
+
+                       return 1;
+               } else {
+                       int i,j;
+                       /* secondary enabled */
+                       printk(KERN_INFO "%s&%s: qd6580: dual IDE board\n",
+                                       ide_hwifs[0].name,ide_hwifs[1].name);
+
+                       for (i=0;i<2;i++) {
+
+                               ide_hwifs[i].chipset = ide_qd65xx;
+                               ide_hwifs[i].mate = &ide_hwifs[i^1];
+                               ide_hwifs[i].channel = i;
+
+                               ide_hwifs[i].select_data = base;
+                               ide_hwifs[i].config_data = config | (control <<8);
+                               ide_hwifs[i].tuneproc = &qd6580_tune_drive;
+
+                               for (j=0;j<2;j++) {
+                                       ide_hwifs[i].drives[j].drive_data = QD6580_DEF_DATA;
+                                       ide_hwifs[i].drives[j].io_32bit = 1;
+                               }
+                       }
+
+                       qd_write_reg(QD_DEF_CONTR,QD_CONTROL_PORT);
+
+                       return 0; /* no other qd65xx possible */
+               }
+       }
+       /* no qd65xx found */
+       return 1;
+}
+
+/*
+ * init_qd65xx:
+ *
+ * called at the very beginning of initialization ; should just probe and link
+ */
+
+void __init init_qd65xx (void)
+{
+       if (probe(0x30)) probe(0xb0);
+}
diff --git a/drivers/ide/qd65xx.h b/drivers/ide/qd65xx.h
new file mode 100644 (file)
index 0000000..8a3d9b6
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * linux/drivers/ide/qd65xx.h
+ *
+ * Copyright (c) 2000  Linus Torvalds & authors
+ */
+
+/*
+ * Authors:    Petr Soucek <petr@ryston.cz>
+ *             Samuel Thibault <samuel.thibault@fnac.net>
+ */
+
+/* truncates a in [b,c] */
+#define IDE_IN(a,b,c)   ( ((a)<(b)) ? (b) : ( (a)>(c) ? (c) : (a)) )
+
+#define IDE_IMPLY(a,b) ((!(a)) || (b))
+
+#define QD_TIM1_PORT           (base)
+#define QD_CONFIG_PORT         (base+0x01)
+#define QD_TIM2_PORT           (base+0x02)
+#define QD_CONTROL_PORT                (base+0x03)
+
+#define QD_CONFIG_IDE_BASEPORT 0x01
+#define QD_CONFIG_BASEPORT     0x02
+#define QD_CONFIG_ID3          0x04
+#define QD_CONFIG_DISABLED     0x08
+#define QD_CONFIG_QD6500       0xc0
+#define QD_CONFIG_QD6580_A     0xa0
+#define QD_CONFIG_QD6580_B     0x50
+
+#define QD_CONTR_SEC_DISABLED  0x01
+
+#define QD_ID3                 (config & QD_CONFIG_ID3)
+
+#define QD_CONFIG(hwif)                ((hwif)->config_data & 0x00ff)
+#define QD_CONTROL(hwif)       (((hwif)->config_data & 0xff00) >> 8)
+
+#define QD_TIMING(drive)       (byte)(((drive)->drive_data) & 0x00ff)
+#define QD_TIMREG(drive)       (byte)((((drive)->drive_data) & 0xff00) >> 8)
+
+#define QD6500_DEF_DATA                ((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0c : 0x08))
+#define QD6580_DEF_DATA                ((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0a : 0x00))
+#define QD_DEF_CONTR           (0x40 | ((control & 0x02) ? 0x9f : 0x1f))
+
+#define QD_TESTVAL             0x19    /* safe value */
+
+/* Drive specific timing taken from DOS driver v3.7 */
+
+struct qd65xx_timing_s {
+       char    offset;   /* ofset from the beginning of Model Number" */
+       char    model[4];    /* 4 chars from Model number, no conversion */
+       short   active;   /* active time */
+       short   recovery; /* recovery time */
+} qd65xx_timing [] = {
+       { 30, "2040", 110, 225 },  /* Conner CP30204                    */
+       { 30, "2045", 135, 225 },  /* Conner CP30254                    */
+       { 30, "1040", 155, 325 },  /* Conner CP30104                    */
+       { 30, "1047", 135, 265 },  /* Conner CP30174                    */
+       { 30, "5344", 135, 225 },  /* Conner CP3544                     */
+       { 30, "01 4", 175, 405 },  /* Conner CP-3104                    */
+       { 27, "C030", 175, 375 },  /* Conner CP3000                     */
+       {  8, "PL42", 110, 295 },  /* Quantum LP240                     */
+       {  8, "PL21", 110, 315 },  /* Quantum LP120                     */
+       {  8, "PL25", 175, 385 },  /* Quantum LP52                      */
+       {  4, "PA24", 110, 285 },  /* WD Piranha SP4200                 */
+       {  6, "2200", 110, 260 },  /* WD Caviar AC2200                  */
+       {  6, "3204", 110, 235 },  /* WD Caviar AC2340                  */
+       {  6, "1202", 110, 265 },  /* WD Caviar AC2120                  */
+       {  0, "DS3-", 135, 315 },  /* Teac SD340                        */
+       {  8, "KM32", 175, 355 },  /* Toshiba MK234                     */
+       {  2, "53A1", 175, 355 },  /* Seagate ST351A                    */
+       {  2, "4108", 175, 295 },  /* Seagate ST1480A                   */
+       {  2, "1344", 175, 335 },  /* Seagate ST3144A                   */
+       {  6, "7 12", 110, 225 },  /* Maxtor 7213A                      */
+       { 30, "02F4", 145, 295 },  /* Conner 3204F                      */
+       {  2, "1302", 175, 335 },  /* Seagate ST3120A                   */
+       {  2, "2334", 145, 265 },  /* Seagate ST3243A                   */
+       {  2, "2338", 145, 275 },  /* Seagate ST3283A                   */
+       {  2, "3309", 145, 275 },  /* Seagate ST3390A                   */
+       {  2, "5305", 145, 275 },  /* Seagate ST3550A                   */
+       {  2, "4100", 175, 295 },  /* Seagate ST1400A                   */
+       {  2, "4110", 175, 295 },  /* Seagate ST1401A                   */
+       {  2, "6300", 135, 265 },  /* Seagate ST3600A                   */
+       {  2, "5300", 135, 265 },  /* Seagate ST3500A                   */
+       {  6, "7 31", 135, 225 },  /* Maxtor 7131 AT                    */
+       {  6, "7 43", 115, 265 },  /* Maxtor 7345 AT                    */
+       {  6, "7 42", 110, 255 },  /* Maxtor 7245 AT                    */
+       {  6, "3 04", 135, 265 },  /* Maxtor 340 AT                     */
+       {  6, "61 0", 135, 285 },  /* WD AC160                          */
+       {  6, "1107", 135, 235 },  /* WD AC1170                         */
+       {  6, "2101", 110, 220 },  /* WD AC1210                         */
+       {  6, "4202", 135, 245 },  /* WD AC2420                         */
+       {  6, "41 0", 175, 355 },  /* WD Caviar 140                     */
+       {  6, "82 0", 175, 355 },  /* WD Caviar 280                     */
+       {  8, "PL01", 175, 375 },  /* Quantum LP105                     */
+       {  8, "PL25", 110, 295 },  /* Quantum LP525                     */
+       { 10, "4S 2", 175, 385 },  /* Quantum ELS42                     */
+       { 10, "8S 5", 175, 385 },  /* Quantum ELS85                     */
+       { 10, "1S72", 175, 385 },  /* Quantum ELS127                    */
+       { 10, "1S07", 175, 385 },  /* Quantum ELS170                    */
+       {  8, "ZE42", 135, 295 },  /* Quantum EZ240                     */
+       {  8, "ZE21", 175, 385 },  /* Quantum EZ127                     */
+       {  8, "ZE58", 175, 385 },  /* Quantum EZ85                      */
+       {  8, "ZE24", 175, 385 },  /* Quantum EZ42                      */
+       { 27, "C036", 155, 325 },  /* Conner CP30064                    */
+       { 27, "C038", 155, 325 },  /* Conner CP30084                    */
+       {  6, "2205", 110, 255 },  /* WDC AC2250                        */
+       {  2, " CHA", 140, 415 },  /* WDC AH series; WDC AH260, WDC     */
+       {  2, " CLA", 140, 415 },  /* WDC AL series: WDC AL2120, 2170,  */
+       {  4, "UC41", 140, 415 },  /* WDC CU140                         */
+       {  6, "1207", 130, 275 },  /* WDC AC2170                        */
+       {  6, "2107", 130, 275 },  /* WDC AC1270                        */
+       {  6, "5204", 130, 275 },  /* WDC AC2540                        */
+       { 30, "3004", 110, 235 },  /* Conner CP30340                    */
+       { 30, "0345", 135, 255 },  /* Conner CP30544                    */
+       { 12, "12A3", 175, 320 },  /* MAXTOR LXT-213A                   */
+       { 12, "43A0", 145, 240 },  /* MAXTOR LXT-340A                   */
+       {  6, "7 21", 180, 290 },  /* Maxtor 7120 AT                    */
+       {  6, "7 71", 135, 240 },  /* Maxtor 7170 AT                    */
+       { 12, "45\0000", 110, 205 },   /* MAXTOR MXT-540                */
+       {  8, "PL11", 180, 290 },  /* QUANTUM LP110A                    */
+       {  8, "OG21", 150, 275 },  /* QUANTUM GO120                     */
+       { 12, "42A5", 175, 320 },  /* MAXTOR LXT-245A                   */
+       {  2, "2309", 175, 295 },  /* ST3290A                           */
+       {  2, "3358", 180, 310 },  /* ST3385A                           */
+       {  2, "6355", 180, 310 },  /* ST3655A                           */
+       {  2, "1900", 175, 270 },  /* ST9100A                           */
+       {  2, "1954", 175, 270 },  /* ST9145A                           */
+       {  2, "1909", 175, 270 },  /* ST9190AG                          */
+       {  2, "2953", 175, 270 },  /* ST9235A                           */
+       {  2, "1359", 175, 270 },  /* ST3195A                           */
+       { 24, "3R11", 175, 290 },  /* ALPS ELECTRIC Co.,LTD, DR311C     */
+       {  0, "2M26", 175, 215 },  /* M262XT-0Ah                        */
+       {  4, "2253", 175, 300 },  /* HP C2235A                         */
+       {  4, "-32A", 145, 245 },  /* H3133-A2                          */
+       { 30, "0326", 150, 270 },  /* Samsung Electronics 120MB         */
+       { 30, "3044", 110, 195 },  /* Conner CFA340A                    */
+       { 30, "43A0", 110, 195 },  /* Conner CFA340A                    */
+       { -1, "    ", 175, 415 }   /* unknown disk name                 */
+};
index e8f8379254e3f3cd34c3e56177139bc48803472a..d8ed8be3f53fb4f4f016285b540d8f32c9ac2d50 100644 (file)
@@ -96,7 +96,7 @@ static struct _udma_mode_mapping {
        { 4, "Mode 2" }, 
        { 3, "Mode 3" },
        { 2, "Mode 4" },
-       { 0, "Undefined" }
+       { 0, "Mode 5" }
 };
 
 static __inline__ char * find_udma_mode (byte cycle_time)
@@ -135,7 +135,7 @@ static char *recovery_time [] ={
 };
 
 static char * cycle_time [] = {
-       "Undefined", "2 CLCK",
+       "2 CLK", "2 CLK",
        "3 CLK", "4 CLK",
        "5 CLK", "6 CLK",
        "7 CLK", "8 CLK"
@@ -495,7 +495,7 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
        printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive->dn);
 #endif /* SIS5513_DEBUG_DRIVE_INFO */
 
-       return ((int)   ((id->dma_ultra >> 11) & 3) ? ide_dma_on :
+       return ((int)   ((id->dma_ultra >> 11) & 7) ? ide_dma_on :
                        ((id->dma_ultra >> 8) & 7) ? ide_dma_on :
                        ((id->dma_mword >> 8) & 7) ? ide_dma_on :
                        ((id->dma_1word >> 8) & 7) ? ide_dma_on :
@@ -515,7 +515,7 @@ static int config_drive_xfer_rate (ide_drive_t *drive)
                }
                dma_func = ide_dma_off_quietly;
                if (id->field_valid & 4) {
-                       if (id->dma_ultra & 0x001F) {
+                       if (id->dma_ultra & 0x003F) {
                                /* Force if Capable UltraDMA */
                                dma_func = config_chipset_for_dma(drive, 1);
                                if ((id->field_valid & 2) &&
index d868e5f4009f599936b7d3f64fca2565fb68dfde..4e9e16d8231869ca6e13696c69d9fc7e31633844 100644 (file)
@@ -28,7 +28,6 @@
 
 extern char *ide_xfer_verbose (byte xfer_rate);
 
-#ifdef CONFIG_ARCH_NETWINDER
 /*
  * Convert a PIO mode and cycle time to the required on/off
  * times for the interface.  This has protection against run-away
@@ -273,36 +272,3 @@ void __init ide_init_sl82c105(ide_hwif_t *hwif)
        hwif->tuneproc = tune_sl82c105;
 }
 
-#else
-
-unsigned int pci_init_sl82c105(struct pci_dev *dev, const char *msg)
-{
-       return ide_special_settings(dev, msg);
-}
-
-void dma_init_sl82c105(ide_hwif_t *hwif, unsigned long dma_base)
-{
-       ide_setup_dma(hwif, dma_base, 8);
-}
-
-void __init ide_init_sl82c105(ide_hwif_t *hwif)
-{
-       struct pci_dev *dev = hwif->pci_dev;
-       unsigned short t16;
-       unsigned int t32;
-       pci_read_config_word(dev, PCI_COMMAND, &t16);
-       printk("SL82C105 command word: %x\n",t16);
-        t16 |= PCI_COMMAND_IO;
-        pci_write_config_word(dev, PCI_COMMAND, t16);
-       /* IDE timing */
-       pci_read_config_dword(dev, 0x44, &t32);
-       printk("IDE timing: %08x, resetting to PIO0 timing\n",t32);
-       pci_write_config_dword(dev, 0x44, 0x03e4);
-#ifndef CONFIG_MBX
-       pci_read_config_dword(dev, 0x40, &t32);
-       printk("IDE control/status register: %08x\n",t32);
-       pci_write_config_dword(dev, 0x40, 0x10ff08a1);
-#endif /* CONFIG_MBX */
-}
-#endif
-
index af073283da19161be3b9dec33d2fca89ebb0c067..9d6636f239daccbee3b9241d1200cd9eec827eba 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: via82cxxx.c,v 3.26 2001/08/17 12:03:00 vojtech Exp $
+ * $Id: via82cxxx.c,v 3.28 2001/09/01 21:10:00 vojtech Exp $
  *
  *  Copyright (c) 2000-2001 Vojtech Pavlik
  *
 /*
  * VIA IDE driver for Linux. Supports
  *
- *   vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b,
+ *   vt82c576, vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b,
  *   vt82c686, vt82c686a, vt82c686b, vt8231, vt8233
  *
  * southbridges, which can be found in
  *
- *  VIA Apollo VP, VPX, VPX/97, VP2, VP2/97, VP3, MVP3, MVP4, P6, Pro,
- *  Pro Plus, Pro 133, Pro 133A, ProMedia PM601, ProSavage PM133, PLE133,
- *  Pro 266, KX133, KT133, ProSavage KM133, KT133A, KT266
- *  PC-Chips VXPro, VXPro+, TXPro-III, TXPro-AGP, ViaGra, BXToo, BXTel
- *  AMD 640, 640 AGP, 750 IronGate
- *  ETEQ 6618, 6628, 6638
+ *  VIA Apollo Master, VP, VP2, VP2/97, VP3, VPX, VPX/97, MVP3, MVP4, P6, Pro,
+ *    ProII, ProPlus, Pro133, Pro133+, Pro133A, Pro133A Dual, Pro133T, Pro133Z,
+ *    PLE133, PLE133T, Pro266, Pro266T, ProP4X266, PM601, PM133, PN133, PL133T,
+ *    PX266, PM266, KX133, KT133, KT133A, KLE133, KT266, KX266, KM133, KM133A,
+ *    KL133, KN133, KM266
+ *  PC-Chips VXPro, VXPro+, VXTwo, TXPro-III, TXPro-AGP, AGPPro, ViaGra, BXToo,
+ *    BXTel, BXpert
+ *  AMD 640, 640 AGP, 750 IronGate, 760, 760MP
+ *  ETEQ 6618, 6628, 6629, 6638
  *  Micron Samurai
  *
  * chipsets. Supports
@@ -100,6 +103,11 @@ static struct via_isa_bridge {
        unsigned char rev_max;
        unsigned short flags;
 } via_isa_bridges[] = {
+#ifdef FUTURE_BRIDGES
+       { "vt8237",     PCI_DEVICE_ID_VIA_8237,     0x00, 0x2f, VIA_UDMA_100 },
+       { "vt8235",     PCI_DEVICE_ID_VIA_8235,     0x00, 0x2f, VIA_UDMA_100 },
+       { "vt8233c",    PCI_DEVICE_ID_VIA_8233C,    0x30, 0x4f, VIA_UDMA_100 },
+#endif
        { "vt8233",     PCI_DEVICE_ID_VIA_8233_0,   0x00, 0x2f, VIA_UDMA_100 },
        { "vt8231",     PCI_DEVICE_ID_VIA_8231,     0x00, 0x2f, VIA_UDMA_100 },
        { "vt82c686b",  PCI_DEVICE_ID_VIA_82C686,   0x40, 0x4f, VIA_UDMA_100 },
@@ -107,10 +115,12 @@ static struct via_isa_bridge {
        { "vt82c686",   PCI_DEVICE_ID_VIA_82C686,   0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 },
        { "vt82c596b",  PCI_DEVICE_ID_VIA_82C596,   0x10, 0x2f, VIA_UDMA_66 },
        { "vt82c596a",  PCI_DEVICE_ID_VIA_82C596,   0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 },
-       { "vt82c586b",  PCI_DEVICE_ID_VIA_82C586_0, 0x40, 0x4f, VIA_UDMA_33 | VIA_SET_FIFO | VIA_BAD_PREQ },
+       { "vt82c586b",  PCI_DEVICE_ID_VIA_82C586_0, 0x47, 0x4f, VIA_UDMA_33 | VIA_SET_FIFO },
+       { "vt82c586b",  PCI_DEVICE_ID_VIA_82C586_0, 0x40, 0x46, VIA_UDMA_33 | VIA_SET_FIFO | VIA_BAD_PREQ },
        { "vt82c586b",  PCI_DEVICE_ID_VIA_82C586_0, 0x30, 0x3f, VIA_UDMA_33 | VIA_SET_FIFO },
        { "vt82c586a",  PCI_DEVICE_ID_VIA_82C586_0, 0x20, 0x2f, VIA_UDMA_33 | VIA_SET_FIFO },
        { "vt82c586",   PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, VIA_UDMA_NONE | VIA_SET_FIFO },
+       { "vt82c576",   PCI_DEVICE_ID_VIA_82C576,   0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO },
        { NULL }
 };
 
@@ -151,7 +161,7 @@ static int via_get_info(char *buffer, char **addr, off_t offset, int count)
 
        via_print("----------VIA BusMastering IDE Configuration----------------");
 
-       via_print("Driver Version:                     3.26");
+       via_print("Driver Version:                     3.27");
        via_print("South Bridge:                       VIA %s", via_config->name);
 
        pci_read_config_byte(isa_dev, PCI_REVISION_ID, &t);
index 3ce13fcd4632a72334e1904ba88e6e49f393d0c7..e33b5ed75db1b887648b8643cef71e08210feb7a 100644 (file)
@@ -157,15 +157,16 @@ void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host,
 #define DEFINE_MULTIPLEXER(Function) \
 void highlevel_##Function(struct hpsb_host *host) \
 { \
-        struct list_head *entry; \
+        struct list_head *entry,*next; \
         void (*funcptr)(struct hpsb_host*); \
         read_lock(&hl_drivers_lock); \
         entry = hl_drivers.next; \
         while (entry != &hl_drivers) { \
+               next = entry->next; \
                 funcptr = list_entry(entry, struct hpsb_highlevel, hl_list) \
                           ->op->Function; \
                 if (funcptr) funcptr(host); \
-                entry = entry->next; \
+                entry = next; \
         } \
         read_unlock(&hl_drivers_lock); \
 }
index 689444358f291b6f60678ca06b3b0390f5a6ffa9..fe58e3a33bc005938310f9c3e8446d53db6ab770 100644 (file)
@@ -352,7 +352,7 @@ void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,
         }
 
         if (ackcode != ACK_PENDING || !packet->expect_response) {
-                packet->state = complete;
+                packet->state = completed;
                 up(&packet->state_change);
                 up(&packet->state_change);
                 run_task_queue(&packet->complete_tq);
@@ -503,7 +503,7 @@ void handle_packet_response(struct hpsb_host *host, int tcode, quadlet_t *data,
                 break;
         }
 
-        packet->state = complete;
+        packet->state = completed;
         up(&packet->state_change);
         run_task_queue(&packet->complete_tq);
 }
@@ -720,7 +720,7 @@ void abort_requests(struct hpsb_host *host)
 
         list_for_each(lh, &llist) {
                 packet = list_entry(lh, struct hpsb_packet, list);
-                packet->state = complete;
+                packet->state = completed;
                 packet->ack_code = ACKX_ABORTED;
                 up(&packet->state_change);
                 run_task_queue(&packet->complete_tq);
@@ -761,7 +761,7 @@ void abort_timedouts(struct hpsb_host *host)
 
         list_for_each(lh, &expiredlist) {
                 packet = list_entry(lh, struct hpsb_packet, list);
-                packet->state = complete;
+                packet->state = completed;
                 packet->ack_code = ACKX_TIMEOUT;
                 up(&packet->state_change);
                 run_task_queue(&packet->complete_tq);
index 422997faec06e35f01d46221b1276f3a31299a20..c1ebc47ad6264dde23902cc3e0e8eed3ec39af5b 100644 (file)
@@ -25,11 +25,11 @@ struct hpsb_packet {
         /* Okay, this is core internal and a no care for hosts.
          * queued   = queued for sending
          * pending  = sent, waiting for response
-         * complete = processing completed, successful or not
+         * completed = processing completed, successful or not
          * incoming = incoming packet
          */
         enum { 
-                unused, queued, pending, complete, incoming 
+                unused, queued, pending, completed, incoming 
         } __attribute__((packed)) state;
 
         /* These are core internal. */
index aede8b81c577c1e917dd27e39dde195a5d3b562d..c36164745290c056977b689c2ac834540b827c34 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: isar.c,v 1.17.6.3 2001/06/09 15:14:17 kai Exp $
+/* $Id: isar.c,v 1.17.6.4 2001/08/17 12:34:26 kai Exp $
  *
  * isar.c   ISAR (Siemens PSB 7110) specific routines
  *
@@ -18,8 +18,6 @@
 #define DBG_LOADFIRM   0
 #define DUMP_MBOXFRAME 2
 
-#define MIN(a,b) ((a<b)?a:b)
-
 #define DLE    0x10
 #define ETX    0x03
 
@@ -272,7 +270,9 @@ isar_load_firmware(struct IsdnCardState *cs, u_char *buf)
                        ret = 1;goto reterror;
                }
                while (left>0) {
-                       noc = MIN(126, left);
+                       noc = left;
+                       if (noc > 126)
+                               noc = 126;
                        nom = 2*noc;
                        mp  = msg;
                        *mp++ = sadr / 256;
index 26e154d5660c212e10de8735a47a35824dc1baf2..9c68d92520dfe19553930397d642d15be822b526 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: icn.c,v 1.65.6.6 2001/07/13 09:20:12 kai Exp $
+/* $Id: icn.c,v 1.65.6.7 2001/08/17 12:34:27 kai Exp $
 
  * ISDN low-level module for the ICN active ISDN-Card.
  *
@@ -34,7 +34,7 @@
 #undef MAP_DEBUG
 
 static char
-*revision = "$Revision: 1.65.6.6 $";
+*revision = "$Revision: 1.65.6.7 $";
 
 static int icn_addcard(int, char *, char *);
 
@@ -930,7 +930,9 @@ icn_loadproto(u_char * buffer, icn_card * card)
        restore_flags(flags);
        while (left) {
                if (sbfree) {   /* If there is a free buffer...  */
-                       cnt = MIN(256, left);
+                       cnt = left;
+                       if (cnt > 256)
+                               cnt = 256;
                        if (copy_from_user(codebuf, p, cnt)) {
                                icn_maprelease_channel(card, 0);
                                return -EFAULT;
@@ -1029,7 +1031,6 @@ static int
 icn_writecmd(const u_char * buf, int len, int user, icn_card * card)
 {
        int mch = card->secondhalf ? 2 : 0;
-       int avail;
        int pp;
        int i;
        int count;
@@ -1046,8 +1047,9 @@ icn_writecmd(const u_char * buf, int len, int user, icn_card * card)
        ocount = 1;
        xcount = loop = 0;
        while (len) {
-               avail = cmd_free;
-               count = MIN(avail, len);
+               count = cmd_free;
+               if (count > len)
+                       count = len;
                if (user)
                        copy_from_user(msg, buf, count);
                else
index 789b7deb987ac3f19823c060f2f8ca91138721e6..281b85735dc7eeb2b95d2fb011c8575e925ca66a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: icn.h,v 1.30.6.3 2001/04/20 02:42:01 keil Exp $
+/* $Id: icn.h,v 1.30.6.4 2001/08/17 12:34:27 kai Exp $
 
  * ISDN lowlevel-module for the ICN active ISDN-Card.
  *
@@ -285,8 +285,5 @@ MODULE_PARM_DESC(icn_id2, "ID-String of first card, second S0 (4B only)");
 
 #define CID (card->interface.id)
 
-#define MIN(a,b) ((a<b)?a:b)
-#define MAX(a,b) ((a>b)?a:b)
-
 #endif                          /* defined(__KERNEL__) || defined(__DEBUGVAR__) */
 #endif                          /* icn_h */
index e8850ee95107e87b383dc12de8179a25a7cd623d..d5f05e029b0cf23f0149708d3b90c36d3e4ff573 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: isdn_audio.c,v 1.21 2000/06/20 18:01:55 keil Exp $
+/* $Id: isdn_audio.c,v 1.21.6.1 2001/08/17 12:34:25 kai Exp $
 
  * Linux ISDN subsystem, audio conversion and compression (linklevel).
  *
@@ -28,7 +28,7 @@
 #include "isdn_audio.h"
 #include "isdn_common.h"
 
-char *isdn_audio_revision = "$Revision: 1.21 $";
+char *isdn_audio_revision = "$Revision: 1.21.6.1 $";
 
 /*
  * Misc. lookup-tables.
@@ -607,7 +607,9 @@ isdn_audio_calc_dtmf(modem_info * info, unsigned char *buf, int len, int fmt)
        int c;
 
        while (len) {
-               c = MIN(len, (DTMF_NPOINTS - s->idx));
+               c = DTMF_NPOINTS - s->idx;
+               if (c > len)
+                       c = len;
                if (c <= 0)
                        break;
                for (i = 0; i < c; i++) {
index e6e8108af79d2ebd2534871365330b03fc67c395..7b0ac469a687ebc9e042b6acae622c85635f50ca 100644 (file)
@@ -176,7 +176,6 @@ pcbit_transmit(struct pcbit_dev *dev)
        struct frame_buf *frame = NULL;
        unsigned char unacked;
        int flen;               /* fragment frame length including all headers */
-       int totlen;             /* non-fragmented frame length */
        int free;
        int count,
         cp_len;
@@ -213,11 +212,12 @@ pcbit_transmit(struct pcbit_dev *dev)
                        ulong   msg;
 
                        if (frame->skb)
-                               totlen = FRAME_HDR_LEN + PREHDR_LEN + frame->skb->len;
+                               flen = FRAME_HDR_LEN + PREHDR_LEN + frame->skb->len;
                        else
-                               totlen = FRAME_HDR_LEN + PREHDR_LEN;
+                               flen = FRAME_HDR_LEN + PREHDR_LEN;
 
-                       flen = MIN(totlen, free);
+                       if (flen > free)
+                               flen = free;
 
                        msg = frame->msg;
 
@@ -259,9 +259,10 @@ pcbit_transmit(struct pcbit_dev *dev)
                } else {
                        /* Type 1 frame */
 
-                       totlen = 2 + (frame->skb->len - frame->copied);
+                       flen = 2 + (frame->skb->len - frame->copied);
 
-                       flen = MIN(totlen, free);
+                       if (flen > free)
+                               flen = free;
 
                        /* TT */
                        tt = ((ushort) (flen - 2)) | 0x8000U;   /* Type 1 */
@@ -271,8 +272,9 @@ pcbit_transmit(struct pcbit_dev *dev)
                }
 
                if (frame->skb) {
-                       cp_len = MIN(frame->skb->len - frame->copied,
-                                    flen - count);
+                       cp_len = frame->skb->len - frame->copied;
+                       if (cp_len > flen - count)
+                               cp_len = flen - count;
 
                        memcpy_topcbit(dev, frame->skb->data + frame->copied,
                                       cp_len);
index 6d3e6cb3c8db3387f8695a2848979f0e80808f3b..69e24ce9413aa8e9e343a18c1203bfde58c52e09 100644 (file)
@@ -121,8 +121,6 @@ struct frame_buf {
         struct frame_buf * next;
 };
 
-#define MIN(a,b) ((a<b)?a:b)
-
 extern int pcbit_l2_write(struct pcbit_dev * dev, ulong msg, ushort refnum, 
                           struct sk_buff *skb, unsigned short hdr_len);
 
index 3536c85cf35ca54b5301f38420185cf241b4b017..fc27265d79855cc09c936f5cd05bef25085e4c37 100644 (file)
@@ -18,7 +18,7 @@
 
 #define NVRAM_SIZE     8192
 
-static long long nvram_llseek(struct file *file, loff_t offset, int origin)
+static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
 {
        switch (origin) {
        case 1:
index 5b97e8c61911372be20b25c10c30f3cb8a4d6cbe..c484e420715e36dc539c27a5adf7b3b655bba233 100644 (file)
@@ -2769,7 +2769,6 @@ static struct block_device_operations md_fops=
 int md_thread(void * arg)
 {
        mdk_thread_t *thread = arg;
-       struct completion *event;
 
        md_lock_kernel();
 
@@ -2910,7 +2909,7 @@ int md_error (mddev_t *mddev, kdev_t rdev)
                return 0;
        }
        rrdev = find_rdev(mddev, rdev);
-       if (rrdev->faulty)
+       if (!rrdev || rrdev->faulty)
                return 0;
        if (mddev->pers->error_handler == NULL
            || mddev->pers->error_handler(mddev,rdev) <= 0) {
@@ -3213,7 +3212,7 @@ recheck:
                if (mddev2 == mddev)
                        continue;
                if (mddev2->curr_resync && match_mddev_units(mddev,mddev2)) {
-                       printk(KERN_INFO "md: serializing resync, md%d shares one or more physical units with md%d!\n", mdidx(mddev), mdidx(mddev2));
+                       printk(KERN_INFO "md: delaying resync of md%d until md%d has finished resync (they share one or more physical units)\n", mdidx(mddev), mdidx(mddev2));
                        serialize = 1;
                        break;
                }
@@ -3275,9 +3274,12 @@ recheck:
 
                if (last_check + window > j)
                        continue;
+
+               last_check = j;
                
-               run_task_queue(&tq_disk); //??
+               run_task_queue(&tq_disk);
 
+       repeat:
                if (jiffies >= mark[last_mark] + SYNC_MARK_STEP ) {
                        /* step marks */
                        int next = (last_mark+1) % SYNC_MARKS;
@@ -3309,7 +3311,6 @@ recheck:
                 * about not overloading the IO subsystem. (things like an
                 * e2fsck being done on the RAID array should execute fast)
                 */
-repeat:
                if (md_need_resched(current))
                        schedule();
 
@@ -3322,8 +3323,7 @@ repeat:
                                        !is_mddev_idle(mddev)) {
                                current->state = TASK_INTERRUPTIBLE;
                                md_schedule_timeout(HZ/4);
-                               if (!md_signal_pending(current))
-                                       goto repeat;
+                               goto repeat;
                        }
                } else
                        current->nice = -20;
@@ -3748,7 +3748,7 @@ void md__init md_setup_drive(void)
                        ainfo.md_minor =minor;
                        ainfo.not_persistent = 1;
 
-                       ainfo.state = MD_SB_CLEAN;
+                       ainfo.state = (1 << MD_SB_CLEAN);
                        ainfo.active_disks = 0;
                        ainfo.working_disks = 0;
                        ainfo.failed_disks = 0;
index 60bd041ebea0f14c74d85c6373a5b89096a2f2ca..c63f68c4729118a936af5377dbed699f26d8ee26 100644 (file)
@@ -485,7 +485,7 @@ static int raid5_error (mddev_t *mddev, kdev_t dev)
        int i;
 
        PRINTK("raid5_error called\n");
-       conf->resync_parity = 0;
+
        for (i = 0, disk = conf->disks; i < conf->raid_disks; i++, disk++) {
                if (disk->dev == dev && disk->operational) {
                        disk->operational = 0;
@@ -516,7 +516,7 @@ static int raid5_error (mddev_t *mddev, kdev_t dev)
                                "raid5: Disk failure on spare %s\n",
                                partition_name (dev));
                        if (!conf->spare->operational) {
-                               MD_BUG();
+                               /* probably a SET_DISK_FAULTY ioctl */
                                return -EIO;
                        }
                        disk->operational = 0;
@@ -529,6 +529,9 @@ static int raid5_error (mddev_t *mddev, kdev_t dev)
                        sb->working_disks--;
                        sb->failed_disks++;
 
+                       mddev->sb_dirty = 1;
+                       md_wakeup_thread(conf->thread);
+
                        return 0;
                }
        }
@@ -898,11 +901,11 @@ static void handle_stripe(struct stripe_head *sh)
                                spin_unlock_irq(&conf->device_lock);
                        }
                }
-               if (syncing) {
-                       md_done_sync(conf->mddev, (sh->size>>9) - sh->sync_redone,0);
-                       clear_bit(STRIPE_SYNCING, &sh->state);
-                       syncing = 0;
-               }                       
+       }
+       if (failed > 1 && syncing) {
+               md_done_sync(conf->mddev, (sh->size>>9) - sh->sync_redone,0);
+               clear_bit(STRIPE_SYNCING, &sh->state);
+               syncing = 0;
        }
 
        /* might be able to return some write requests if the parity block
@@ -1076,6 +1079,7 @@ static void handle_stripe(struct stripe_head *sh)
                        }
                }
                if (!test_bit(STRIPE_INSYNC, &sh->state)) {
+                       struct disk_info *spare;
                        if (failed==0)
                                failed_num = sh->pd_idx;
                        /* should be able to compute the missing block and write it to spare */
@@ -1094,8 +1098,8 @@ static void handle_stripe(struct stripe_head *sh)
                        set_bit(STRIPE_INSYNC, &sh->state);
                        if (conf->disks[failed_num].operational)
                                md_sync_acct(conf->disks[failed_num].dev, bh->b_size>>9);
-                       else if (conf->spare)
-                               md_sync_acct(conf->spare->dev, bh->b_size>>9);
+                       else if ((spare=conf->spare))
+                               md_sync_acct(spare->dev, bh->b_size>>9);
 
                }
        }
@@ -1120,6 +1124,7 @@ static void handle_stripe(struct stripe_head *sh)
        for (i=disks; i-- ;) 
                if (action[i]) {
                        struct buffer_head *bh = sh->bh_cache[i];
+                       struct disk_info *spare = conf->spare;
                        int skip = 0;
                        if (action[i] == READ+1)
                                bh->b_end_io = raid5_end_read_request;
@@ -1127,8 +1132,8 @@ static void handle_stripe(struct stripe_head *sh)
                                bh->b_end_io = raid5_end_write_request;
                        if (conf->disks[i].operational)
                                bh->b_dev = conf->disks[i].dev;
-                       else if (conf->spare && action[i] == WRITE+1)
-                               bh->b_dev = conf->spare->dev;
+                       else if (spare && action[i] == WRITE+1)
+                               bh->b_dev = spare->dev;
                        else skip=1;
                        if (!skip) {
                                PRINTK("for %ld schedule op %d on disc %d\n", sh->sector, action[i]-1, i);
diff --git a/drivers/media/video/vino.h b/drivers/media/video/vino.h
new file mode 100644 (file)
index 0000000..11a2616
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 1999 Ulf Carlsson (ulfc@bun.falkenberg.se)
+ * Copyright (C) 2001 Ralf Baechle (ralf@gnu.org)
+ */
+
+#define VINO_BASE              0x00080000      /* In EISA address space */
+
+#define VINO_REVID             0x0000
+#define VINO_CTRL              0x0008
+#define VINO_INTSTAT           0x0010  /* Interrupt status */
+#define VINO_I2C_CTRL          0x0018
+#define VINO_I2C_DATA          0x0020
+#define VINO_A_ALPHA           0x0028  /* Channel A ... */
+#define VINO_A_CLIPS           0x0030  /* Clipping start */
+#define VINO_A_CLIPE           0x0038  /* Clipping end */
+#define VINO_A_FRAMERT         0x0040  /* Framerate */
+#define VINO_A_FLDCNT          0x0048  /* Field counter */
+#define VINO_A_LNSZ            0x0050
+#define VINO_A_LNCNT           0x0058
+#define VINO_A_PGIX            0x0060  /* Page index */
+#define VINO_A_DESC_PTR                0x0068  /* Ptr to next four descriptors */
+#define VINO_A_DESC_TLB_PTR    0x0070  /* Ptr to start of descriptor table */
+#define VINO_A_DESC_DATA0      0x0078  /* Descriptor data 0 */
+#define VINO_A_DESC_DATA1      0x0080  /* ... */
+#define VINO_A_DESC_DATA2      0x0088
+#define VINO_A_DESC_DATA3      0x0090
+#define VINO_A_FIFO_THRESHOLD  0x0098  /* FIFO threshold */
+#define VINO_A_FIFO_RP         0x00a0
+#define VINO_A_FIFO_WP         0x00a8
+#define VINO_B_ALPHA           0x00b0  /* Channel B ... */
+#define VINO_B_CLIPS           0x00b8
+#define VINO_B_CLIPE           0x00c0
+#define VINO_B_FRAMERT         0x00c8
+#define VINO_B_FLDCNT          0x00d0
+#define VINO_B_LNSZ            0x00d8
+#define VINO_B_LNCNT           0x00e0
+#define VINO_B_PGIX            0x00e8
+#define VINO_B_DESC_PTR                0x00f0
+#define VINO_B_DESC_TLB_PTR    0x00f8
+#define VINO_B_DESC_DATA0      0x0100
+#define VINO_B_DESC_DATA1      0x0108
+#define VINO_B_DESC_DATA2      0x0110
+#define VINO_B_DESC_DATA3      0x0118
+#define VINO_B_FIFO_THRESHOLD  0x0120
+#define VINO_B_FIFO_RP         0x0128
+#define VINO_B_FIFO_WP         0x0130
+
+/* Bits in the VINO_REVID register */
+
+#define VINO_REVID_REV_MASK            0x000f  /* bits 0:3 */
+#define VINO_REVID_ID_MASK             0x00f0  /* bits 4:7 */
+
+/* Bits in the VINO_CTRL register */
+
+#define VINO_CTRL_LITTLE_ENDIAN                (1<<0)
+#define VINO_CTRL_A_FIELD_TRANS_INT    (1<<1)  /* Field transferred int */
+#define VINO_CTRL_A_FIFO_OF_INT                (1<<2)  /* FIFO overflow int */
+#define VINO_CTRL_A_END_DESC_TBL_INT   (1<<3)  /* End of desc table int */
+#define VINO_CTRL_B_FIELD_TRANS_INT    (1<<4)  /* Field transferred int */
+#define VINO_CTRL_B_FIFO_OF_INT                (1<<5)  /* FIFO overflow int */
+#define VINO_CTRL_B_END_DESC_TLB_INT   (1<<6)  /* End of desc table int */
+#define VINO_CTRL_A_DMA_ENBL           (1<<7)
+#define VINO_CTRL_A_INTERLEAVE_ENBL    (1<<8)
+#define VINO_CTRL_A_SYNC_ENBL          (1<<9)
+#define VINO_CTRL_A_SELECT             (1<<10) /* 1=D1 0=Philips */
+#define VINO_CTRL_A_RGB                        (1<<11) /* 1=RGB 0=YUV */
+#define VINO_CTRL_A_LUMA_ONLY          (1<<12)
+#define VINO_CTRL_A_DEC_ENBL           (1<<13) /* Decimation */
+#define VINO_CTRL_A_DEC_SCALE_MASK     0x1c000 /* bits 14:17 */
+#define VINO_CTRL_A_DEC_HOR_ONLY       (1<<17) /* Horizontal only */
+#define VINO_CTRL_A_DITHER             (1<<18) /* 24 -> 8 bit dither */
+#define VINO_CTRL_B_DMA_ENBL           (1<<19)
+#define VINO_CTRL_B_INTERLEAVE_ENBL    (1<<20)
+#define VINO_CTRL_B_SYNC_ENBL          (1<<21)
+#define VINO_CTRL_B_SELECT             (1<<22) /* 1=D1 0=Philips */
+#define VINO_CTRL_B_RGB                        (1<<22) /* 1=RGB 0=YUV */
+#define VINO_CTRL_B_LUMA_ONLY          (1<<23)
+#define VINO_CTRL_B_DEC_ENBL           (1<<24) /* Decimation */
+#define VINO_CTRL_B_DEC_SCALE_MASK     0x1c000000      /* bits 25:28 */
+#define VINO_CTRL_B_DEC_HOR_ONLY       (1<<29) /* Decimation horizontal only */
+#define VINO_CTRL_B_DITHER             (1<<30) /* ChanB 24 -> 8 bit dither */
+
+/* Bits in the Interrupt and Status register */
+
+#define VINO_INTSTAT_A_FIELD_TRANS     (1<<0)  /* Field transferred int */
+#define VINO_INTSTAT_A_FIFO_OF         (1<<1)  /* FIFO overflow int */
+#define VINO_INTSTAT_A_END_DESC_TBL    (1<<2)  /* End of desc table int */
+#define VINO_INTSTAT_B_FIELD_TRANS     (1<<3)  /* Field transferred int */
+#define VINO_INTSTAT_B_FIFO_OF         (1<<4)  /* FIFO overflow int */
+#define VINO_INTSTAT_B_END_DESC_TBL    (1<<5)  /* End of desc table int */
+
+/* Bits in the Clipping Start register */
+
+#define VINO_CLIPS_START               0x3ff           /* bits 0:9 */
+#define VINO_CLIPS_ODD_MASK            0x7fc00         /* bits 10:18 */
+#define VINO_CLIPS_EVEN_MASK           0xff80000       /* bits 19:27 */
+
+/* Bits in the Clipping End register */
+
+#define VINO_CLIPE_END                 0x3ff           /* bits 0:9 */
+#define VINO_CLIPE_ODD_MASK            0x7fc00         /* bits 10:18 */
+#define VINO_CLIPE_EVEN_MASK           0xff80000       /* bits 19:27 */
+
+/* Bits in the Frame Rate register */
+
+#define VINO_FRAMERT_PAL               (1<<0)  /* 0=NTSC 1=PAL */
+#define VINO_FRAMERT_RT_MASK           0x1ffe          /* bits 1:12 */
+
+/* Bits in the VINO_I2C_CTRL */
+
+#define VINO_CTRL_I2C_IDLE             (1<<0)  /* write: 0=force idle
+                                                * read: 0=idle 1=not idle */
+#define VINO_CTRL_I2C_DIR              (1<<1)  /* 0=read 1=write */
+#define VINO_CTRL_I2C_MORE_BYTES       (1<<2)  /* 0=last byte 1=more bytes */
+#define VINO_CTRL_I2C_TRANS_BUSY       (1<<4)  /* 0=trans done 1=trans busy */
+#define VINO_CTRL_I2C_ACK              (1<<5)  /* 0=ack received 1=ack not */
+#define VINO_CTRL_I2C_BUS_ERROR                (1<<7)  /* 0=no bus err 1=bus err */
index 46df6571dfc5611bc279dc17f75f0200870fe281..a1ddc8e105dffd5b72ec560d8c51e5285ccdbc7a 100644 (file)
@@ -27,18 +27,22 @@ EXTRA_CFLAGS += -I. ${MPT_CFLAGS}
 #EXTRA_CFLAGS += -DDEBUG
 #EXTRA_CFLAGS += -DMPT_DEBUG
 #EXTRA_CFLAGS += -DMPT_DEBUG_MSG_FRAME
-#EXTRA_CFLAGS += -DMPT_DEBUG_SPINLOCK
+#
 # driver/module specifics...
+#
 #  For mptbase:
 #CFLAGS_mptbase.o += -DMPT_DEBUG_HANDSHAKE
 #CFLAGS_mptbase.o += -DMPT_DEBUG_IRQ
+#
 #  For {mptscsih, mptctl}:
 #CFLAGS_mptscsih.o += -DMPT_SCSI_USE_NEW_EH
-#CFLAGS_mptscsih.o += -DMPT_SCSI_CACHE_AUTOSENSE
+#CFLAGS_mptscsih.o += -DMPT_DEBUG_SCANDV
 #CFLAGS_mptscsih.o += -DMPT_DEBUG_SG
 #CFLAGS_mptctl.o += -DMPT_DEBUG_SG
+#
 #  For mptlan:
 #CFLAGS_mptlan.o += -DMPT_LAN_IO_DEBUG
+#
 #  For isense:
 
 #  EXP...
index 553c8db6a37d990189c2bfe0387bcd4dd2d7edab..457c3e819a77f9cb8f6b9b66fb1331f2262dbfee 100644 (file)
@@ -10,7 +10,7 @@
  *  (yes I wrote some of the orig. code back in 1991!)
  *  (mailto:Steve.Ralston@lsil.com)
  *
- *  $Id: isense.c,v 1.28 2001/01/14 23:11:09 sralston Exp $
+ *  $Id: isense.c,v 1.28.14.1 2001/08/24 20:07:04 sralston Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -61,7 +61,7 @@
 #endif
 
 #define MODULEAUTHOR "Steven J. Ralston"
-#define COPYRIGHT "Copyright (c) 2000 " MODULEAUTHOR
+#define COPYRIGHT "Copyright (c) 2001 " MODULEAUTHOR
 #include "mptbase.h"
 
 #include "isense.h"
index 57597172ee31ae066bc1a14b2fe74a2baeea4602..82166de4a2c4965bed3fb9de1621edc167285479 100644 (file)
@@ -7,7 +7,7 @@
  *                  in the IOCLogInfo field of a MPI Default Reply Message.
  *
  *  CREATION DATE:  6/02/2000
- *  ID:             $Id: fc_log.h,v 4.2 2001/03/01 18:28:59 fibre Exp $
+ *  ID:             $Id: fc_log.h,v 4.5 2001/06/07 19:18:00 sschremm Exp $
  */
 
 
@@ -38,11 +38,16 @@ typedef enum _MpiIocLogInfoFc
 {
     MPI_IOCLOGINFO_FC_INIT_BASE                     = 0x20000000,
     MPI_IOCLOGINFO_FC_INIT_ERROR_OUT_OF_ORDER_FRAME = 0x20000001, /* received an out of order frame - unsupported */
-    MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_START_OF_FRAME = 0x20000002, /* bad start of frame primative */
-    MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_END_OF_FRAME   = 0x20000003, /* bad end of frame primative */
-    MPI_IOCLOGINFO_FC_INIT_ERROR_OVER_RUN           = 0x20000004, /* Receiver hardware detected overrun */
+    MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_START_OF_FRAME = 0x20000002, /* Bad Rx Frame, bad start of frame primative */
+    MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_END_OF_FRAME   = 0x20000003, /* Bad Rx Frame, bad end of frame primative */
+    MPI_IOCLOGINFO_FC_INIT_ERROR_OVER_RUN           = 0x20000004, /* Bad Rx Frame, overrun */
     MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OTHER           = 0x20000005, /* Other errors caught by IOC which require retries */
     MPI_IOCLOGINFO_FC_INIT_ERROR_SUBPROC_DEAD       = 0x20000006, /* Main processor could not initialize sub-processor */
+    MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OVERRUN         = 0x20000007, /* Scatter Gather overrun  */
+    MPI_IOCLOGINFO_FC_INIT_ERROR_RX_BAD_STATUS      = 0x20000008, /* Receiver detected context mismatch via invalid header */
+    MPI_IOCLOGINFO_FC_INIT_ERROR_RX_UNEXPECTED_FRAME= 0x20000009, /* CtxMgr detected unsupported frame type  */
+    MPI_IOCLOGINFO_FC_INIT_ERROR_LINK_FAILURE       = 0x2000000A, /* Link failure occurred  */
+    MPI_IOCLOGINFO_FC_INIT_ERROR_TX_TIMEOUT         = 0x2000000B, /* Transmitter timeout error */
 
     MPI_IOCLOGINFO_FC_TARGET_BASE                   = 0x21000000,
     MPI_IOCLOGINFO_FC_TARGET_NO_PDISC               = 0x21000001, /* not sent because we are waiting for a PDISC from the initiator */
@@ -72,10 +77,11 @@ typedef enum _MpiIocLogInfoFc
     MPI_IOCLOGINFO_FC_LINK_LOOP_INIT_TIMEOUT        = 0x24000001, /* Loop initialization timed out */
     MPI_IOCLOGINFO_FC_LINK_ALREADY_INITIALIZED      = 0x24000002, /* Another system controller already initialized the loop */
     MPI_IOCLOGINFO_FC_LINK_LINK_NOT_ESTABLISHED     = 0x24000003, /* Not synchronized to signal or still negotiating (possible cable problem) */
+    MPI_IOCLOGINFO_FC_LINK_CRC_ERROR                = 0x24000004, /* CRC check detected error on received frame */
 
     MPI_IOCLOGINFO_FC_CTX_BASE                      = 0x25000000,
 
-    MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET     = 0x26000000, /* The lower 24 bits give the byte offset of the field in the request message that is invalid. */
+    MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET     = 0x26000000, /* The lower 24 bits give the byte offset of the field in the request message that is invalid */
     MPI_IOCLOGINFO_FC_INVALID_FIELD_MAX_OFFSET      = 0x26ffffff,
 
     MPI_IOCLOGINFO_FC_STATE_CHANGE                  = 0x27000000  /* The lower 24 bits give additional information concerning state change */
index bf0a662e50f52e463091afb315d63200ef88a5d9..9aba9138bbf9513c452b57a234a5eb0ef57bb0fd 100644 (file)
@@ -6,7 +6,7 @@
  *          Title:  MPI Message independent structures and definitions
  *  Creation Date:  July 27, 2000
  *
- *    MPI Version:  01.01.06
+ *    MPI Version:  01.01.07
  *
  *  Version History
  *  ---------------
@@ -37,6 +37,8 @@
  *                      Obsoleted MPI_IOCSTATUS_TARGET_FC_ defines.
  *  02-27-01  01.01.06  Removed MPI_HOST_INDEX_REGISTER define.
  *                      Added function codes for RAID.
+ *  04-09-01  01.01.07  Added alternate define for MPI_DOORBELL_ACTIVE,
+ *                      MPI_DOORBELL_USED, to better match the spec.
  *  --------------------------------------------------------------------------
  */
 
@@ -90,7 +92,8 @@
 
 /* S y s t e m    D o o r b e l l */
 #define MPI_DOORBELL_OFFSET                 (0x00000000)
-#define MPI_DOORBELL_ACTIVE                 (0x08000000)
+#define MPI_DOORBELL_ACTIVE                 (0x08000000) /* DoorbellUsed */
+#define MPI_DOORBELL_USED                   (MPI_DOORBELL_ACTIVE)
 #define MPI_DOORBELL_ACTIVE_SHIFT           (27)
 #define MPI_DOORBELL_WHO_INIT_MASK          (0x07000000)
 #define MPI_DOORBELL_WHO_INIT_SHIFT         (24)
@@ -634,9 +637,9 @@ typedef struct _MSG_DEFAULT_REPLY
 /****************************************************************************/
 
 #define MPI_IOCLOGINFO_TYPE_MASK                (0xF0000000)
-#define MPI_IOCLOGINFO_TYPE_NONE                (0x00)
-#define MPI_IOCLOGINFO_TYPE_SCSI                (0x01)
-#define MPI_IOCLOGINFO_TYPE_FC                  (0x02)
+#define MPI_IOCLOGINFO_TYPE_NONE                (0x0)
+#define MPI_IOCLOGINFO_TYPE_SCSI                (0x1)
+#define MPI_IOCLOGINFO_TYPE_FC                  (0x2)
 #define MPI_IOCLOGINFO_LOG_DATA_MASK            (0x0FFFFFFF)
 
 
index dd81a65e25b547392cf351457613053f6905a6c8..573cc277b46b4fbc1e24868082e0cd5c0212467a 100644 (file)
@@ -6,7 +6,7 @@
  *          Title:  MPI Config message, structures, and Pages
  *  Creation Date:  July 27, 2000
  *
- *    MPI Version:  01.01.09
+ *    MPI Version:  01.01.11
  *
  *  Version History
  *  ---------------
  *                      MPI_CONFIG_PAGETYPE_RAID_VOLUME.
  *                      Added definitions and structures for IOC Page 2 and
  *                      RAID Volume Page 2.
+ *  03-27-01  01.01.10  Added CONFIG_PAGE_FC_PORT_8 and CONFIG_PAGE_FC_PORT_9.
+ *                      CONFIG_PAGE_FC_PORT_3 now supports persistent by DID.
+ *                      Added VendorId and ProductRevLevel fields to
+ *                      RAIDVOL2_IM_PHYS_ID struct.
+ *                      Modified values for MPI_FCPORTPAGE0_FLAGS_ATTACH_
+ *                      defines to make them compatible to MPI version 1.0.
+ *                      Added structure offset comments.
+ *  04-09-01  01.01.11  Added some new defines for the PageAddress field and
+ *                      removed some obsolete ones.
+ *                      Added IO Unit Page 3.
+ *                      Modified defines for Scsi Port Page 2.
+ *                      Modified RAID Volume Pages.
  *  --------------------------------------------------------------------------
  */
 
 
 typedef struct _CONFIG_PAGE_HEADER
 {
-    U8                      PageVersion;
-    U8                      PageLength;
-    U8                      PageNumber;
-    U8                      PageType;
+    U8                      PageVersion;                /* 00h */
+    U8                      PageLength;                 /* 01h */
+    U8                      PageNumber;                 /* 02h */
+    U8                      PageType;                   /* 03h */
 } fCONFIG_PAGE_HEADER, MPI_POINTER PTR_CONFIG_PAGE_HEADER,
   ConfigPageHeader_t, MPI_POINTER pConfigPageHeader_t;
 
@@ -120,17 +132,19 @@ typedef union _CONFIG_PAGE_HEADER_UNION
  ****************************************************************************/
 #define MPI_SCSI_PORT_PGAD_PORT_MASK                (0x000000FF)
 
+#define MPI_SCSI_DEVICE_FORM_MASK                   (0xF0000000)
+#define MPI_SCSI_DEVICE_FORM_TARGETID               (0x00000000)
+#define MPI_SCSI_DEVICE_FORM_RAID_PHYS_DEV_NUM      (0x10000000)
 #define MPI_SCSI_DEVICE_TARGET_ID_MASK              (0x000000FF)
 #define MPI_SCSI_DEVICE_TARGET_ID_SHIFT             (0)
 #define MPI_SCSI_DEVICE_BUS_MASK                    (0x0000FF00)
 #define MPI_SCSI_DEVICE_BUS_SHIFT                   (8)
-
-#define MPI_SCSI_LUN_TARGET_ID_MASK                 (0x000000FF)
-#define MPI_SCSI_LUN_TARGET_ID_SHIFT                (0)
-#define MPI_SCSI_LUN_BUS_MASK                       (0x0000FF00)
-#define MPI_SCSI_LUN_BUS_SHIFT                      (8)
-#define MPI_SCSI_LUN_LUN_MASK                       (0x00FF0000)
-#define MPI_SCSI_LUN_LUN_SHIFT                      (16)
+#define MPI_SCSI_DEVICE_VOLUME_TARG_ID_MASK         (0x000000FF)
+#define MPI_SCSI_DEVICE_VOLUME_TARG_ID_SHIFT        (0)
+#define MPI_SCSI_DEVICE_VOLUME_BUS_MASK             (0x0000FF00)
+#define MPI_SCSI_DEVICE_VOLUME_BUS_SHIFT            (8)
+#define MPI_SCSI_DEVICE_PHYS_DISK_NUM_MASK          (0x00FF0000)
+#define MPI_SCSI_DEVICE_PHYS_DISK_NUM_SHIFT         (16)
 
 #define MPI_FC_PORT_PGAD_PORT_MASK                  (0xF0000000)
 #define MPI_FC_PORT_PGAD_PORT_SHIFT                 (28)
@@ -159,17 +173,17 @@ typedef union _CONFIG_PAGE_HEADER_UNION
 /****************************************************************************/
 typedef struct _MSG_CONFIG
 {
-    U8                      Action;
-    U8                      Reserved;
-    U8                      ChainOffset;
-    U8                      Function;
-    U8                      Reserved1[3];
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U8                      Reserved2[8];
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     PageAddress;
-    SGE_IO_UNION            PageBufferSGE;
+    U8                      Action;                     /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Reserved1[3];               /* 04h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U8                      Reserved2[8];               /* 0Ch */
+   fCONFIG_PAGE_HEADER      Header;                     /* 14h */
+    U32                     PageAddress;                /* 18h */
+    SGE_IO_UNION            PageBufferSGE;              /* 1Ch */
 } MSG_CONFIG, MPI_POINTER PTR_MSG_CONFIG,
   Config_t, MPI_POINTER pConfig_t;
 
@@ -178,12 +192,9 @@ typedef struct _MSG_CONFIG
 /*  Action field values                                                     */
 /****************************************************************************/
 #define MPI_CONFIG_ACTION_PAGE_HEADER               (0x00)
-/*#define MPI_CONFIG_ACTION_PAGE_READ                 (0x01) *//* obsolete */
 #define MPI_CONFIG_ACTION_PAGE_READ_CURRENT         (0x01)
-/*#define MPI_CONFIG_ACTION_PAGE_WRITE                (0x02) *//* obsolete */
 #define MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT        (0x02)
 #define MPI_CONFIG_ACTION_PAGE_DEFAULT              (0x03)
-/*#define MPI_CONFIG_ACTION_PAGE_WRITE_COMMIT         (0x04) */ /* obsolete */
 #define MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM          (0x04)
 #define MPI_CONFIG_ACTION_PAGE_READ_DEFAULT         (0x05)
 #define MPI_CONFIG_ACTION_PAGE_READ_NVRAM           (0x06)
@@ -192,17 +203,17 @@ typedef struct _MSG_CONFIG
 /* Config Reply Message */
 typedef struct _MSG_CONFIG_REPLY
 {
-    U8                      Action;
-    U8                      Reserved;
-    U8                      MsgLength;
-    U8                      Function;
-    U8                      Reserved1[3];
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U8                      Reserved2[2];
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
-   fCONFIG_PAGE_HEADER      Header;
+    U8                      Action;                     /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Reserved1[3];               /* 04h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U8                      Reserved2[2];               /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
+   fCONFIG_PAGE_HEADER      Header;                     /* 14h */
 } MSG_CONFIG_REPLY, MPI_POINTER PTR_MSG_CONFIG_REPLY,
   ConfigReply_t, MPI_POINTER pConfigReply_t;
 
@@ -226,12 +237,12 @@ typedef struct _MSG_CONFIG_REPLY
 
 typedef struct _CONFIG_PAGE_MANUFACTURING_0
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U8                      ChipName[16];
-    U8                      ChipRevision[8];
-    U8                      BoardName[16];
-    U8                      BoardAssembly[16];
-    U8                      BoardTracerNumber[16];
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U8                      ChipName[16];               /* 04h */
+    U8                      ChipRevision[8];            /* 14h */
+    U8                      BoardName[16];              /* 1Ch */
+    U8                      BoardAssembly[16];          /* 2Ch */
+    U8                      BoardTracerNumber[16];      /* 3Ch */
 
 } fCONFIG_PAGE_MANUFACTURING_0, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_0,
   ManufacturingPage0_t, MPI_POINTER pManufacturingPage0_t;
@@ -241,8 +252,8 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_0
 
 typedef struct _CONFIG_PAGE_MANUFACTURING_1
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U8                      VPD[256];
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U8                      VPD[256];                   /* 04h */
 } fCONFIG_PAGE_MANUFACTURING_1, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_1,
   ManufacturingPage1_t, MPI_POINTER pManufacturingPage1_t;
 
@@ -251,18 +262,18 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_1
 
 typedef struct _MPI_CHIP_REVISION_ID
 {
-    U16 DeviceID;
-    U8  PCIRevisionID;
-    U8  Reserved;
+    U16 DeviceID;                                       /* 00h */
+    U8  PCIRevisionID;                                  /* 02h */
+    U8  Reserved;                                       /* 03h */
 } MPI_CHIP_REVISION_ID, MPI_POINTER PTR_MPI_CHIP_REVISION_ID,
   MpiChipRevisionId_t, MPI_POINTER pMpiChipRevisionId_t;
 
 
 typedef struct _CONFIG_PAGE_MANUFACTURING_2
 {
-   fCONFIG_PAGE_HEADER                  Header;
-    MPI_CHIP_REVISION_ID                ChipId;
-    U32                                 HwSettings[1];
+   fCONFIG_PAGE_HEADER                  Header;         /* 00h */
+    MPI_CHIP_REVISION_ID                ChipId;         /* 04h */
+    U32                                 HwSettings[1];  /* 08h */
 } fCONFIG_PAGE_MANUFACTURING_2, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_2,
   ManufacturingPage2_t, MPI_POINTER pManufacturingPage2_t;
 
@@ -271,9 +282,9 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_2
 
 typedef struct _CONFIG_PAGE_MANUFACTURING_3
 {
-   fCONFIG_PAGE_HEADER                  Header;
-    MPI_CHIP_REVISION_ID                ChipId;
-    U32                                 Info[1];
+   fCONFIG_PAGE_HEADER                  Header;         /* 00h */
+    MPI_CHIP_REVISION_ID                ChipId;         /* 04h */
+    U32                                 Info[1];        /* 08h */
 } fCONFIG_PAGE_MANUFACTURING_3, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_3,
   ManufacturingPage3_t, MPI_POINTER pManufacturingPage3_t;
 
@@ -286,8 +297,8 @@ typedef struct _CONFIG_PAGE_MANUFACTURING_3
 
 typedef struct _CONFIG_PAGE_IO_UNIT_0
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U64                     UniqueValue;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U64                     UniqueValue;                /* 04h */
 } fCONFIG_PAGE_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_0,
   IOUnitPage0_t, MPI_POINTER pIOUnitPage0_t;
 
@@ -296,8 +307,8 @@ typedef struct _CONFIG_PAGE_IO_UNIT_0
 
 typedef struct _CONFIG_PAGE_IO_UNIT_1
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     Flags;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     Flags;                      /* 04h */
 } fCONFIG_PAGE_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_1,
   IOUnitPage1_t, MPI_POINTER pIOUnitPage1_t;
 
@@ -313,9 +324,9 @@ typedef struct _CONFIG_PAGE_IO_UNIT_1
 
 typedef struct _MPI_ADAPTER_INFO
 {
-    U8      PciBusNumber;
-    U8      PciDeviceAndFunctionNumber;
-    U16     AdapterFlags;
+    U8      PciBusNumber;                               /* 00h */
+    U8      PciDeviceAndFunctionNumber;                 /* 01h */
+    U16     AdapterFlags;                               /* 02h */
 } MPI_ADAPTER_INFO, MPI_POINTER PTR_MPI_ADAPTER_INFO,
   MpiAdapterInfo_t, MPI_POINTER pMpiAdapterInfo_t;
 
@@ -324,10 +335,10 @@ typedef struct _MPI_ADAPTER_INFO
 
 typedef struct _CONFIG_PAGE_IO_UNIT_2
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     Flags;
-    U32                     BiosVersion;
-    MPI_ADAPTER_INFO        AdapterOrder[4];
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     Flags;                      /* 04h */
+    U32                     BiosVersion;                /* 08h */
+    MPI_ADAPTER_INFO        AdapterOrder[4];            /* 0Ch */
 } fCONFIG_PAGE_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_2,
   IOUnitPage2_t, MPI_POINTER pIOUnitPage2_t;
 
@@ -340,34 +351,53 @@ typedef struct _CONFIG_PAGE_IO_UNIT_2
 #define MPI_IOUNITPAGE2_FLAGS_DONT_HOOK_INT_40          (0x00000010)
 
 
+typedef struct _CONFIG_PAGE_IO_UNIT_3
+{
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     VolumeSettings;             /* 04h */
+    U8                      InfoOffset0;                /* 08h */
+    U8                      InfoSize0;                  /* 09h */
+    U8                      InfoOffset1;                /* 0Ah */
+    U8                      InfoSize1;                  /* 0Bh */
+    U8                      InquirySize;                /* 0Ch */
+    U8                      Reserved;                   /* 0Dh */
+    U16                     Reserved2;                  /* 0Eh */
+    U8                      InquiryData[56];            /* 10h */
+} fCONFIG_PAGE_IO_UNIT_3, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_3,
+  IOUnitPage3_t, MPI_POINTER pIOUnitPage3_t;
+
+#define MPI_IOUNITPAGE3_PAGEVERSION                     (0x00)
+
+
 /****************************************************************************/
 /*  IOC Config Pages                                                        */
 /****************************************************************************/
 
 typedef struct _CONFIG_PAGE_IOC_0
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     TotalNVStore;
-    U32                     FreeNVStore;
-    U16                     VendorID;
-    U16                     DeviceID;
-    U8                      RevisionID;
-    U8                      Reserved[3];
-    U32                     ClassCode;
-    U16                     SubsystemVendorID;
-    U16                     SubsystemID;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     TotalNVStore;               /* 04h */
+    U32                     FreeNVStore;                /* 08h */
+    U16                     VendorID;                   /* 0Ch */
+    U16                     DeviceID;                   /* 0Eh */
+    U8                      RevisionID;                 /* 10h */
+    U8                      Reserved[3];                /* 11h */
+    U32                     ClassCode;                  /* 14h */
+    U16                     SubsystemVendorID;          /* 18h */
+    U16                     SubsystemID;                /* 1Ah */
 } fCONFIG_PAGE_IOC_0, MPI_POINTER PTR_CONFIG_PAGE_IOC_0,
   IOCPage0_t, MPI_POINTER pIOCPage0_t;
 
 #define MPI_IOCPAGE0_PAGEVERSION                        (0x01)
 
+
 typedef struct _CONFIG_PAGE_IOC_1
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     Flags;
-    U32                     CoalescingTimeout;
-    U8                      CoalescingDepth;
-    U8                      Reserved[3];
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     Flags;                      /* 04h */
+    U32                     CoalescingTimeout;          /* 08h */
+    U8                      CoalescingDepth;            /* 0Ch */
+    U8                      Reserved[3];                /* 0Dh */
 } fCONFIG_PAGE_IOC_1, MPI_POINTER PTR_CONFIG_PAGE_IOC_1,
   IOCPage1_t, MPI_POINTER pIOCPage1_t;
 
@@ -375,26 +405,27 @@ typedef struct _CONFIG_PAGE_IOC_1
 
 #define MPI_IOCPAGE1_REPLY_COALESCING                   (0x00000001)
 
+
 typedef struct _CONFIG_PAGE_IOC_2_RAID_VOL
 {
-    U8                      VolumeTargetID;
-    U8                      VolumeBus;
-    U16                     Reserved;
-    U8                      VolumeVersionMinor;
-    U8                      VolumeVersionMajor;
-    U8                      VolumeRaidType;
-    U8                      Reserved1;
+    U8                      VolumeTargetID;             /* 00h */
+    U8                      VolumeBus;                  /* 01h */
+    U16                     Reserved;                   /* 02h */
+    U8                      VolumeVersionMinor;         /* 04h */
+    U8                      VolumeVersionMajor;         /* 05h */
+    U8                      VolumeRaidType;             /* 06h */
+    U8                      Reserved1;                  /* 07h */
 } fCONFIG_PAGE_IOC_2_RAID_VOL, MPI_POINTER PTR_CONFIG_PAGE_IOC_2_RAID_VOL,
   ConfigPageIoc2RaidVol_t, MPI_POINTER pConfigPageIoc2RaidVol_t;
 
 typedef struct _CONFIG_PAGE_IOC_2
 {
-   fCONFIG_PAGE_HEADER          Header;
-    U32                         CapabilitiesFlags;
-    U8                          NumActiveVolumes;
-    U8                          MaxVolumes;
-    U16                         Reserved;
-   fCONFIG_PAGE_IOC_2_RAID_VOL  RaidVolume[1];
+   fCONFIG_PAGE_HEADER          Header;                 /* 00h */
+    U32                         CapabilitiesFlags;      /* 04h */
+    U8                          NumActiveVolumes;       /* 08h */
+    U8                          MaxVolumes;             /* 09h */
+    U16                         Reserved;               /* 0Ah */
+   fCONFIG_PAGE_IOC_2_RAID_VOL  RaidVolume[1];          /* 0Ch */
 } fCONFIG_PAGE_IOC_2, MPI_POINTER PTR_CONFIG_PAGE_IOC_2,
   IOCPage2_t, MPI_POINTER pIOCPage2_t;
 
@@ -423,9 +454,9 @@ typedef struct _CONFIG_PAGE_IOC_2
 
 typedef struct _CONFIG_PAGE_SCSI_PORT_0
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     Capabilities;
-    U32                     PhysicalInterface;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     Capabilities;               /* 04h */
+    U32                     PhysicalInterface;          /* 08h */
 } fCONFIG_PAGE_SCSI_PORT_0, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_0,
   SCSIPortPage0_t, MPI_POINTER pSCSIPortPage0_t;
 
@@ -445,10 +476,11 @@ typedef struct _CONFIG_PAGE_SCSI_PORT_0
 #define MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE                 (0x02)
 #define MPI_SCSIPORTPAGE0_PHY_SIGNAL_LVD                (0x03)
 
+
 typedef struct _CONFIG_PAGE_SCSI_PORT_1
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     Configuration;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     Configuration;              /* 04h */
 } fCONFIG_PAGE_SCSI_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_1,
   SCSIPortPage1_t, MPI_POINTER pSCSIPortPage1_t;
 
@@ -457,20 +489,21 @@ typedef struct _CONFIG_PAGE_SCSI_PORT_1
 #define MPI_SCSIPORTPAGE1_CFG_PORT_SCSI_ID_MASK         (0x000000FF)
 #define MPI_SCSIPORTPAGE1_CFG_PORT_RESPONSE_ID_MASK     (0xFFFF0000)
 
+
 typedef struct _MPI_DEVICE_INFO
 {
-    U8      Timeout;
-    U8      SyncFactor;
-    U16     DeviceFlags;
+    U8      Timeout;                                    /* 00h */
+    U8      SyncFactor;                                 /* 01h */
+    U16     DeviceFlags;                                /* 02h */
 } MPI_DEVICE_INFO, MPI_POINTER PTR_MPI_DEVICE_INFO,
   MpiDeviceInfo_t, MPI_POINTER pMpiDeviceInfo_t;
 
 typedef struct _CONFIG_PAGE_SCSI_PORT_2
 {
-   fCONFIG_PAGE_HEADER  Header;
-    U32                 PortFlags;
-    U32                 PortSettings;
-    MPI_DEVICE_INFO     DeviceSettings[16];
+   fCONFIG_PAGE_HEADER  Header;                         /* 00h */
+    U32                 PortFlags;                      /* 04h */
+    U32                 PortSettings;                   /* 08h */
+    MPI_DEVICE_INFO     DeviceSettings[16];             /* 0Ch */
 } fCONFIG_PAGE_SCSI_PORT_2, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_2,
   SCSIPortPage2_t, MPI_POINTER pSCSIPortPage2_t;
 
@@ -492,15 +525,15 @@ typedef struct _CONFIG_PAGE_SCSI_PORT_2
 #define MPI_SCSIPORTPAGE2_PORT_SPINUP_DELAY_MASK            (0x00000F00)
 #define MPI_SCSIPORTPAGE2_PORT_MASK_NEGO_MASTER_SETTINGS    (0x00003000)
 #define MPI_SCSIPORTPAGE2_PORT_NEGO_MASTER_SETTINGS         (0x00000000)
-#define MPI_SCSIPORTPAGE2_PORT_NONE_MASTER_SETTINGS         (0x00000001)
-#define MPI_SCSIPORTPAGE2_PORT_ALL_MASTER_SETTINGS          (0x00000003)
+#define MPI_SCSIPORTPAGE2_PORT_NONE_MASTER_SETTINGS         (0x00001000)
+#define MPI_SCSIPORTPAGE2_PORT_ALL_MASTER_SETTINGS          (0x00003000)
 
-#define MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE          (0x00000001)
-#define MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE             (0x00000002)
-#define MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE            (0x00000004)
-#define MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE           (0x00000008)
-#define MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE               (0x00000010)
-#define MPI_SCSIPORTPAGE2_DEVICE_BOOT_CHOICE                (0x00000020)
+#define MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE          (0x0001)
+#define MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE             (0x0002)
+#define MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE            (0x0004)
+#define MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE           (0x0008)
+#define MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE               (0x0010)
+#define MPI_SCSIPORTPAGE2_DEVICE_BOOT_CHOICE                (0x0020)
 
 
 /****************************************************************************/
@@ -509,9 +542,9 @@ typedef struct _CONFIG_PAGE_SCSI_PORT_2
 
 typedef struct _CONFIG_PAGE_SCSI_DEVICE_0
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     NegotiatedParameters;
-    U32                     Information;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     NegotiatedParameters;       /* 04h */
+    U32                     Information;                /* 08h */
 } fCONFIG_PAGE_SCSI_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_SCSI_DEVICE_0,
   SCSIDevicePage0_t, MPI_POINTER pSCSIDevicePage0_t;
 
@@ -528,16 +561,17 @@ typedef struct _CONFIG_PAGE_SCSI_DEVICE_0
 
 #define MPI_SCSIDEVPAGE0_INFO_PARAMS_NEGOTIATED         (0x00000001)
 
+
 typedef struct _CONFIG_PAGE_SCSI_DEVICE_1
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     RequestedParameters;
-    U32                     DomainValidation;
-    U32                     Configuration;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     RequestedParameters;        /* 04h */
+    U32                     Reserved;                   /* 08h */
+    U32                     Configuration;              /* 0Ch */
 } fCONFIG_PAGE_SCSI_DEVICE_1, MPI_POINTER PTR_CONFIG_PAGE_SCSI_DEVICE_1,
   SCSIDevicePage1_t, MPI_POINTER pSCSIDevicePage1_t;
 
-#define MPI_SCSIDEVPAGE1_PAGEVERSION                    (0x01)
+#define MPI_SCSIDEVPAGE1_PAGEVERSION                    (0x02)
 
 #define MPI_SCSIDEVPAGE1_RP_IU                          (0x00000001)
 #define MPI_SCSIDEVPAGE1_RP_DT                          (0x00000002)
@@ -553,29 +587,71 @@ typedef struct _CONFIG_PAGE_SCSI_DEVICE_1
 
 #define MPI_SCSIDEVPAGE1_CONF_PPR_ALLOWED               (0x00000001)
 
+
+typedef struct _CONFIG_PAGE_SCSI_DEVICE_2
+{
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     DomainValidation;           /* 04h */
+    U32                     ParityPipeSelect;           /* 08h */
+    U32                     DataPipeSelect;             /* 0Ch */
+} fCONFIG_PAGE_SCSI_DEVICE_2, MPI_POINTER PTR_CONFIG_PAGE_SCSI_DEVICE_2,
+  SCSIDevicePage2_t, MPI_POINTER pSCSIDevicePage2_t;
+
+#define MPI_SCSIDEVPAGE2_PAGEVERSION                    (0x00)
+
+#define MPI_SCSIDEVPAGE2_DV_ISI_ENABLE                  (0x00000010)
+#define MPI_SCSIDEVPAGE2_DV_SECONDARY_DRIVER_ENABLE     (0x00000020)
+#define MPI_SCSIDEVPAGE2_DV_SLEW_RATE_CTRL              (0x00000380)
+#define MPI_SCSIDEVPAGE2_DV_PRIM_DRIVE_STR_CTRL         (0x00001C00)
+#define MPI_SCSIDEVPAGE2_DV_SECOND_DRIVE_STR_CTRL       (0x0000E000)
+#define MPI_SCSIDEVPAGE2_DV_XCLKH_ST                    (0x10000000)
+#define MPI_SCSIDEVPAGE2_DV_XCLKS_ST                    (0x20000000)
+#define MPI_SCSIDEVPAGE2_DV_XCLKH_DT                    (0x40000000)
+#define MPI_SCSIDEVPAGE2_DV_XCLKS_DT                    (0x80000000)
+
+#define MPI_SCSIDEVPAGE2_PPS_PPS_MASK                   (0x00000003)
+
+#define MPI_SCSIDEVPAGE2_DPS_BIT_0_PL_SELECT_MASK       (0x00000003)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_1_PL_SELECT_MASK       (0x0000000C)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_2_PL_SELECT_MASK       (0x00000030)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_3_PL_SELECT_MASK       (0x000000C0)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_4_PL_SELECT_MASK       (0x00000300)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_5_PL_SELECT_MASK       (0x00000C00)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_6_PL_SELECT_MASK       (0x00003000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_7_PL_SELECT_MASK       (0x0000C000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_8_PL_SELECT_MASK       (0x00030000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_9_PL_SELECT_MASK       (0x000C0000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_10_PL_SELECT_MASK      (0x00300000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_11_PL_SELECT_MASK      (0x00C00000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_12_PL_SELECT_MASK      (0x03000000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_13_PL_SELECT_MASK      (0x0C000000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_14_PL_SELECT_MASK      (0x30000000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_15_PL_SELECT_MASK      (0xC0000000)
+
+
 /****************************************************************************/
 /*  FC Port Config Pages                                                    */
 /****************************************************************************/
 
 typedef struct _CONFIG_PAGE_FC_PORT_0
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     Flags;
-    U8                      MPIPortNumber;
-    U8                      LinkType;
-    U8                      PortState;
-    U8                      Reserved;
-    U32                     PortIdentifier;
-    U64                     WWNN;
-    U64                     WWPN;
-    U32                     SupportedServiceClass;
-    U32                     SupportedSpeeds;
-    U32                     CurrentSpeed;
-    U32                     MaxFrameSize;
-    U64                     FabricWWNN;
-    U64                     FabricWWPN;
-    U32                     DiscoveredPortsCount;
-    U32                     MaxInitiators;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     Flags;                      /* 04h */
+    U8                      MPIPortNumber;              /* 08h */
+    U8                      LinkType;                   /* 09h */
+    U8                      PortState;                  /* 0Ah */
+    U8                      Reserved;                   /* 0Bh */
+    U32                     PortIdentifier;             /* 0Ch */
+    U64                     WWNN;                       /* 10h */
+    U64                     WWPN;                       /* 18h */
+    U32                     SupportedServiceClass;      /* 20h */
+    U32                     SupportedSpeeds;            /* 24h */
+    U32                     CurrentSpeed;               /* 28h */
+    U32                     MaxFrameSize;               /* 2Ch */
+    U64                     FabricWWNN;                 /* 30h */
+    U64                     FabricWWPN;                 /* 38h */
+    U32                     DiscoveredPortsCount;       /* 40h */
+    U32                     MaxInitiators;              /* 44h */
 } fCONFIG_PAGE_FC_PORT_0, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_0,
   FCPortPage0_t, MPI_POINTER pFCPortPage0_t;
 
@@ -591,12 +667,12 @@ typedef struct _CONFIG_PAGE_FC_PORT_0
 #define MPI_FCPORTPAGE0_FLAGS_ALIAS_WWN_SUPPORTED       (0x00000020)
 #define MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID          (0x00000030)
 
-#define MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK          (0x00000700)
-#define MPI_FCPORTPAGE0_FLAGS_ATTACH_POINT_TO_POINT     (0x00000000)
-#define MPI_FCPORTPAGE0_FLAGS_ATTACH_PRIVATE_LOOP       (0x00000100)
-#define MPI_FCPORTPAGE0_FLAGS_ATTACH_FABRIC_DIRECT      (0x00000200)
-#define MPI_FCPORTPAGE0_FLAGS_ATTACH_PUBLIC_LOOP        (0x00000300)
-#define MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT            (0x00000700)
+#define MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK          (0x00000F00)
+#define MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT            (0x00000000)
+#define MPI_FCPORTPAGE0_FLAGS_ATTACH_POINT_TO_POINT     (0x00000100)
+#define MPI_FCPORTPAGE0_FLAGS_ATTACH_PRIVATE_LOOP       (0x00000200)
+#define MPI_FCPORTPAGE0_FLAGS_ATTACH_FABRIC_DIRECT      (0x00000400)
+#define MPI_FCPORTPAGE0_FLAGS_ATTACH_PUBLIC_LOOP        (0x00000800)
 
 #define MPI_FCPORTPAGE0_LTYPE_RESERVED                  (0x00)
 #define MPI_FCPORTPAGE0_LTYPE_OTHER                     (0x01)
@@ -639,14 +715,14 @@ typedef struct _CONFIG_PAGE_FC_PORT_0
 
 typedef struct _CONFIG_PAGE_FC_PORT_1
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     Flags;
-    U64                     NoSEEPROMWWNN;
-    U64                     NoSEEPROMWWPN;
-    U8                      HardALPA;
-    U8                      LinkConfig;
-    U8                      TopologyConfig;
-    U8                      Reserved;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     Flags;                      /* 04h */
+    U64                     NoSEEPROMWWNN;              /* 08h */
+    U64                     NoSEEPROMWWPN;              /* 10h */
+    U8                      HardALPA;                   /* 18h */
+    U8                      LinkConfig;                 /* 19h */
+    U8                      TopologyConfig;             /* 1Ah */
+    U8                      Reserved;                   /* 1Bh */
 } fCONFIG_PAGE_FC_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_1,
   FCPortPage1_t, MPI_POINTER pFCPortPage1_t;
 
@@ -679,23 +755,36 @@ typedef struct _CONFIG_PAGE_FC_PORT_1
 
 typedef struct _CONFIG_PAGE_FC_PORT_2
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U8                      NumberActive;
-    U8                      ALPA[126];
-    U8                      Reserved;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U8                      NumberActive;               /* 04h */
+    U8                      ALPA[126];                  /* 05h */
+    U8                      Reserved;                   /* 83h */
 } fCONFIG_PAGE_FC_PORT_2, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_2,
   FCPortPage2_t, MPI_POINTER pFCPortPage2_t;
 
 #define MPI_FCPORTPAGE2_PAGEVERSION                     (0x00)
 
 
+typedef struct _WWN_FORMAT
+{
+    U64                     WWNN;                       /* 00h */
+    U64                     WWPN;                       /* 08h */
+} WWN_FORMAT, MPI_POINTER PTR_WWN_FORMAT,
+  WWNFormat, MPI_POINTER pWWNFormat;
+
+typedef union _FC_PORT_PERSISTENT_PHYSICAL_ID
+{
+    WWN_FORMAT              WWN;
+    U32                     Did;
+} FC_PORT_PERSISTENT_PHYSICAL_ID, MPI_POINTER PTR_FC_PORT_PERSISTENT_PHYSICAL_ID,
+  PersistentPhysicalId_t, MPI_POINTER pPersistentPhysicalId_t;
+
 typedef struct _FC_PORT_PERSISTENT
 {
-    U64                     WWNN;
-    U64                     WWPN;
-    U8                      TargetID;
-    U8                      Bus;
-    U16                     Flags;
+    FC_PORT_PERSISTENT_PHYSICAL_ID  PhysicalIdentifier; /* 00h */
+    U8                              TargetID;           /* 10h */
+    U8                              Bus;                /* 11h */
+    U16                             Flags;              /* 12h */
 } FC_PORT_PERSISTENT, MPI_POINTER PTR_FC_PORT_PERSISTENT,
   PersistentData_t, MPI_POINTER pPersistentData_t;
 
@@ -704,22 +793,23 @@ typedef struct _FC_PORT_PERSISTENT
 #define MPI_PERSISTENT_FLAGS_SCAN_ID                    (0x0002)
 #define MPI_PERSISTENT_FLAGS_SCAN_LUNS                  (0x0004)
 #define MPI_PERSISTENT_FLAGS_BOOT_DEVICE                (0x0008)
+#define MPI_PERSISTENT_FLAGS_BY_DID                     (0x0080)
 
 typedef struct _CONFIG_PAGE_FC_PORT_3
 {
-   fCONFIG_PAGE_HEADER      Header;
-    FC_PORT_PERSISTENT      Entry[1];
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    FC_PORT_PERSISTENT      Entry[1];                   /* 04h */
 } fCONFIG_PAGE_FC_PORT_3, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_3,
   FCPortPage3_t, MPI_POINTER pFCPortPage3_t;
 
-#define MPI_FCPORTPAGE3_PAGEVERSION                     (0x00)
+#define MPI_FCPORTPAGE3_PAGEVERSION                     (0x01)
 
 
 typedef struct _CONFIG_PAGE_FC_PORT_4
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     PortFlags;
-    U32                     PortSettings;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     PortFlags;                  /* 04h */
+    U32                     PortSettings;               /* 08h */
 } fCONFIG_PAGE_FC_PORT_4, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_4,
   FCPortPage4_t, MPI_POINTER pFCPortPage4_t;
 
@@ -738,18 +828,18 @@ typedef struct _CONFIG_PAGE_FC_PORT_4
 
 typedef struct _CONFIG_PAGE_FC_PORT_5_ALIAS_INFO
 {
-    U8      Flags;
-    U8      AliasAlpa;
-    U16     Reserved;
-    U64     AliasWWNN;
-    U64     AliasWWPN;
+    U8      Flags;                                      /* 00h */
+    U8      AliasAlpa;                                  /* 01h */
+    U16     Reserved;                                   /* 02h */
+    U64     AliasWWNN;                                  /* 04h */
+    U64     AliasWWPN;                                  /* 0Ch */
 } fCONFIG_PAGE_FC_PORT_5_ALIAS_INFO, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_5_ALIAS_INFO,
   FcPortPage5AliasInfo_t, MPI_POINTER pFcPortPage5AliasInfo_t;
 
 typedef struct _CONFIG_PAGE_FC_PORT_5
 {
-   fCONFIG_PAGE_HEADER                  Header;
-   fCONFIG_PAGE_FC_PORT_5_ALIAS_INFO    AliasInfo[1];
+   fCONFIG_PAGE_HEADER                  Header;         /* 00h */
+   fCONFIG_PAGE_FC_PORT_5_ALIAS_INFO    AliasInfo[1];   /* 04h */
 } fCONFIG_PAGE_FC_PORT_5, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_5,
   FCPortPage5_t, MPI_POINTER pFCPortPage5_t;
 
@@ -761,24 +851,24 @@ typedef struct _CONFIG_PAGE_FC_PORT_5
 
 typedef struct _CONFIG_PAGE_FC_PORT_6
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     Reserved;
-    U64                     TimeSinceReset;
-    U64                     TxFrames;
-    U64                     RxFrames;
-    U64                     TxWords;
-    U64                     RxWords;
-    U64                     LipCount;
-    U64                     NosCount;
-    U64                     ErrorFrames;
-    U64                     DumpedFrames;
-    U64                     LinkFailureCount;
-    U64                     LossOfSyncCount;
-    U64                     LossOfSignalCount;
-    U64                     PrimativeSeqErrCount;
-    U64                     InvalidTxWordCount;
-    U64                     InvalidCrcCount;
-    U64                     FcpInitiatorIoCount;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     Reserved;                   /* 04h */
+    U64                     TimeSinceReset;             /* 08h */
+    U64                     TxFrames;                   /* 10h */
+    U64                     RxFrames;                   /* 18h */
+    U64                     TxWords;                    /* 20h */
+    U64                     RxWords;                    /* 28h */
+    U64                     LipCount;                   /* 30h */
+    U64                     NosCount;                   /* 38h */
+    U64                     ErrorFrames;                /* 40h */
+    U64                     DumpedFrames;               /* 48h */
+    U64                     LinkFailureCount;           /* 50h */
+    U64                     LossOfSyncCount;            /* 58h */
+    U64                     LossOfSignalCount;          /* 60h */
+    U64                     PrimativeSeqErrCount;       /* 68h */
+    U64                     InvalidTxWordCount;         /* 70h */
+    U64                     InvalidCrcCount;            /* 78h */
+    U64                     FcpInitiatorIoCount;        /* 80h */
 } fCONFIG_PAGE_FC_PORT_6, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_6,
   FCPortPage6_t, MPI_POINTER pFCPortPage6_t;
 
@@ -787,35 +877,65 @@ typedef struct _CONFIG_PAGE_FC_PORT_6
 
 typedef struct _CONFIG_PAGE_FC_PORT_7
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U32                     Reserved;
-    U8                      PortSymbolicName[256];
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     Reserved;                   /* 04h */
+    U8                      PortSymbolicName[256];      /* 08h */
 } fCONFIG_PAGE_FC_PORT_7, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_7,
   FCPortPage7_t, MPI_POINTER pFCPortPage7_t;
 
 #define MPI_FCPORTPAGE7_PAGEVERSION                     (0x00)
 
 
+typedef struct _CONFIG_PAGE_FC_PORT_8
+{
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     BitVector[8];               /* 04h */
+} fCONFIG_PAGE_FC_PORT_8, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_8,
+  FCPortPage8_t, MPI_POINTER pFCPortPage8_t;
+
+#define MPI_FCPORTPAGE8_PAGEVERSION                     (0x00)
+
+
+typedef struct _CONFIG_PAGE_FC_PORT_9
+{
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U32                     Reserved;                   /* 04h */
+    U64                     GlobalWWPN;                 /* 08h */
+    U64                     GlobalWWNN;                 /* 10h */
+    U32                     UnitType;                   /* 18h */
+    U32                     PhysicalPortNumber;         /* 1Ch */
+    U32                     NumAttachedNodes;           /* 20h */
+    U16                     IPVersion;                  /* 24h */
+    U16                     UDPPortNumber;              /* 26h */
+    U8                      IPAddress[16];              /* 28h */
+    U16                     Reserved1;                  /* 38h */
+    U16                     TopologyDiscoveryFlags;     /* 3Ah */
+} fCONFIG_PAGE_FC_PORT_9, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_9,
+  FCPortPage9_t, MPI_POINTER pFCPortPage9_t;
+
+#define MPI_FCPORTPAGE9_PAGEVERSION                     (0x00)
+
+
 /****************************************************************************/
 /*  FC Device Config Pages                                                  */
 /****************************************************************************/
 
 typedef struct _CONFIG_PAGE_FC_DEVICE_0
 {
-   fCONFIG_PAGE_HEADER      Header;
-    U64                     WWNN;
-    U64                     WWPN;
-    U32                     PortIdentifier;
-    U8                      Protocol;
-    U8                      Flags;
-    U16                     BBCredit;
-    U16                     MaxRxFrameSize;
-    U8                      Reserved1;
-    U8                      PortNumber;
-    U8                      FcPhLowestVersion;
-    U8                      FcPhHighestVersion;
-    U8                      CurrentTargetID;
-    U8                      CurrentBus;
+   fCONFIG_PAGE_HEADER      Header;                     /* 00h */
+    U64                     WWNN;                       /* 04h */
+    U64                     WWPN;                       /* 0Ch */
+    U32                     PortIdentifier;             /* 14h */
+    U8                      Protocol;                   /* 18h */
+    U8                      Flags;                      /* 19h */
+    U16                     BBCredit;                   /* 1Ah */
+    U16                     MaxRxFrameSize;             /* 1Ch */
+    U8                      Reserved1;                  /* 1Eh */
+    U8                      PortNumber;                 /* 1Fh */
+    U8                      FcPhLowestVersion;          /* 20h */
+    U8                      FcPhHighestVersion;         /* 21h */
+    U8                      CurrentTargetID;            /* 22h */
+    U8                      CurrentBus;                 /* 23h */
 } fCONFIG_PAGE_FC_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_FC_DEVICE_0,
   FCDevicePage0_t, MPI_POINTER pFCDevicePage0_t;
 
@@ -841,70 +961,75 @@ typedef struct _CONFIG_PAGE_FC_DEVICE_0
 /*  RAID Volume Config Pages                                                  */
 /****************************************************************************/
 
-typedef struct _RAIDVOL2_EM_PHYS_ID
-{
-    U8                      TargetID;
-    U8                      Bus;
-    U8                      IocNumber;
-    U8                      PhysDiskNumber;
-    U8                      Reserved[8];
-    U8                      PhysicalDiskIdentifier[16];
-    U8                      ProductId[16];
-    U8                      InfoOffset0;
-    U8                      InfoSize0;
-    U8                      InfoOffset1;
-    U8                      InfoSize1;
-    U8                      Info[32];
-} RAIDVOL2_EM_PHYS_ID, MPI_POINTER PTR_RAIDVOL2_EM_PHYS_ID,
-  RaidVol2EmPhysicalID_t, MPI_POINTER pRaidVol2EmPhysicalID_t;
-
-typedef struct _RAIDVOL2_EM_DISK_INFO
-{
-    U32                     DiskStatus;
-    U32                     DeviceSettings;
-    U16                     ErrorCount;
-    U16                     Reserved;
-    U8                      ErrorCdbByte;
-    U8                      ErrorSenseKey;
-    U8                      ErrorASC;
-    U8                      ErrorASCQ;
-    U16                     SmartCount;
-    U8                      SmartASC;
-    U8                      SmartASCQ;
-} RAIDVOL2_EM_DISK_INFO, MPI_POINTER PTR_RAIDVOL2_EM_DISK_INFO,
-  RaidVol2EmDiskInfo_t, MPI_POINTER pRaidVol2EmDiskInfo_t;
-
-/* RAID Volume 2 EM Physical Disk DiskStatus flags */
-
-#define MPI_RAIDVOLPAGE2_PHYS_DISK_PRIMARY              (0x00000001)
-#define MPI_RAIDVOLPAGE2_PHYS_DISK_SECONDARY            (0x00000002)
-#define MPI_RAIDVOLPAGE2_PHYS_DISK_HOT_SPARE            (0x00000004)
-#define MPI_RAIDVOLPAGE2_PHYS_DISK_OUT_OF_SYNC          (0x00000008)
-#define MPI_RAIDVOLPAGE2_PHYS_DISK_OFFLINE              (0x00000010)
-#define MPI_RAIDVOLPAGE2_PHYS_DISK_NOT_RESPONDING       (0x00000020)
-
-typedef struct _RAIDVOL2_EM_PHYSICAL_DISK
-{
-    RAIDVOL2_EM_PHYS_ID     Id;
-    RAIDVOL2_EM_DISK_INFO   Info;
-} RAIDVOL2_EM_PHYSICAL_DISK, MPI_POINTER PTR_RAIDVOL2_EM_PHYSICAL_DISK,
-  RaidVol2EmPhysicalDisk_t, MPI_POINTER pRaidVol2EmPhysicalDisk_t;
+typedef struct _RAIDVOL2_IM_PHYS_ID
+{
+    U8                      TargetID;                   /* 00h */
+    U8                      Bus;                        /* 01h */
+    U8                      IocNumber;                  /* 02h */
+    U8                      PhysDiskNumber;             /* 03h */
+    U8                      Reserved[8];                /* 04h */
+    U8                      PhysicalDiskIdentifier[16]; /* 0Ch */
+    U8                      VendorId[8];                /* 1Ch */
+    U8                      ProductId[16];              /* 24h */
+    U8                      ProductRevLevel[4];         /* 34h */
+    U32                     Reserved1;                  /* 38h */
+    U8                      Info[32];                   /* 3Ch */
+} RAIDVOL2_IM_PHYS_ID, MPI_POINTER PTR_RAIDVOL2_IM_PHYS_ID,
+  RaidVol2ImPhysicalID_t, MPI_POINTER pRaidVol2ImPhysicalID_t;
+
+typedef struct _RAIDVOL2_IM_DISK_INFO
+{
+    U32                     DiskStatus;                 /* 00h */
+    U32                     DeviceSettings;             /* 04h */
+    U16                     ErrorCount;                 /* 08h */
+    U16                     Reserved;                   /* 0Ah */
+    U8                      ErrorCdbByte;               /* 0Ch */
+    U8                      ErrorSenseKey;              /* 0Dh */
+    U8                      ErrorASC;                   /* 0Eh */
+    U8                      ErrorASCQ;                  /* 0Fh */
+    U16                     SmartCount;                 /* 10h */
+    U8                      SmartASC;                   /* 12h */
+    U8                      SmartASCQ;                  /* 13h */
+} RAIDVOL2_IM_DISK_INFO, MPI_POINTER PTR_RAIDVOL2_IM_DISK_INFO,
+  RaidVol2ImDiskInfo_t, MPI_POINTER pRaidVol2ImDiskInfo_t;
+
+/* RAID Volume 2 IM Physical Disk DiskStatus flags */
+
+#define MPI_RVP2_PHYS_DISK_PRIMARY                      (0x00000001)
+#define MPI_RVP2_PHYS_DISK_SECONDARY                    (0x00000002)
+#define MPI_RVP2_PHYS_DISK_HOT_SPARE                    (0x00000004)
+#define MPI_RVP2_PHYS_DISK_OUT_OF_SYNC                  (0x00000008)
+#define MPI_RVP2_PHYS_DISK_STATUS_MASK                  (0x00000F00)
+#define MPI_RVP2_PHYS_DISK_STATUS_ONLINE                (0x00000000)
+#define MPI_RVP2_PHYS_DISK_STATUS_MISSING               (0x00000100)
+#define MPI_RVP2_PHYS_DISK_STATUS_NOT_COMPATIBLE        (0x00000200)
+#define MPI_RVP2_PHYS_DISK_STATUS_FAILED                (0x00000300)
+#define MPI_RVP2_PHYS_DISK_STATUS_INITIALIZING          (0x00000400)
+#define MPI_RVP2_PHYS_DISK_STATUS_OFFLINE_REQUESTED     (0x00000500)
+#define MPI_RVP2_PHYS_DISK_STATUS_OTHER_OFFLINE         (0x00000F00)
+
+
+typedef struct _RAIDVOL2_IM_PHYSICAL_DISK
+{
+    RAIDVOL2_IM_PHYS_ID     Id;                         /* 00h */
+    RAIDVOL2_IM_DISK_INFO   Info;                       /* 5Ch */
+} RAIDVOL2_IM_PHYSICAL_DISK, MPI_POINTER PTR_RAIDVOL2_IM_PHYSICAL_DISK,
+  RaidVol2ImPhysicalDisk_t, MPI_POINTER pRaidVol2ImPhysicalDisk_t;
 
 #define MPI_RAIDVOLPAGE2_MAX_DISKS                      (3)
 
 typedef struct _CONFIG_PAGE_RAID_VOL_2
 {
-   fCONFIG_PAGE_HEADER          Header;
-    U32                         VolumeStatus;
-    U32                         VolumeSettings;
-    U32                         Reserved;
-    U64                         MaxLba;
-    U32                         BlockSize;
-    U8                          InquirySize;
-    U8                          NumPhysicalDisks;
-    U16                         Reserved1;
-    U8                          InquiryData[56];
-    RAIDVOL2_EM_PHYSICAL_DISK   EMPhysicalDisk[MPI_RAIDVOLPAGE2_MAX_DISKS];
+   fCONFIG_PAGE_HEADER          Header;                 /* 00h */
+    U32                         VolumeStatus;           /* 04h */
+    U32                         VolumeSettings;         /* 08h */
+    U32                         Reserved;               /* 0Ch */
+    U64                         MaxLba;                 /* 10h */
+    U32                         BlockSize;              /* 18h */
+    U8                          Reserved1;              /* 1Ch */
+    U8                          NumPhysicalDisks;       /* 1Dh */
+    U16                         Reserved2;              /* 1Eh */
+    RAIDVOL2_IM_PHYSICAL_DISK   IMPhysicalDisk[MPI_RAIDVOLPAGE2_MAX_DISKS];
 } fCONFIG_PAGE_RAID_VOL_2, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_2,
   RaidVolumePage2_t, MPI_POINTER pRaidVolumePage2_t;
 
@@ -922,6 +1047,7 @@ typedef struct _CONFIG_PAGE_RAID_VOL_2
 #define MPI_RAIDVOLPAGE2_SETTING_WRITE_CACHING_ENABLE   (0x00000001)
 #define MPI_RAIDVOLPAGE2_SETTING_OFFLINE_ON_SMART       (0x00000002)
 #define MPI_RAIDVOLPAGE2_SETTING_AUTO_CONFIGURE         (0x00000004)
+#define MPI_RAIDVOLPAGE2_SETTING_USE_DEFAULTS           (0x80000000)
 
 
 /****************************************************************************/
@@ -930,10 +1056,10 @@ typedef struct _CONFIG_PAGE_RAID_VOL_2
 
 typedef struct _CONFIG_PAGE_LAN_0
 {
-    ConfigPageHeader_t      Header;
-    U16                     TxRxModes;
-    U16                     Reserved;
-    U32                     PacketPrePad;
+    ConfigPageHeader_t      Header;                     /* 00h */
+    U16                     TxRxModes;                  /* 04h */
+    U16                     Reserved;                   /* 06h */
+    U32                     PacketPrePad;               /* 08h */
 } fCONFIG_PAGE_LAN_0, MPI_POINTER PTR_CONFIG_PAGE_LAN_0,
   LANPage0_t, MPI_POINTER pLANPage0_t;
 
@@ -945,20 +1071,20 @@ typedef struct _CONFIG_PAGE_LAN_0
 
 typedef struct _CONFIG_PAGE_LAN_1
 {
-    ConfigPageHeader_t      Header;
-    U16                     Reserved;
-    U8                      CurrentDeviceState;
-    U8                      Reserved1;
-    U32                     MinPacketSize;
-    U32                     MaxPacketSize;
-    U32                     HardwareAddressLow;
-    U32                     HardwareAddressHigh;
-    U32                     MaxWireSpeedLow;
-    U32                     MaxWireSpeedHigh;
-    U32                     BucketsRemaining;
-    U32                     MaxReplySize;
-    U32                     NegWireSpeedHigh;
-    U32                     NegWireSpeedLow;
+    ConfigPageHeader_t      Header;                     /* 00h */
+    U16                     Reserved;                   /* 04h */
+    U8                      CurrentDeviceState;         /* 06h */
+    U8                      Reserved1;                  /* 07h */
+    U32                     MinPacketSize;              /* 08h */
+    U32                     MaxPacketSize;              /* 0Ch */
+    U32                     HardwareAddressLow;         /* 10h */
+    U32                     HardwareAddressHigh;        /* 14h */
+    U32                     MaxWireSpeedLow;            /* 18h */
+    U32                     MaxWireSpeedHigh;           /* 1Ch */
+    U32                     BucketsRemaining;           /* 20h */
+    U32                     MaxReplySize;               /* 24h */
+    U32                     NegWireSpeedHigh;           /* 28h */
+    U32                     NegWireSpeedLow;            /* 2Ch */
 } fCONFIG_PAGE_LAN_1, MPI_POINTER PTR_CONFIG_PAGE_LAN_1,
   LANPage1_t, MPI_POINTER pLANPage1_t;
 
index 73d17d2217bac95ed5d1814fe6a9ed3aaac60cdc..042953b4a7562a90eab4b71f3cffc69b4f536a2e 100644 (file)
@@ -6,7 +6,7 @@
  *          Title:  MPI Fibre Channel messages and structures
  *  Creation Date:  June 12, 2000
  *
- *    MPI Version:  01.01.05
+ *    MPI Version:  01.01.07
  *
  *  Version History
  *  ---------------
  *                      FC_ABORT_TYPE_EXLINKSEND_REQUEST for FcAbort request.
  *                      Added MPI_FC_PRIM_SEND_FLAGS_STOP_SEND.
  *  02-20-01  01.01.05  Started using MPI_POINTER.
+ *  03-27-01  01.01.06  Added Flags field to MSG_LINK_SERVICE_BUFFER_POST_REPLY
+ *                      and defined MPI_LS_BUF_POST_REPLY_FLAG_NO_RSP_NEEDED.
+ *                      Added MPI_FC_PRIM_SEND_FLAGS_RESET_LINK define.
+ *                      Added structure offset comments.
+ *  04-09-01  01.01.07  Added RspLength field to MSG_LINK_SERVICE_RSP_REQUEST.
  *  --------------------------------------------------------------------------
  */
 
@@ -136,7 +141,7 @@ typedef struct _MSG_LINK_SERVICE_BUFFER_POST_REPLY
 typedef struct _MSG_LINK_SERVICE_RSP_REQUEST
 {
     U8                      RspFlags;           /* 00h */
-    U8                      Reserved;           /* 01h */
+    U8                      RspLength;          /* 01h */
     U8                      ChainOffset;        /* 02h */
     U8                      Function;           /* 03h */
     U16                     Reserved1;          /* 04h */
@@ -224,14 +229,14 @@ typedef struct _MSG_EXLINK_SERVICE_SEND_REPLY
 
 typedef struct _MSG_FC_ABORT_REQUEST
 {
-    U8                      AbortFlags;         /* 00h */
-    U8                      AbortType;          /* 01h */
-    U8                      ChainOffset;        /* 02h */
-    U8                      Function;           /* 03h */
-    U16                     Reserved1;          /* 04h */
-    U8                      Reserved2;          /* 06h */
-    U8                      MsgFlags;           /* 07h */
-    U32                     MsgContext;         /* 08h */
+    U8                      AbortFlags;                 /* 00h */
+    U8                      AbortType;                  /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved1;                  /* 04h */
+    U8                      Reserved2;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
     U32                     TransactionContextToAbort;  /* 0Ch */
 } MSG_FC_ABORT_REQUEST, MPI_POINTER PTR_MSG_FC_ABORT_REQUEST,
   FcAbortRequest_t, MPI_POINTER pFcAbortRequest_t;
@@ -323,6 +328,7 @@ typedef struct _MSG_FC_PRIMITIVE_SEND_REQUEST
   FcPrimitiveSendRequest_t, MPI_POINTER pFcPrimitiveSendRequest_t;
 
 #define MPI_FC_PRIM_SEND_FLAGS_PORT_MASK       (0x01)
+#define MPI_FC_PRIM_SEND_FLAGS_RESET_LINK      (0x04)
 #define MPI_FC_PRIM_SEND_FLAGS_STOP_SEND       (0x08)
 #define MPI_FC_PRIM_SEND_FLAGS_SEND_ONCE       (0x10)
 #define MPI_FC_PRIM_SEND_FLAGS_SEND_AROUND     (0x20)
index 5ac3e0622f52aae7169fc7ac2ab7991d215e69bc..0deb7721e9362835b6c9d11b8d620ecd93b462c6 100644 (file)
@@ -6,22 +6,22 @@
  Copyright (c) 2000-2001 LSI Logic Corporation.
 
  ---------------------------------------
- Header Set Release Version:    01.01.08
- Header Set Release Date:       02-27-01
+ Header Set Release Version:    01.01.10
+ Header Set Release Date:       04-09-01
  ---------------------------------------
 
  Filename               Current version     Prior version
  ----------             ---------------     -------------
- mpi.h                  01.01.06            01.01.05
- mpi_ioc.h              01.01.05            01.01.04
- mpi_cnfg.h             01.01.09            01.01.08
- mpi_init.h             01.01.03            01.01.03
- mpi_targ.h             01.01.03            01.01.03
- mpi_fc.h               01.01.05            01.01.05
- mpi_lan.h              01.01.02            01.01.02
- mpi_raid.h             01.01.01            none
+ mpi.h                  01.01.07            01.01.06
+ mpi_ioc.h              01.01.07            01.01.06
+ mpi_cnfg.h             01.01.11            01.01.10
+ mpi_init.h             01.01.05            01.01.04
+ mpi_targ.h             01.01.04            01.01.04
+ mpi_fc.h               01.01.07            01.01.06
+ mpi_lan.h              01.01.03            01.01.03
+ mpi_raid.h             01.01.02            01.01.02
  mpi_type.h             01.01.02            01.01.02
- mpi_history.txt        01.01.08            01.01.07
+ mpi_history.txt        01.01.09            01.01.09
 
 
  *  Date      Version   Description
@@ -51,6 +51,8 @@ mpi.h
  *                      Obsoleted MPI_IOCSTATUS_TARGET_FC_ defines.
  *  02-27-01  01.01.06  Removed MPI_HOST_INDEX_REGISTER define.
  *                      Added function codes for RAID.
+ *  04-09-01  01.01.07  Added alternate define for MPI_DOORBELL_ACTIVE,
+ *                      MPI_DOORBELL_USED, to better match the spec.
  *  --------------------------------------------------------------------------
 
 mpi_ioc.h
@@ -76,6 +78,9 @@ mpi_ioc.h
  *  02-20-01  01.01.04  Started using MPI_POINTER.
  *  02-27-01  01.01.05  Added event for RAID status change and its event data.
  *                      Added IocNumber field to MSG_IOC_FACTS_REPLY.
+ *  03-27-01  01.01.06  Added defines for ProductId field of MPI_FW_HEADER.
+ *                      Added structure offset comments.
+ *  04-09-01  01.01.07  Added structure EVENT_DATA_EVENT_CHANGE.
  *  --------------------------------------------------------------------------
 
 mpi_cnfg.h
@@ -125,6 +130,18 @@ mpi_cnfg.h
  *                      MPI_CONFIG_PAGETYPE_RAID_VOLUME.
  *                      Added definitions and structures for IOC Page 2 and
  *                      RAID Volume Page 2.
+ *  03-27-01  01.01.10  Added CONFIG_PAGE_FC_PORT_8 and CONFIG_PAGE_FC_PORT_9.
+ *                      CONFIG_PAGE_FC_PORT_3 now supports persistent by DID.
+ *                      Added VendorId and ProductRevLevel fields to
+ *                      RAIDVOL2_IM_PHYS_ID struct.
+ *                      Modified values for MPI_FCPORTPAGE0_FLAGS_ATTACH_
+ *                      defines to make them compatible to MPI version 1.0.
+ *                      Added structure offset comments.
+ *  04-09-01  01.01.11  Added some new defines for the PageAddress field and
+ *                      removed some obsolete ones.
+ *                      Added IO Unit Page 3.
+ *                      Modified defines for Scsi Port Page 2.
+ *                      Modified RAID Volume Pages.
  *  --------------------------------------------------------------------------
 
 mpi_init.h
@@ -135,6 +152,8 @@ mpi_init.h
  *  11-02-00  01.01.01  Original release for post 1.0 work
  *  12-04-00  01.01.02  Added MPI_SCSIIO_CONTROL_NO_DISCONNECT.
  *  02-20-01  01.01.03  Started using MPI_POINTER.
+ *  03-27-01  01.01.04  Added structure offset comments.
+ *  04-10-01  01.01.05  Added new MsgFlag for MSG_SCSI_TASK_MGMT.
  *  --------------------------------------------------------------------------
 
 mpi_targ.h
@@ -150,6 +169,7 @@ mpi_targ.h
  *  02-20-01  01.01.03  Started using MPI_POINTER.
  *                      Added structures for MPI_TARGET_SCSI_SPI_CMD_BUFFER and
  *                      MPI_TARGET_FCP_CMD_BUFFER.
+ *  03-27-01  01.01.04  Added structure offset comments.
  *  --------------------------------------------------------------------------
 
 mpi_fc.h
@@ -167,6 +187,11 @@ mpi_fc.h
  *                      FC_ABORT_TYPE_EXLINKSEND_REQUEST for FcAbort request.
  *                      Added MPI_FC_PRIM_SEND_FLAGS_STOP_SEND.
  *  02-20-01  01.01.05  Started using MPI_POINTER.
+ *  03-27-01  01.01.06  Added Flags field to MSG_LINK_SERVICE_BUFFER_POST_REPLY
+ *                      and defined MPI_LS_BUF_POST_REPLY_FLAG_NO_RSP_NEEDED.
+ *                      Added MPI_FC_PRIM_SEND_FLAGS_RESET_LINK define.
+ *                      Added structure offset comments.
+ *  04-09-01  01.01.07  Added RspLength field to MSG_LINK_SERVICE_RSP_REQUEST.
  *  --------------------------------------------------------------------------
 
 mpi_lan.h
@@ -183,10 +208,12 @@ mpi_lan.h
  *                      to lan private header file
  *  11-02-00  01.01.01  Original release for post 1.0 work
  *  02-20-01  01.01.02  Started using MPI_POINTER.
+ *  03-27-01  01.01.03  Added structure offset comments.
  *  --------------------------------------------------------------------------
 
 mpi_raid.h
  *  02-27-01  01.01.01  Original release for this file.
+ *  03-27-01  01.01.02  Added structure offset comments.
  *  --------------------------------------------------------------------------
 
 mpi_type.h
@@ -198,17 +225,29 @@ mpi_type.h
 
 mpi_history.txt         Parts list history
 
-Filename    01.01.08   01.01.07   01.01.06   01.01.05   01.01.04
-----------  --------   --------   --------   --------   --------
-mpi.h       01.01.06   01.01.05   01.01.04   01.01.04   01.01.03
-mpi_ioc.h   01.01.05   01.01.04   01.01.03   01.01.03   01.01.03
-mpi_cnfg.h  01.01.09   01.01.08   01.01.07   01.01.06   01.01.05
-mpi_init.h  01.01.03   01.01.03   01.01.02   01.01.02   01.01.02
-mpi_targ.h  01.01.03   01.01.03   01.01.02   01.01.02   01.01.02
-mpi_fc.h    01.01.05   01.01.05   01.01.04   01.01.04   01.01.03
-mpi_lan.h   01.01.02   01.01.02   01.01.01   01.01.01   01.01.01
-mpi_raid.h  01.01.01
-mpi_type.h  01.01.02   01.01.02   01.01.01   01.01.01   01.01.01
+Filename    01.01.10
+----------  --------
+mpi.h       01.01.07
+mpi_ioc.h   01.01.07
+mpi_cnfg.h  01.01.11
+mpi_init.h  01.01.05
+mpi_targ.h  01.01.04
+mpi_fc.h    01.01.07
+mpi_lan.h   01.01.03
+mpi_raid.h  01.01.02
+mpi_type.h  01.01.02
+
+Filename    01.01.09   01.01.08   01.01.07   01.01.06   01.01.05   01.01.04
+----------  --------   --------   --------   --------   --------   --------
+mpi.h       01.01.06   01.01.06   01.01.05   01.01.04   01.01.04   01.01.03
+mpi_ioc.h   01.01.06   01.01.05   01.01.04   01.01.03   01.01.03   01.01.03
+mpi_cnfg.h  01.01.10   01.01.09   01.01.08   01.01.07   01.01.06   01.01.05
+mpi_init.h  01.01.04   01.01.03   01.01.03   01.01.02   01.01.02   01.01.02
+mpi_targ.h  01.01.04   01.01.03   01.01.03   01.01.02   01.01.02   01.01.02
+mpi_fc.h    01.01.06   01.01.05   01.01.05   01.01.04   01.01.04   01.01.03
+mpi_lan.h   01.01.03   01.01.02   01.01.02   01.01.01   01.01.01   01.01.01
+mpi_raid.h  01.01.02   01.01.01
+mpi_type.h  01.01.02   01.01.02   01.01.02   01.01.01   01.01.01   01.01.01
 
 Filename    01.01.03   01.01.02   01.01.01   01.00.07   01.00.06   01.00.05
 ----------  --------   --------   --------   --------   --------   --------
index 4f3c8dc705c5e29a299436ee4d2a74e3098e23e4..5d871e4fd11d61e517123da380750eb3efd7c74a 100644 (file)
@@ -6,7 +6,7 @@
  *          Title:  MPI initiator mode messages and structures
  *  Creation Date:  June 8, 2000
  *
- *    MPI Version:  01.01.03
+ *    MPI Version:  01.01.05
  *
  *  Version History
  *  ---------------
@@ -20,6 +20,8 @@
  *  11-02-00  01.01.01  Original release for post 1.0 work.
  *  12-04-00  01.01.02  Added MPI_SCSIIO_CONTROL_NO_DISCONNECT.
  *  02-20-01  01.01.03  Started using MPI_POINTER.
+ *  03-27-01  01.01.04  Added structure offset comments.
+ *  04-10-01  01.01.05  Added new MsgFlag for MSG_SCSI_TASK_MGMT.
  *  --------------------------------------------------------------------------
  */
 
 
 typedef struct _MSG_SCSI_IO_REQUEST
 {
-    U8                      TargetID;
-    U8                      Bus;
-    U8                      ChainOffset;
-    U8                      Function;
-    U8                      CDBLength;
-    U8                      SenseBufferLength;
-    U8                      Reserved;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U8                      LUN[8];
-    U32                     Control;
-    U8                      CDB[16];
-    U32                     DataLength;
-    U32                     SenseBufferLowAddr;
-    SGE_IO_UNION            SGL;
+    U8                      TargetID;           /* 00h */
+    U8                      Bus;                /* 01h */
+    U8                      ChainOffset;        /* 02h */
+    U8                      Function;           /* 03h */
+    U8                      CDBLength;          /* 04h */
+    U8                      SenseBufferLength;  /* 05h */
+    U8                      Reserved;           /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U8                      LUN[8];             /* 0Ch */
+    U32                     Control;            /* 14h */
+    U8                      CDB[16];            /* 18h */
+    U32                     DataLength;         /* 28h */
+    U32                     SenseBufferLowAddr; /* 2Ch */
+    SGE_IO_UNION            SGL;                /* 30h */
 } MSG_SCSI_IO_REQUEST, MPI_POINTER PTR_MSG_SCSI_IO_REQUEST,
   SCSIIORequest_t, MPI_POINTER pSCSIIORequest_t;
 
@@ -108,22 +110,22 @@ typedef struct _MSG_SCSI_IO_REQUEST
 /* SCSIIO reply structure */
 typedef struct _MSG_SCSI_IO_REPLY
 {
-    U8                      TargetID;
-    U8                      Bus;
-    U8                      MsgLength;
-    U8                      Function;
-    U8                      CDBLength;
-    U8                      SenseBufferLength;
-    U8                      Reserved;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U8                      SCSIStatus;
-    U8                      SCSIState;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
-    U32                     TransferCount;
-    U32                     SenseCount;
-    U32                     ResponseInfo;
+    U8                      TargetID;           /* 00h */
+    U8                      Bus;                /* 01h */
+    U8                      MsgLength;          /* 02h */
+    U8                      Function;           /* 03h */
+    U8                      CDBLength;          /* 04h */
+    U8                      SenseBufferLength;  /* 05h */
+    U8                      Reserved;           /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U8                      SCSIStatus;         /* 0Ch */
+    U8                      SCSIState;          /* 0Dh */
+    U16                     IOCStatus;          /* 0Eh */
+    U32                     IOCLogInfo;         /* 10h */
+    U32                     TransferCount;      /* 14h */
+    U32                     SenseCount;         /* 18h */
+    U32                     ResponseInfo;       /* 1Ch */
 } MSG_SCSI_IO_REPLY, MPI_POINTER PTR_MSG_SCSI_IO_REPLY,
   SCSIIOReply_t, MPI_POINTER pSCSIIOReply_t;
 
@@ -168,47 +170,49 @@ typedef struct _MSG_SCSI_IO_REPLY
 
 typedef struct _MSG_SCSI_TASK_MGMT
 {
-    U8                      TargetID;
-    U8                      Bus;
-    U8                      ChainOffset;
-    U8                      Function;
-    U8                      Reserved;
-    U8                      TaskType;
-    U8                      Reserved1;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U8                      LUN[8];
-    U32                     Reserved2[7];
-    U32                     TaskMsgContext;
+    U8                      TargetID;           /* 00h */
+    U8                      Bus;                /* 01h */
+    U8                      ChainOffset;        /* 02h */
+    U8                      Function;           /* 03h */
+    U8                      Reserved;           /* 04h */
+    U8                      TaskType;           /* 05h */
+    U8                      Reserved1;          /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U8                      LUN[8];             /* 0Ch */
+    U32                     Reserved2[7];       /* 14h */
+    U32                     TaskMsgContext;     /* 30h */
 } MSG_SCSI_TASK_MGMT, MPI_POINTER PTR_SCSI_TASK_MGMT,
   SCSITaskMgmt_t, MPI_POINTER pSCSITaskMgmt_t;
 
 /* TaskType values */
 
-#define MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK        (0x00000001)
-#define MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET     (0x00000002)
-#define MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET      (0x00000003)
-#define MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS         (0x00000004)
+#define MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK            (0x01)
+#define MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET         (0x02)
+#define MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET          (0x03)
+#define MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS             (0x04)
 
 /* MsgFlags bits */
-#define MPI_SCSITASKMGMT_MSGFLAGS_LIP_RESET_OPTION  (0x00000002)
+#define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION   (0x00)
+#define MPI_SCSITASKMGMT_MSGFLAGS_LIP_RESET_OPTION      (0x02)
+#define MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION (0x04)
 
 /* SCSI Task Management Reply */
 typedef struct _MSG_SCSI_TASK_MGMT_REPLY
 {
-    U8                      TargetID;
-    U8                      Bus;
-    U8                      MsgLength;
-    U8                      Function;
-    U8                      Reserved;
-    U8                      TaskType;
-    U8                      Reserved1;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U8                      Reserved2[2];
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
-    U32                     TerminationCount;
+    U8                      TargetID;           /* 00h */
+    U8                      Bus;                /* 01h */
+    U8                      MsgLength;          /* 02h */
+    U8                      Function;           /* 03h */
+    U8                      Reserved;           /* 04h */
+    U8                      TaskType;           /* 05h */
+    U8                      Reserved1;          /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U8                      Reserved2[2];       /* 0Ch */
+    U16                     IOCStatus;          /* 0Eh */
+    U32                     IOCLogInfo;         /* 10h */
+    U32                     TerminationCount;   /* 14h */
 } MSG_SCSI_TASK_MGMT_REPLY, MPI_POINTER PTR_MSG_SCSI_TASK_MGMT_REPLY,
   SCSITaskMgmtReply_t, MPI_POINTER pSCSITaskMgmtReply_t;
 
index 0411671dc9a9466ac71a388acc4aeaba38baf039..d910811bc0ff19ebdabccf6fcd9e15240da02f94 100644 (file)
@@ -3,10 +3,10 @@
  *
  *
  *           Name:  MPI_IOC.H
- *          Title:  MPI IOC, Port, Event, FW Load, and ToolBox messages
+ *          Title:  MPI IOC, Port, Event, FW Download, and FW Upload messages
  *  Creation Date:  August 11, 2000
  *
- *    MPI Version:  01.01.05
+ *    MPI Version:  01.01.07
  *
  *  Version History
  *  ---------------
@@ -35,6 +35,9 @@
  *  02-20-01  01.01.04  Started using MPI_POINTER.
  *  02-27-01  01.01.05  Added event for RAID status change and its event data.
  *                      Added IocNumber field to MSG_IOC_FACTS_REPLY.
+ *  03-27-01  01.01.06  Added defines for ProductId field of MPI_FW_HEADER.
+ *                      Added structure offset comments.
+ *  04-09-01  01.01.07  Added structure EVENT_DATA_EVENT_CHANGE.
  *  --------------------------------------------------------------------------
  */
 
 
 typedef struct _MSG_IOC_INIT
 {
-    U8                      WhoInit;
-    U8                      Reserved;
-    U8                      ChainOffset;
-    U8                      Function;
-    U8                      Flags;
-    U8                      MaxDevices;
-    U8                      MaxBuses;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     ReplyFrameSize;
-    U8                      Reserved1[2];
-    U32                     HostMfaHighAddr;
-    U32                     SenseBufferHighAddr;
+    U8                      WhoInit;                    /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Flags;                      /* 04h */
+    U8                      MaxDevices;                 /* 05h */
+    U8                      MaxBuses;                   /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     ReplyFrameSize;             /* 0Ch */
+    U8                      Reserved1[2];               /* 0Eh */
+    U32                     HostMfaHighAddr;            /* 10h */
+    U32                     SenseBufferHighAddr;        /* 14h */
 } MSG_IOC_INIT, MPI_POINTER PTR_MSG_IOC_INIT,
   IOCInit_t, MPI_POINTER pIOCInit_t;
 
 typedef struct _MSG_IOC_INIT_REPLY
 {
-    U8                      WhoInit;
-    U8                      Reserved;
-    U8                      MsgLength;
-    U8                      Function;
-    U8                      Flags;
-    U8                      MaxDevices;
-    U8                      MaxBuses;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved2;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
+    U8                      WhoInit;                    /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Flags;                      /* 04h */
+    U8                      MaxDevices;                 /* 05h */
+    U8                      MaxBuses;                   /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     Reserved2;                  /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
 } MSG_IOC_INIT_REPLY, MPI_POINTER PTR_MSG_IOC_INIT_REPLY,
   IOCInitReply_t, MPI_POINTER pIOCInitReply_t;
 
@@ -103,12 +106,12 @@ typedef struct _MSG_IOC_INIT_REPLY
 
 typedef struct _MSG_IOC_FACTS
 {
-    U8                      Reserved[2];
-    U8                      ChainOffset;
-    U8                      Function;
-    U8                      Reserved1[3];
-    U8                      MsgFlags;
-    U32                     MsgContext;
+    U8                      Reserved[2];                /* 00h */
+    U8                      ChainOffset;                /* 01h */
+    U8                      Function;                   /* 02h */
+    U8                      Reserved1[3];               /* 03h */
+    U8                      MsgFlags;                   /* 04h */
+    U32                     MsgContext;                 /* 08h */
 } MSG_IOC_FACTS, MPI_POINTER PTR_IOC_FACTS,
   IOCFacts_t, MPI_POINTER pIOCFacts_t;
 
@@ -116,34 +119,34 @@ typedef struct _MSG_IOC_FACTS
 
 typedef struct _MSG_IOC_FACTS_REPLY
 {
-    U16                     MsgVersion;
-    U8                      MsgLength;
-    U8                      Function;
-    U16                     Reserved;
-    U8                      IOCNumber;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved2;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
-    U8                      MaxChainDepth;
-    U8                      WhoInit;
-    U8                      BlockSize;
-    U8                      Flags;
-    U16                     ReplyQueueDepth;
-    U16                     RequestFrameSize;
-    U16                     FWVersion;
-    U16                     ProductID;
-    U32                     CurrentHostMfaHighAddr;
-    U16                     GlobalCredits;
-    U8                      NumberOfPorts;
-    U8                      EventState;
-    U32                     CurrentSenseBufferHighAddr;
-    U16                     CurReplyFrameSize;
-    U8                      MaxDevices;
-    U8                      MaxBuses;
-    U32                     FWImageSize;
-    U32                     DataImageSize;
+    U16                     MsgVersion;                 /* 00h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved;                   /* 04h */
+    U8                      IOCNumber;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     Reserved2;                  /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
+    U8                      MaxChainDepth;              /* 14h */
+    U8                      WhoInit;                    /* 15h */
+    U8                      BlockSize;                  /* 16h */
+    U8                      Flags;                      /* 17h */
+    U16                     ReplyQueueDepth;            /* 18h */
+    U16                     RequestFrameSize;           /* 1Ah */
+    U16                     FWVersion;                  /* 1Ch */
+    U16                     ProductID;                  /* 1Eh */
+    U32                     CurrentHostMfaHighAddr;     /* 20h */
+    U16                     GlobalCredits;              /* 24h */
+    U8                      NumberOfPorts;              /* 26h */
+    U8                      EventState;                 /* 27h */
+    U32                     CurrentSenseBufferHighAddr; /* 28h */
+    U16                     CurReplyFrameSize;          /* 2Ch */
+    U8                      MaxDevices;                 /* 2Eh */
+    U8                      MaxBuses;                   /* 2Fh */
+    U32                     FWImageSize;                /* 30h */
+    U32                     DataImageSize;              /* 34h */
 } MSG_IOC_FACTS_REPLY, MPI_POINTER PTR_MSG_IOC_FACTS_REPLY,
   IOCFactsReply_t, MPI_POINTER pIOCFactsReply_t;
 
@@ -170,38 +173,38 @@ typedef struct _MSG_IOC_FACTS_REPLY
 
 typedef struct _MSG_PORT_FACTS
 {
-     U8                     Reserved[2];
-     U8                     ChainOffset;
-     U8                     Function;
-     U8                     Reserved1[2];
-     U8                     PortNumber;
-     U8                     MsgFlags;
-     U32                    MsgContext;
+     U8                     Reserved[2];                /* 00h */
+     U8                     ChainOffset;                /* 02h */
+     U8                     Function;                   /* 03h */
+     U8                     Reserved1[2];               /* 04h */
+     U8                     PortNumber;                 /* 06h */
+     U8                     MsgFlags;                   /* 07h */
+     U32                    MsgContext;                 /* 08h */
 } MSG_PORT_FACTS, MPI_POINTER PTR_MSG_PORT_FACTS,
   PortFacts_t, MPI_POINTER pPortFacts_t;
 
 typedef struct _MSG_PORT_FACTS_REPLY
 {
-     U16                    Reserved;
-     U8                     MsgLength;
-     U8                     Function;
-     U16                    Reserved1;
-     U8                     PortNumber;
-     U8                     MsgFlags;
-     U32                    MsgContext;
-     U16                    Reserved2;
-     U16                    IOCStatus;
-     U32                    IOCLogInfo;
-     U8                     Reserved3;
-     U8                     PortType;
-     U16                    MaxDevices;
-     U16                    PortSCSIID;
-     U16                    ProtocolFlags;
-     U16                    MaxPostedCmdBuffers;
-     U16                    MaxPersistentIDs;
-     U16                    MaxLanBuckets;
-     U16                    Reserved4;
-     U32                    Reserved5;
+     U16                    Reserved;                   /* 00h */
+     U8                     MsgLength;                  /* 02h */
+     U8                     Function;                   /* 03h */
+     U16                    Reserved1;                  /* 04h */
+     U8                     PortNumber;                 /* 06h */
+     U8                     MsgFlags;                   /* 07h */
+     U32                    MsgContext;                 /* 08h */
+     U16                    Reserved2;                  /* 0Ch */
+     U16                    IOCStatus;                  /* 0Eh */
+     U32                    IOCLogInfo;                 /* 10h */
+     U8                     Reserved3;                  /* 14h */
+     U8                     PortType;                   /* 15h */
+     U16                    MaxDevices;                 /* 16h */
+     U16                    PortSCSIID;                 /* 18h */
+     U16                    ProtocolFlags;              /* 1Ah */
+     U16                    MaxPostedCmdBuffers;        /* 1Ch */
+     U16                    MaxPersistentIDs;           /* 1Eh */
+     U16                    MaxLanBuckets;              /* 20h */
+     U16                    Reserved4;                  /* 22h */
+     U32                    Reserved5;                  /* 24h */
 } MSG_PORT_FACTS_REPLY, MPI_POINTER PTR_MSG_PORT_FACTS_REPLY,
   PortFactsReply_t, MPI_POINTER pPortFactsReply_t;
 
@@ -226,28 +229,28 @@ typedef struct _MSG_PORT_FACTS_REPLY
 
 typedef struct _MSG_PORT_ENABLE
 {
-    U8                      Reserved[2];
-    U8                      ChainOffset;
-    U8                      Function;
-    U8                      Reserved1[2];
-    U8                      PortNumber;
-    U8                      MsgFlags;
-    U32                     MsgContext;
+    U8                      Reserved[2];                /* 00h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Reserved1[2];               /* 04h */
+    U8                      PortNumber;                 /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
 } MSG_PORT_ENABLE, MPI_POINTER PTR_MSG_PORT_ENABLE,
   PortEnable_t, MPI_POINTER pPortEnable_t;
 
 typedef struct _MSG_PORT_ENABLE_REPLY
 {
-    U8                      Reserved[2];
-    U8                      MsgLength;
-    U8                      Function;
-    U8                      Reserved1[2];
-    U8                      PortNumber;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved2;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
+    U8                      Reserved[2];                /* 00h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Reserved1[2];               /* 04h */
+    U8                      PortNumber;                 /* 05h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     Reserved2;                  /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
 } MSG_PORT_ENABLE_REPLY, MPI_POINTER PTR_MSG_PORT_ENABLE_REPLY,
   PortEnableReply_t, MPI_POINTER pPortEnableReply_t;
 
@@ -264,13 +267,13 @@ typedef struct _MSG_PORT_ENABLE_REPLY
 
 typedef struct _MSG_EVENT_NOTIFY
 {
-    U8                      Switch;
-    U8                      Reserved;
-    U8                      ChainOffset;
-    U8                      Function;
-    U8                      Reserved1[3];
-    U8                      MsgFlags;
-    U32                     MsgContext;
+    U8                      Switch;                     /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Reserved1[3];               /* 04h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
 } MSG_EVENT_NOTIFY, MPI_POINTER PTR_MSG_EVENT_NOTIFY,
   EventNotification_t, MPI_POINTER pEventNotification_t;
 
@@ -278,19 +281,19 @@ typedef struct _MSG_EVENT_NOTIFY
 
 typedef struct _MSG_EVENT_NOTIFY_REPLY
 {
-     U16                    EventDataLength;
-     U8                     MsgLength;
-     U8                     Function;
-     U8                     Reserved1[2];
-     U8                     AckRequired;
-     U8                     MsgFlags;
-     U32                    MsgContext;
-     U8                     Reserved2[2];
-     U16                    IOCStatus;
-     U32                    IOCLogInfo;
-     U32                    Event;
-     U32                    EventContext;
-     U32                    Data[1];
+     U16                    EventDataLength;            /* 00h */
+     U8                     MsgLength;                  /* 02h */
+     U8                     Function;                   /* 03h */
+     U8                     Reserved1[2];               /* 04h */
+     U8                     AckRequired;                /* 06h */
+     U8                     MsgFlags;                   /* 07h */
+     U32                    MsgContext;                 /* 08h */
+     U8                     Reserved2[2];               /* 0Ch */
+     U16                    IOCStatus;                  /* 0Eh */
+     U32                    IOCLogInfo;                 /* 10h */
+     U32                    Event;                      /* 14h */
+     U32                    EventContext;               /* 18h */
+     U32                    Data[1];                    /* 1Ch */
 } MSG_EVENT_NOTIFY_REPLY, MPI_POINTER PTR_MSG_EVENT_NOTIFY_REPLY,
   EventNotificationReply_t, MPI_POINTER pEventNotificationReply_t;
 
@@ -298,28 +301,28 @@ typedef struct _MSG_EVENT_NOTIFY_REPLY
 
 typedef struct _MSG_EVENT_ACK
 {
-    U8                      Reserved[2];
-    U8                      ChainOffset;
-    U8                      Function;
-    U8                      Reserved1[3];
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U32                     Event;
-    U32                     EventContext;
+    U8                      Reserved[2];                /* 00h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Reserved1[3];               /* 04h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U32                     Event;                      /* 0Ch */
+    U32                     EventContext;               /* 10h */
 } MSG_EVENT_ACK, MPI_POINTER PTR_MSG_EVENT_ACK,
   EventAck_t, MPI_POINTER pEventAck_t;
 
 typedef struct _MSG_EVENT_ACK_REPLY
 {
-    U8                      Reserved[2];
-    U8                      MsgLength;
-    U8                      Function;
-    U8                      Reserved1[3];
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved2;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
+    U8                      Reserved[2];                /* 00h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Reserved1[3];               /* 04h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     Reserved2;                  /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
 } MSG_EVENT_ACK_REPLY, MPI_POINTER PTR_MSG_EVENT_ACK_REPLY,
   EventAckReply_t, MPI_POINTER pEventAckReply_t;
 
@@ -349,13 +352,23 @@ typedef struct _MSG_EVENT_ACK_REPLY
 #define MPI_EVENT_NOTIFICATION_ACK_NOT_REQUIRED (0x00)
 #define MPI_EVENT_NOTIFICATION_ACK_REQUIRED     (0x01)
 
-/* SCSI Event data for Port, Bus and Device forms) */
+/* EventChange Event data */
+
+typedef struct _EVENT_DATA_EVENT_CHANGE
+{
+    U8                      EventState;                 /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U16                     Reserved1;                  /* 02h */
+} EVENT_DATA_EVENT_CHANGE, MPI_POINTER PTR_EVENT_DATA_EVENT_CHANGE,
+  EventDataEventChange_t, MPI_POINTER pEventDataEventChange_t;
+
+/* SCSI Event data for Port, Bus and Device forms */
 
 typedef struct _EVENT_DATA_SCSI
 {
-    U8                      TargetID;
-    U8                      BusPort;
-    U16                     Reserved;
+    U8                      TargetID;                   /* 00h */
+    U8                      BusPort;                    /* 01h */
+    U16                     Reserved;                   /* 02h */
 } EVENT_DATA_SCSI, MPI_POINTER PTR_EVENT_DATA_SCSI,
   EventDataScsi_t, MPI_POINTER pEventDataScsi_t;
 
@@ -363,12 +376,12 @@ typedef struct _EVENT_DATA_SCSI
 
 typedef struct _EVENT_DATA_LINK_STATUS
 {
-    U8                      State;
-    U8                      Reserved;
-    U16                     Reserved1;
-    U8                      Reserved2;
-    U8                      Port;
-    U16                     Reserved3;
+    U8                      State;                      /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U16                     Reserved1;                  /* 02h */
+    U8                      Reserved2;                  /* 04h */
+    U8                      Port;                       /* 05h */
+    U16                     Reserved3;                  /* 06h */
 } EVENT_DATA_LINK_STATUS, MPI_POINTER PTR_EVENT_DATA_LINK_STATUS,
   EventDataLinkStatus_t, MPI_POINTER pEventDataLinkStatus_t;
 
@@ -379,13 +392,13 @@ typedef struct _EVENT_DATA_LINK_STATUS
 
 typedef struct _EVENT_DATA_LOOP_STATE
 {
-    U8                      Character4;
-    U8                      Character3;
-    U8                      Type;
-    U8                      Reserved;
-    U8                      Reserved1;
-    U8                      Port;
-    U16                     Reserved2;
+    U8                      Character4;                 /* 00h */
+    U8                      Character3;                 /* 01h */
+    U8                      Type;                       /* 02h */
+    U8                      Reserved;                   /* 03h */
+    U8                      Reserved1;                  /* 04h */
+    U8                      Port;                       /* 05h */
+    U16                     Reserved2;                  /* 06h */
 } EVENT_DATA_LOOP_STATE, MPI_POINTER PTR_EVENT_DATA_LOOP_STATE,
   EventDataLoopState_t, MPI_POINTER pEventDataLoopState_t;
 
@@ -397,10 +410,10 @@ typedef struct _EVENT_DATA_LOOP_STATE
 
 typedef struct _EVENT_DATA_LOGOUT
 {
-    U32                     NPortID;
-    U8                      Reserved;
-    U8                      Port;
-    U16                     Reserved1;
+    U32                     NPortID;                    /* 00h */
+    U8                      Reserved;                   /* 04h */
+    U8                      Port;                       /* 05h */
+    U16                     Reserved1;                  /* 06h */
 } EVENT_DATA_LOGOUT, MPI_POINTER PTR_EVENT_DATA_LOGOUT,
   EventDataLogout_t, MPI_POINTER pEventDataLogout_t;
 
@@ -408,13 +421,13 @@ typedef struct _EVENT_DATA_LOGOUT
 
 typedef struct _EVENT_DATA_RAID_STATUS_CHANGE
 {
-    U8                      VolumeTargetID;
-    U8                      VolumeBus;
-    U8                      ReasonCode;
-    U8                      PhysDiskNum;
-    U8                      ASC;
-    U8                      ASCQ;
-    U16                     Reserved;
+    U8                      VolumeTargetID;             /* 00h */
+    U8                      VolumeBus;                  /* 01h */
+    U8                      ReasonCode;                 /* 02h */
+    U8                      PhysDiskNum;                /* 03h */
+    U8                      ASC;                        /* 04h */
+    U8                      ASCQ;                       /* 05h */
+    U16                     Reserved;                   /* 06h */
 } EVENT_DATA_RAID_STATUS_CHANGE, MPI_POINTER PTR_EVENT_DATA_RAID_STATUS_CHANGE,
   MpiEventDataRaidStatusChange_t, MPI_POINTER pMpiEventDataRaidStatusChange_t;
 
@@ -441,14 +454,14 @@ typedef struct _EVENT_DATA_RAID_STATUS_CHANGE
 
 typedef struct _MSG_FW_DOWNLOAD
 {
-    U8                      ImageType;
-    U8                      Reserved;
-    U8                      ChainOffset;
-    U8                      Function;
-    U8                      Reserved1[3];
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    SGE_MPI_UNION           SGL;
+    U8                      ImageType;                  /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Reserved1[3];               /* 04h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    SGE_MPI_UNION           SGL;                        /* 0Ch */
 } MSG_FW_DOWNLOAD, MPI_POINTER PTR_MSG_FW_DOWNLOAD,
   FWDownload_t, MPI_POINTER pFWDownload_t;
 
@@ -459,29 +472,29 @@ typedef struct _MSG_FW_DOWNLOAD
 
 typedef struct _FWDownloadTCSGE
 {
-    U8                      Reserved;
-    U8                      ContextSize;
-    U8                      DetailsLength;
-    U8                      Flags;
-    U32                     Reserved1;
-    U32                     ImageOffset;
-    U32                     ImageSize;
+    U8                      Reserved;                   /* 00h */
+    U8                      ContextSize;                /* 01h */
+    U8                      DetailsLength;              /* 02h */
+    U8                      Flags;                      /* 03h */
+    U32                     Reserved1;                  /* 04h */
+    U32                     ImageOffset;                /* 08h */
+    U32                     ImageSize;                  /* 0Ch */
 } FW_DOWNLOAD_TCSGE, MPI_POINTER PTR_FW_DOWNLOAD_TCSGE,
   FWDownloadTCSGE_t, MPI_POINTER pFWDownloadTCSGE_t;
 
 /* Firmware Download reply */
 typedef struct _MSG_FW_DOWNLOAD_REPLY
 {
-    U8                      ImageType;
-    U8                      Reserved;
-    U8                      MsgLength;
-    U8                      Function;
-    U8                      Reserved1[3];
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved2;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
+    U8                      ImageType;                  /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Reserved1[3];               /* 04h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     Reserved2;                  /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
 } MSG_FW_DOWNLOAD_REPLY, MPI_POINTER PTR_MSG_FW_DOWNLOAD_REPLY,
   FWDownloadReply_t, MPI_POINTER pFWDownloadReply_t;
 
@@ -492,14 +505,14 @@ typedef struct _MSG_FW_DOWNLOAD_REPLY
 
 typedef struct _MSG_FW_UPLOAD
 {
-    U8                      ImageType;
-    U8                      Reserved;
-    U8                      ChainOffset;
-    U8                      Function;
-    U8                      Reserved1[3];
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    SGE_MPI_UNION           SGL;
+    U8                      ImageType;                  /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Reserved1[3];               /* 04h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    SGE_MPI_UNION           SGL;                        /* 0Ch */
 } MSG_FW_UPLOAD, MPI_POINTER PTR_MSG_FW_UPLOAD,
   FWUpload_t, MPI_POINTER pFWUpload_t;
 
@@ -510,74 +523,88 @@ typedef struct _MSG_FW_UPLOAD
 
 typedef struct _FWUploadTCSGE
 {
-    U8                      Reserved;
-    U8                      ContextSize;
-    U8                      DetailsLength;
-    U8                      Flags;
-    U32                     Reserved1;
-    U32                     ImageOffset;
-    U32                     ImageSize;
+    U8                      Reserved;                   /* 00h */
+    U8                      ContextSize;                /* 01h */
+    U8                      DetailsLength;              /* 02h */
+    U8                      Flags;                      /* 03h */
+    U32                     Reserved1;                  /* 04h */
+    U32                     ImageOffset;                /* 08h */
+    U32                     ImageSize;                  /* 0Ch */
 } FW_UPLOAD_TCSGE, MPI_POINTER PTR_FW_UPLOAD_TCSGE,
   FWUploadTCSGE_t, MPI_POINTER pFWUploadTCSGE_t;
 
 /* Firmware Upload reply */
 typedef struct _MSG_FW_UPLOAD_REPLY
 {
-    U8                      ImageType;
-    U8                      Reserved;
-    U8                      MsgLength;
-    U8                      Function;
-    U8                      Reserved1[3];
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved2;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
-    U32                     ActualImageSize;
+    U8                      ImageType;                  /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      Reserved1[3];               /* 04h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     Reserved2;                  /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
+    U32                     ActualImageSize;            /* 14h */
 } MSG_FW_UPLOAD_REPLY, MPI_POINTER PTR_MSG_FW_UPLOAD_REPLY,
   FWUploadReply_t, MPI_POINTER pFWUploadReply_t;
 
 
 typedef struct _MPI_FW_HEADER
 {
-    U32                     ArmBranchInstruction0;
-    U32                     Signature0;
-    U32                     Signature1;
-    U32                     Signature2;
-    U32                     ArmBranchInstruction1;
-    U32                     ArmBranchInstruction2;
-    U32                     Reserved;
-    U32                     Checksum;
-    U16                     VendorId;
-    U16                     ProductId;
-    U16                     FwVersion;
-    U16                     Reserved1;
-    U32                     SeqCodeVersion;
-    U32                     ImageSize;
-    U32                     Reserved2;
-    U32                     LoadStartAddress;
-    U32                     IopResetVectorValue;
-    U32                     IopResetRegAddr;
-    U32                     VersionNameWhat;
-    U8                      VersionName[32];
-    U32                     VendorNameWhat;
-    U8                      VendorName[32];
+    U32                     ArmBranchInstruction0;      /* 00h */
+    U32                     Signature0;                 /* 04h */
+    U32                     Signature1;                 /* 08h */
+    U32                     Signature2;                 /* 0Ch */
+    U32                     ArmBranchInstruction1;      /* 10h */
+    U32                     ArmBranchInstruction2;      /* 14h */
+    U32                     Reserved;                   /* 18h */
+    U32                     Checksum;                   /* 1Ch */
+    U16                     VendorId;                   /* 20h */
+    U16                     ProductId;                  /* 22h */
+    U16                     FwVersion;                  /* 24h */
+    U16                     Reserved1;                  /* 26h */
+    U32                     SeqCodeVersion;             /* 28h */
+    U32                     ImageSize;                  /* 2Ch */
+    U32                     Reserved2;                  /* 30h */
+    U32                     LoadStartAddress;           /* 34h */
+    U32                     IopResetVectorValue;        /* 38h */
+    U32                     IopResetRegAddr;            /* 3Ch */
+    U32                     VersionNameWhat;            /* 40h */
+    U8                      VersionName[32];            /* 44h */
+    U32                     VendorNameWhat;             /* 64h */
+    U8                      VendorName[32];             /* 68h */
 } MPI_FW_HEADER, MPI_POINTER PTR_MPI_FW_HEADER,
   MpiFwHeader_t, MPI_POINTER pMpiFwHeader_t;
 
-#define MPI_FW_HEADER_WHAT_SIGNATURE    (0x29232840)
+#define MPI_FW_HEADER_WHAT_SIGNATURE        (0x29232840)
+
+/* defines for using the ProductId field */
+#define MPI_FW_HEADER_PID_TYPE_MASK         (0xF000)
+#define MPI_FW_HEADER_PID_TYPE_SCSI         (0x0000)
+#define MPI_FW_HEADER_PID_TYPE_FC           (0x1000)
+
+#define MPI_FW_HEADER_PID_FW_VENDOR_MASK    (0x0F00)
+#define MPI_FW_HEADER_PID_FW_VENDOR_LSI     (0x0000)
+
+#define MPI_FW_HEADER_PID_FAMILY_MASK       (0x000F)
+#define MPI_FW_HEADER_PID_FAMILY_1030_SCSI  (0x0000)
+#define MPI_FW_HEADER_PID_FAMILY_909_FC     (0x0000)
+#define MPI_FW_HEADER_PID_FAMILY_919_FC     (0x0001)
+#define MPI_FW_HEADER_PID_FAMILY_919X_FC    (0x0002)
 
 
 typedef struct _MPI_DATA_HEADER
 {
-    U32                     Signature;
-    U16                     FunctionNumber;
-    U16                     Length;
-    U32                     Checksum;
-    U32                     LoadStartAddress;
+    U32                     Signature;                  /* 00h */
+    U16                     FunctionNumber;             /* 04h */
+    U16                     Length;                     /* 06h */
+    U32                     Checksum;                   /* 08h */
+    U32                     LoadStartAddress;           /* 0Ch */
 } MPI_DATA_HEADER, MPI_POINTER PTR_MPI_DATA_HEADER,
   MpiDataHeader_t, MPI_POINTER pMpiDataHeader_t;
 
-#define MPI_DATA_HEADER_SIGNATURE       (0x43504147)
+#define MPI_DATA_HEADER_SIGNATURE           (0x43504147)
 
 #endif
index 86d15dc25996a033aebe983a62c52284f2327d90..f5a3bb0bf3d6257df655239928937b283862fb05 100644 (file)
@@ -6,7 +6,7 @@
  *          Title:  MPI LAN messages and structures
  *  Creation Date:  June 30, 2000
  *
- *    MPI Version:  01.01.02
+ *    MPI Version:  01.01.03
  *
  *  Version History
  *  ---------------
@@ -26,6 +26,7 @@
  *                      to lan private header file
  *  11-02-00  01.01.01  Original release for post 1.0 work
  *  02-20-01  01.01.02  Started using MPI_POINTER.
+ *  03-27-01  01.01.03  Added structure offset comments.
  *  --------------------------------------------------------------------------
  */
 
 
 typedef struct _MSG_LAN_SEND_REQUEST
 {
-    U16                     Reserved;
-    U8                      ChainOffset;
-    U8                      Function;
-    U16                     Reserved2;
-    U8                      PortNumber;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    SGE_MPI_UNION           SG_List[1];
+    U16                     Reserved;           /* 00h */
+    U8                      ChainOffset;        /* 02h */
+    U8                      Function;           /* 03h */
+    U16                     Reserved2;          /* 04h */
+    U8                      PortNumber;         /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    SGE_MPI_UNION           SG_List[1];         /* 0Ch */
 } MSG_LAN_SEND_REQUEST, MPI_POINTER PTR_MSG_LAN_SEND_REQUEST,
   LANSendRequest_t, MPI_POINTER pLANSendRequest_t;
 
 
 typedef struct _MSG_LAN_SEND_REPLY
 {
-    U16                     Reserved;
-    U8                      MsgLength;
-    U8                      Function;
-    U8                      Reserved2;
-    U8                      NumberOfContexts;
-    U8                      PortNumber;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved3;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
-    U32                     BufferContext;
+    U16                     Reserved;           /* 00h */
+    U8                      MsgLength;          /* 02h */
+    U8                      Function;           /* 03h */
+    U8                      Reserved2;          /* 04h */
+    U8                      NumberOfContexts;   /* 05h */
+    U8                      PortNumber;         /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U16                     Reserved3;          /* 0Ch */
+    U16                     IOCStatus;          /* 0Eh */
+    U32                     IOCLogInfo;         /* 10h */
+    U32                     BufferContext;      /* 14h */
 } MSG_LAN_SEND_REPLY, MPI_POINTER PTR_MSG_LAN_SEND_REPLY,
   LANSendReply_t, MPI_POINTER pLANSendReply_t;
 
@@ -77,36 +78,36 @@ typedef struct _MSG_LAN_SEND_REPLY
 
 typedef struct _MSG_LAN_RECEIVE_POST_REQUEST
 {
-    U16                     Reserved;
-    U8                      ChainOffset;
-    U8                      Function;
-    U16                     Reserved2;
-    U8                      PortNumber;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U32                     BucketCount;
-    SGE_MPI_UNION           SG_List[1];
+    U16                     Reserved;           /* 00h */
+    U8                      ChainOffset;        /* 02h */
+    U8                      Function;           /* 03h */
+    U16                     Reserved2;          /* 04h */
+    U8                      PortNumber;         /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U32                     BucketCount;        /* 0Ch */
+    SGE_MPI_UNION           SG_List[1];         /* 10h */
 } MSG_LAN_RECEIVE_POST_REQUEST, MPI_POINTER PTR_MSG_LAN_RECEIVE_POST_REQUEST,
   LANReceivePostRequest_t, MPI_POINTER pLANReceivePostRequest_t;
 
 
 typedef struct _MSG_LAN_RECEIVE_POST_REPLY
 {
-    U16                     Reserved;
-    U8                      MsgLength;
-    U8                      Function;
-    U8                      Reserved2;
-    U8                      NumberOfContexts;
-    U8                      PortNumber;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved3;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
-    U32                     BucketsRemaining;
-    U32                     PacketOffset;
-    U32                     PacketLength;
-    U32                     BucketContext[1];
+    U16                     Reserved;           /* 00h */
+    U8                      MsgLength;          /* 02h */
+    U8                      Function;           /* 03h */
+    U8                      Reserved2;          /* 04h */
+    U8                      NumberOfContexts;   /* 05h */
+    U8                      PortNumber;         /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U16                     Reserved3;          /* 0Ch */
+    U16                     IOCStatus;          /* 0Eh */
+    U32                     IOCLogInfo;         /* 10h */
+    U32                     BucketsRemaining;   /* 14h */
+    U32                     PacketOffset;       /* 18h */
+    U32                     PacketLength;       /* 1Ch */
+    U32                     BucketContext[1];   /* 20h */
 } MSG_LAN_RECEIVE_POST_REPLY, MPI_POINTER PTR_MSG_LAN_RECEIVE_POST_REPLY,
   LANReceivePostReply_t, MPI_POINTER pLANReceivePostReply_t;
 
@@ -115,29 +116,29 @@ typedef struct _MSG_LAN_RECEIVE_POST_REPLY
 
 typedef struct _MSG_LAN_RESET_REQUEST
 {
-    U16                     Reserved;
-    U8                      ChainOffset;
-    U8                      Function;
-    U16                     Reserved2;
-    U8                      PortNumber;
-    U8                      MsgFlags;
-    U32                     MsgContext;
+    U16                     Reserved;           /* 00h */
+    U8                      ChainOffset;        /* 02h */
+    U8                      Function;           /* 03h */
+    U16                     Reserved2;          /* 04h */
+    U8                      PortNumber;         /* 05h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
 } MSG_LAN_RESET_REQUEST, MPI_POINTER PTR_MSG_LAN_RESET_REQUEST,
   LANResetRequest_t, MPI_POINTER pLANResetRequest_t;
 
 
 typedef struct _MSG_LAN_RESET_REPLY
 {
-    U16                     Reserved;
-    U8                      MsgLength;
-    U8                      Function;
-    U16                     Reserved2;
-    U8                      PortNumber;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved3;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
+    U16                     Reserved;           /* 00h */
+    U8                      MsgLength;          /* 02h */
+    U8                      Function;           /* 03h */
+    U16                     Reserved2;          /* 04h */
+    U8                      PortNumber;         /* 06h */
+    U8                      MsgFlags;           /* 07h */
+    U32                     MsgContext;         /* 08h */
+    U16                     Reserved3;          /* 0Ch */
+    U16                     IOCStatus;          /* 0Eh */
+    U32                     IOCLogInfo;         /* 10h */
 } MSG_LAN_RESET_REPLY, MPI_POINTER PTR_MSG_LAN_RESET_REPLY,
   LANResetReply_t, MPI_POINTER pLANResetReply_t;
 
@@ -200,5 +201,11 @@ typedef struct _MSG_LAN_RESET_REPLY
 #define MPI_LAN_DEVICE_STATE_OPERATIONAL               (0x01)
 
 
+/****************************************************************************/
+/* LAN Loopback defines                                                     */
+/****************************************************************************/
+
+#define MPI_LAN_TX_MODES_ENABLE_LOOPBACK_SUPPRESSION   (0x01)
+
 #endif
 
index 8b0d74a2b64c90a70c23db103c620bc670e445e5..1f24a957f5c71f00efaceb585e6a19c2b8d150fe 100644 (file)
@@ -6,7 +6,7 @@
  *          Title:  MPI Target mode messages and structures
  *  Creation Date:  June 22, 2000
  *
- *    MPI Version:  01.01.03
+ *    MPI Version:  01.01.04
  *
  *  Version History
  *  ---------------
@@ -25,6 +25,7 @@
  *  02-20-01  01.01.03  Started using MPI_POINTER.
  *                      Added structures for MPI_TARGET_SCSI_SPI_CMD_BUFFER and
  *                      MPI_TARGET_FCP_CMD_BUFFER.
+ *  03-27-01  01.01.04  Added structure offset comments.
  *  --------------------------------------------------------------------------
  */
 
@@ -40,9 +41,9 @@
 
 typedef struct _CMD_BUFFER_DESCRIPTOR
 {
-    U16                     IoIndex;
-    U16                     Reserved;
-    union
+    U16                     IoIndex;                    /* 00h */
+    U16                     Reserved;                   /* 02h */
+    union                                               /* 04h */
     {
         U32                 PhysicalAddress32;
         U64                 PhysicalAddress64;
@@ -57,16 +58,16 @@ typedef struct _CMD_BUFFER_DESCRIPTOR
 
 typedef struct _MSG_TARGET_CMD_BUFFER_POST_REQUEST
 {
-    U8                      BufferPostFlags;
-    U8                      BufferCount;
-    U8                      ChainOffset;
-    U8                      Function;
-    U8                      BufferLength;
-    U8                      Reserved;
-    U8                      Reserved1;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    CMD_BUFFER_DESCRIPTOR   Buffer[1];
+    U8                      BufferPostFlags;            /* 00h */
+    U8                      BufferCount;                /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      BufferLength;               /* 04h */
+    U8                      Reserved;                   /* 05h */
+    U8                      Reserved1;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    CMD_BUFFER_DESCRIPTOR   Buffer[1];                  /* 0Ch */
 } MSG_TARGET_CMD_BUFFER_POST_REQUEST, MPI_POINTER PTR_MSG_TARGET_CMD_BUFFER_POST_REQUEST,
   TargetCmdBufferPostRequest_t, MPI_POINTER pTargetCmdBufferPostRequest_t;
 
@@ -81,36 +82,36 @@ typedef struct _MSG_TARGET_CMD_BUFFER_POST_REQUEST
 
 typedef struct _MSG_TARGET_CMD_BUFFER_POST_REPLY
 {
-    U8                      BufferPostFlags;
-    U8                      BufferCount;
-    U8                      MsgLength;
-    U8                      Function;
-    U8                      BufferLength;
-    U8                      Reserved;
-    U8                      Reserved1;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved2;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
+    U8                      BufferPostFlags;            /* 00h */
+    U8                      BufferCount;                /* 01h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U8                      BufferLength;               /* 04h */
+    U8                      Reserved;                   /* 05h */
+    U8                      Reserved1;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     Reserved2;                  /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
 } MSG_TARGET_CMD_BUFFER_POST_REPLY, MPI_POINTER PTR_MSG_TARGET_CMD_BUFFER_POST_REPLY,
   TargetCmdBufferPostReply_t, MPI_POINTER pTargetCmdBufferPostReply_t;
 
 
 typedef struct _MSG_PRIORITY_CMD_RECEIVED_REPLY
 {
-    U16                     Reserved;
-    U8                      MsgLength;
-    U8                      Function;
-    U16                     Reserved1;
-    U8                      Reserved2;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U8                      PriorityReason;
-    U8                      Reserved3;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
-    U32                     ReplyWord;
+    U16                     Reserved;                   /* 00h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved1;                  /* 04h */
+    U8                      Reserved2;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U8                      PriorityReason;             /* 0Ch */
+    U8                      Reserved3;                  /* 0Dh */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
+    U32                     ReplyWord;                  /* 14h */
 } MSG_PRIORITY_CMD_RECEIVED_REPLY, MPI_POINTER PTR_MSG_PRIORITY_CMD_RECEIVED_REPLY,
   PriorityCommandReceivedReply_t, MPI_POINTER pPriorityCommandReceivedReply_t;
 
@@ -121,17 +122,17 @@ typedef struct _MSG_PRIORITY_CMD_RECEIVED_REPLY
 
 typedef struct _MSG_TARGET_CMD_BUFFER_POST_ERROR_REPLY
 {
-    U16                     Reserved;
-    U8                      MsgLength;
-    U8                      Function;
-    U16                     Reserved1;
-    U8                      Reserved2;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved3;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
-    U32                     ReplyWord;
+    U16                     Reserved;                   /* 00h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved1;                  /* 04h */
+    U8                      Reserved2;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     Reserved3;                  /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
+    U32                     ReplyWord;                  /* 14h */
 } MSG_TARGET_CMD_BUFFER_POST_ERROR_REPLY,
   MPI_POINTER PTR_MSG_TARGET_CMD_BUFFER_POST_ERROR_REPLY,
   TargetCmdBufferPostErrorReply_t, MPI_POINTER pTargetCmdBufferPostErrorReply_t;
@@ -139,10 +140,10 @@ typedef struct _MSG_TARGET_CMD_BUFFER_POST_ERROR_REPLY
 
 typedef struct _MPI_TARGET_FCP_CMD_BUFFER
 {
-    U8      FcpLun[8];
-    U8      FcpCntl[4];
-    U8      FcpCdb[16];
-    U32     FcpDl;
+    U8      FcpLun[8];                                  /* 00h */
+    U8      FcpCntl[4];                                 /* 08h */
+    U8      FcpCdb[16];                                 /* 0Ch */
+    U32     FcpDl;                                      /* 1Ch */
 } MPI_TARGET_FCP_CMD_BUFFER, MPI_POINTER PTR_MPI_TARGET_FCP_CMD_BUFFER,
   MpiTargetFcpCmdBuffer, MPI_POINTER pMpiTargetFcpCmdBuffer;
 
@@ -150,17 +151,17 @@ typedef struct _MPI_TARGET_FCP_CMD_BUFFER
 typedef struct _MPI_TARGET_SCSI_SPI_CMD_BUFFER
 {
     /* SPI L_Q information unit */
-    U8      L_QType;
-    U8      Reserved;
-    U16     Tag;
-    U8      LogicalUnitNumber[8];
-    U32     DataLength;
+    U8      L_QType;                                    /* 00h */
+    U8      Reserved;                                   /* 01h */
+    U16     Tag;                                        /* 02h */
+    U8      LogicalUnitNumber[8];                       /* 04h */
+    U32     DataLength;                                 /* 0Ch */
     /* SPI command information unit */
-    U8      ReservedFirstByteOfCommandIU;
-    U8      TaskAttribute;
-    U8      TaskManagementFlags;
-    U8      AdditionalCDBLength;
-    U8      CDB[16];
+    U8      ReservedFirstByteOfCommandIU;               /* 10h */
+    U8      TaskAttribute;                              /* 11h */
+    U8      TaskManagementFlags;                        /* 12h */
+    U8      AdditionalCDBLength;                        /* 13h */
+    U8      CDB[16];                                    /* 14h */
 } MPI_TARGET_SCSI_SPI_CMD_BUFFER,
   MPI_POINTER PTR_MPI_TARGET_SCSI_SPI_CMD_BUFFER,
   MpiTargetScsiSpiCmdBuffer, MPI_POINTER pMpiTargetScsiSpiCmdBuffer;
@@ -172,19 +173,19 @@ typedef struct _MPI_TARGET_SCSI_SPI_CMD_BUFFER
 
 typedef struct _MSG_TARGET_ASSIST_REQUEST
 {
-    U8                      StatusCode;
-    U8                      TargetAssistFlags;
-    U8                      ChainOffset;
-    U8                      Function;
-    U16                     QueueTag;
-    U8                      Reserved;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U32                     ReplyWord;
-    U8                      LUN[8];
-    U32                     RelativeOffset;
-    U32                     DataLength;
-    SGE_IO_UNION            SGL[1];
+    U8                      StatusCode;                 /* 00h */
+    U8                      TargetAssistFlags;          /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     QueueTag;                   /* 04h */
+    U8                      Reserved;                   /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U32                     ReplyWord;                  /* 0Ch */
+    U8                      LUN[8];                     /* 10h */
+    U32                     RelativeOffset;             /* 18h */
+    U32                     DataLength;                 /* 1Ch */
+    SGE_IO_UNION            SGL[1];                     /* 20h */
 } MSG_TARGET_ASSIST_REQUEST, MPI_POINTER PTR_MSG_TARGET_ASSIST_REQUEST,
   TargetAssistRequest_t, MPI_POINTER pTargetAssistRequest_t;
 
@@ -196,18 +197,18 @@ typedef struct _MSG_TARGET_ASSIST_REQUEST
 
 typedef struct _MSG_TARGET_ERROR_REPLY
 {
-    U16                     Reserved;
-    U8                      MsgLength;
-    U8                      Function;
-    U16                     Reserved1;
-    U8                      Reserved2;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved3;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
-    U32                     ReplyWord;
-    U32                     TransferCount;
+    U16                     Reserved;                   /* 00h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved1;                  /* 04h */
+    U8                      Reserved2;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     Reserved3;                  /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
+    U32                     ReplyWord;                  /* 14h */
+    U32                     TransferCount;              /* 18h */
 } MSG_TARGET_ERROR_REPLY, MPI_POINTER PTR_MSG_TARGET_ERROR_REPLY,
   TargetErrorReply_t, MPI_POINTER pTargetErrorReply_t;
 
@@ -218,17 +219,17 @@ typedef struct _MSG_TARGET_ERROR_REPLY
 
 typedef struct _MSG_TARGET_STATUS_SEND_REQUEST
 {
-    U8                      StatusCode;
-    U8                      StatusFlags;
-    U8                      ChainOffset;
-    U8                      Function;
-    U16                     QueueTag;
-    U8                      Reserved;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U32                     ReplyWord;
-    U8                      LUN[8];
-    SGE_SIMPLE_UNION        StatusDataSGE;
+    U8                      StatusCode;                 /* 00h */
+    U8                      StatusFlags;                /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     QueueTag;                   /* 04h */
+    U8                      Reserved;                   /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U32                     ReplyWord;                  /* 0Ch */
+    U8                      LUN[8];                     /* 10h */
+    SGE_SIMPLE_UNION        StatusDataSGE;              /* 18h */
 } MSG_TARGET_STATUS_SEND_REQUEST, MPI_POINTER PTR_MSG_TARGET_STATUS_SEND_REQUEST,
   TargetStatusSendRequest_t, MPI_POINTER pTargetStatusSendRequest_t;
 
@@ -242,16 +243,16 @@ typedef struct _MSG_TARGET_STATUS_SEND_REQUEST
 
 typedef struct _MSG_TARGET_MODE_ABORT_REQUEST
 {
-    U8                      AbortType;
-    U8                      Reserved;
-    U8                      ChainOffset;
-    U8                      Function;
-    U16                     Reserved1;
-    U8                      Reserved2;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U32                     ReplyWord;
-    U32                     MsgContextToAbort;
+    U8                      AbortType;                  /* 00h */
+    U8                      Reserved;                   /* 01h */
+    U8                      ChainOffset;                /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved1;                  /* 04h */
+    U8                      Reserved2;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U32                     ReplyWord;                  /* 0Ch */
+    U32                     MsgContextToAbort;          /* 10h */
 } MSG_TARGET_MODE_ABORT, MPI_POINTER PTR_MSG_TARGET_MODE_ABORT,
   TargetModeAbort_t, MPI_POINTER pTargetModeAbort_t;
 
@@ -264,17 +265,17 @@ typedef struct _MSG_TARGET_MODE_ABORT_REQUEST
 
 typedef struct _MSG_TARGET_MODE_ABORT_REPLY
 {
-    U16                     Reserved;
-    U8                      MsgLength;
-    U8                      Function;
-    U16                     Reserved1;
-    U8                      Reserved2;
-    U8                      MsgFlags;
-    U32                     MsgContext;
-    U16                     Reserved3;
-    U16                     IOCStatus;
-    U32                     IOCLogInfo;
-    U32                     AbortCount;
+    U16                     Reserved;                   /* 00h */
+    U8                      MsgLength;                  /* 02h */
+    U8                      Function;                   /* 03h */
+    U16                     Reserved1;                  /* 04h */
+    U8                      Reserved2;                  /* 06h */
+    U8                      MsgFlags;                   /* 07h */
+    U32                     MsgContext;                 /* 08h */
+    U16                     Reserved3;                  /* 0Ch */
+    U16                     IOCStatus;                  /* 0Eh */
+    U32                     IOCLogInfo;                 /* 10h */
+    U32                     AbortCount;                 /* 14h */
 } MSG_TARGET_MODE_ABORT_REPLY, MPI_POINTER PTR_MSG_TARGET_MODE_ABORT_REPLY,
   TargetModeAbortReply_t, MPI_POINTER pTargetModeAbortReply_t;
 
index 0ada7fe6e63250b4d6b8d8e093639d7e2891c4c9..0e3cd3fb4ee3e3dc7389e5ddf64d11fc8842eeaa 100644 (file)
@@ -42,7 +42,7 @@
  *  Originally By: Steven J. Ralston
  *  (mailto:Steve.Ralston@lsil.com)
  *
- *  $Id: mptbase.c,v 1.47 2001/03/22 10:32:23 sralston Exp $
+ *  $Id: mptbase.c,v 1.53.4.1 2001/08/24 20:07:05 sralston Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -130,6 +130,8 @@ void *mpt_v_ASCQ_TablePtr = NULL;
 const char **mpt_ScsiOpcodesPtr = NULL;
 int mpt_ASCQ_TableSz = 0;
 
+#define WHOINIT_UNKNOWN                0xAA
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *  Private data...
@@ -143,6 +145,8 @@ static MPT_CALLBACK          MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
 static int                      MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
                                        /* Event handler lookup table */
 static MPT_EVHANDLER            MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
+                                       /* Reset handler lookup table */
+static MPT_RESETHANDLER                 MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
 
 static int     FusionInitCalled = 0;
 static int     mpt_base_index = -1;
@@ -154,25 +158,27 @@ static int        mpt_base_index = -1;
 static void    mpt_interrupt(int irq, void *bus_id, struct pt_regs *r);
 static int     mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
 
+static int     mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason);
 static int     mpt_adapter_install(struct pci_dev *pdev);
 static void    mpt_detect_929_bound_ports(MPT_ADAPTER *this, struct pci_dev *pdev);
-static void    mpt_adapter_disable(MPT_ADAPTER *ioc);
+static void    mpt_adapter_disable(MPT_ADAPTER *ioc, int freeup);
 static void    mpt_adapter_dispose(MPT_ADAPTER *ioc);
 
 static void    MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
+static int     MakeIocReady(MPT_ADAPTER *ioc, int force);
 static u32     GetIocState(MPT_ADAPTER *ioc, int cooked);
 static int     GetIocFacts(MPT_ADAPTER *ioc);
-static int     GetPortFacts(MPT_ADAPTER *ioc);
+static int     GetPortFacts(MPT_ADAPTER *ioc, int portnum);
 static int     SendIocInit(MPT_ADAPTER *ioc);
 static int     SendPortEnable(MPT_ADAPTER *ioc, int portnum);
-static int     mpt_fc9x9_reset(MPT_ADAPTER *ioc);
-static int     KickStart(MPT_ADAPTER *ioc);
+static int     mpt_fc9x9_reset(MPT_ADAPTER *ioc, int ignore);
+static int     KickStart(MPT_ADAPTER *ioc, int ignore);
 static int     SendIocReset(MPT_ADAPTER *ioc, u8 reset_type);
 static int     PrimeIocFifos(MPT_ADAPTER *ioc);
-static int     HandShakeReqAndReply(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u16 *u16reply);
-static int     WaitForDoorbellAck(MPT_ADAPTER *ioc);
-static int     WaitForDoorbellInt(MPT_ADAPTER *ioc);
-static int     WaitForDoorbellReply(MPT_ADAPTER *ioc);
+static int     HandShakeReqAndReply(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u16 *u16reply, int maxwait);
+static int     WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong);
+static int     WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong);
+static int     WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong);
 static int     GetLanConfigPages(MPT_ADAPTER *ioc);
 static int     SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
 static int     SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
@@ -192,6 +198,7 @@ static void mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info);
 static struct proc_dir_entry   *procmpt_root_dir = NULL;
 
 int            fusion_init(void);
+static void    fusion_exit(void);
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /* 20000207 -sralston
@@ -584,6 +591,45 @@ mpt_event_deregister(int cb_idx)
        MptEvHandlers[cb_idx] = NULL;
 }
 
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *     mpt_reset_register - Register protocol-specific IOC reset handler.
+ *     @cb_idx: previously registered (via mpt_register) callback handle
+ *     @reset_func: reset function
+ *
+ *     This routine can be called by one or more protocol-specific drivers
+ *     if/when they choose to be notified of IOC resets.
+ *
+ *     Returns 0 for success.
+ */
+int
+mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
+{
+       if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
+               return -1;
+
+       MptResetHandlers[cb_idx] = reset_func;
+       return 0;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *     mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
+ *     @cb_idx: previously registered callback handle
+ *
+ *     Each protocol-specific driver should call this routine
+ *     when it does not (or can no longer) handle IOC reset handling,
+ *     or when it's module is unloaded.
+ */
+void
+mpt_reset_deregister(int cb_idx)
+{
+       if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
+               return;
+
+       MptResetHandlers[cb_idx] = NULL;
+}
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
  *     mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
@@ -723,13 +769,29 @@ mpt_send_handshake_request(int handle, int iocid, int reqBytes, u32 *req)
 
        iocp = mpt_adapters[iocid];
        if (iocp != NULL) {
-               u8 *req_as_bytes;
-               int i;
+               u8              *req_as_bytes;
+               u32              ioc_raw_state;
+               int              i;
+
+               /* YIKES!  We already know something is amiss.
+                * Do upfront check on IOC state.
+                */
+               ioc_raw_state = GetIocState(iocp, 0);
+               if ((ioc_raw_state & MPI_DOORBELL_ACTIVE) ||
+                   ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL)) {
+                       printk(KERN_WARNING MYNAM ": %s: Bad IOC state (%08x) WARNING!\n",
+                                       iocp->name, ioc_raw_state);
+                       if ((r = mpt_do_ioc_recovery(iocp, MPT_HOSTEVENT_IOC_RECOVER)) != 0) {
+                               printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
+                                               r, iocp->name);
+                               return r;
+                       }
+               }
 
                /*
-                *  Emulate what mpt_put_msg_frame() does /wrt to sanity
-                *  setting cb_idx/req_idx.  But ONLY if this request
-                *  is in proper (pre-alloc'd) request buffer range...
+                * Emulate what mpt_put_msg_frame() does /wrt to sanity
+                * setting cb_idx/req_idx.  But ONLY if this request
+                * is in proper (pre-alloc'd) request buffer range...
                 */
                i = MFPTR_2_MPT_INDEX(iocp,(MPT_FRAME_HDR*)req);
                if (reqBytes >= 12 && i >= 0 && i < iocp->req_depth) {
@@ -738,17 +800,15 @@ mpt_send_handshake_request(int handle, int iocid, int reqBytes, u32 *req)
                        mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
                }
 
-               /*  Make sure there are no doorbells  */
+               /* Make sure there are no doorbells */
                CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
 
                CHIPREG_WRITE32(&iocp->chip->Doorbell,
                                ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
                                 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
 
-               /*  Wait for IOC doorbell int  */
-               if ((i = WaitForDoorbellInt(iocp)) < 0) {
-                       /* FIXME! Recovery action(s)? */
-                       /*i = unresponsive_ioc(i);*/
+               /* Wait for IOC doorbell int */
+               if ((i = WaitForDoorbellInt(iocp, 2)) < 0) {
                        return i;
                }
 
@@ -757,10 +817,11 @@ mpt_send_handshake_request(int handle, int iocid, int reqBytes, u32 *req)
 
                CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
 
-               if ((r = WaitForDoorbellAck(iocp)) < 0)
+               if ((r = WaitForDoorbellAck(iocp, 1)) < 0) {
                        return -2;
+               }
 
-               /*  Send request via doorbell handshake  */
+               /* Send request via doorbell handshake */
                req_as_bytes = (u8 *) req;
                for (i = 0; i < reqBytes/4; i++) {
                        u32 word;
@@ -770,15 +831,19 @@ mpt_send_handshake_request(int handle, int iocid, int reqBytes, u32 *req)
                                (req_as_bytes[(i*4) + 2] << 16) |
                                (req_as_bytes[(i*4) + 3] << 24));
                        CHIPREG_WRITE32(&iocp->chip->Doorbell, word);
-                       if ((r = WaitForDoorbellAck(iocp)) < 0) {
+                       if ((r = WaitForDoorbellAck(iocp, 1)) < 0) {
                                r = -3;
                                break;
                        }
                }
 
-               /*  Make sure there are no doorbells  */
-               CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
+               if ((r = WaitForDoorbellInt(iocp, 2)) >= 0)
+                       r = 0;
+               else
+                       r = -4;
 
+               /* Make sure there are no doorbells */
+               CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
        }
 
        return r;
@@ -849,9 +914,8 @@ mpt_pci_scan(void)
 
                if ((pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC909) &&
                    (pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC929) &&
-#if 0
-                   /* FIXME! FC919 */
                    (pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC919) &&
+#if 0
                    /* FIXME! C103x family */
                    (pdev->device != MPI_MANUFACTPAGE_DEVID_53C1030) &&
                    (pdev->device != MPI_MANUFACTPAGE_DEVID_53C1030_ZC) &&
@@ -897,8 +961,10 @@ mpt_pci_scan(void)
        printk(KERN_INFO MYNAM ": %d MPT adapter%s found, %d installed.\n",
                 found, (found==1) ? "" : "s", count);
 
-       if (count == 0)
+       if (!found || !count) {
+               fusion_exit();
                return -ENODEV;
+       }
 
 #ifdef CONFIG_PROC_FS
        if (procmpt_create() != 0)
@@ -962,12 +1028,9 @@ mpt_adapter_install(struct pci_dev *pdev)
        unsigned long    port;
        u32              msize;
        u32              psize;
-       u32              ioc_state;
        int              i;
        int              r = -ENODEV;
-       int              cntdn;
        int              len;
-       int              statefault = 0;
 
        ioc = kmalloc(sizeof(MPT_ADAPTER), GFP_KERNEL);
        if (ioc == NULL) {
@@ -980,7 +1043,7 @@ mpt_adapter_install(struct pci_dev *pdev)
 
        ioc->pcidev = pdev;
 
-       /*  Find lookup slot.  GRRRR...  */
+       /* Find lookup slot. */
        for (i=0; i < MPT_MAX_ADAPTERS; i++) {
                if (mpt_adapters[i] == NULL) {
                        ioc->id = i;            /* Assign adapter unique id (lookup) */
@@ -997,11 +1060,11 @@ mpt_adapter_install(struct pci_dev *pdev)
        port = psize = 0;
        for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {
                if (pdev->PCI_BASEADDR_FLAGS(i) & PCI_BASE_ADDRESS_SPACE_IO) {
-                       /*  Get I/O space!  */
+                       /* Get I/O space! */
                        port = pdev->PCI_BASEADDR_START(i);
                        psize = PCI_BASEADDR_SIZE(pdev,i);
                } else {
-                       /*  Get memmap  */
+                       /* Get memmap */
                        mem_phys = pdev->PCI_BASEADDR_START(i);
                        msize = PCI_BASEADDR_SIZE(pdev,i);
                        break;
@@ -1021,7 +1084,7 @@ mpt_adapter_install(struct pci_dev *pdev)
 
        mem = NULL;
        if (! PortIo) {
-               /*  Get logical ptr for PciMem0 space  */
+               /* Get logical ptr for PciMem0 space */
                /*mem = ioremap(mem_phys, msize);*/
                mem = ioremap(mem_phys, 0x100);
                if (mem == NULL) {
@@ -1051,11 +1114,11 @@ mpt_adapter_install(struct pci_dev *pdev)
                ioc->chip_type = FC929;
                ioc->prod_name = "LSIFC929";
        }
-#if 0
        else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {
-               ioc->chip_type = C1030;
+               ioc->chip_type = FC919;
                ioc->prod_name = "LSIFC919";
        }
+#if 0
        else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_53C1030) {
                ioc->chip_type = C1030;
                ioc->prod_name = "LSI53C1030";
@@ -1070,10 +1133,10 @@ mpt_adapter_install(struct pci_dev *pdev)
        Q_INIT(&ioc->FreeQ, MPT_FRAME_HDR);
        spin_lock_init(&ioc->FreeQlock);
 
-       /*  Disable all!  */
+       /* Disable all! */
        CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
-       CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
        ioc->active = 0;
+       CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
 
        ioc->pci_irq = -1;
        if (pdev->irq) {
@@ -1094,7 +1157,7 @@ mpt_adapter_install(struct pci_dev *pdev)
                dprintk((KERN_INFO MYNAM ": %s installed at interrupt %d\n", ioc->name, pdev->irq));
        }
 
-       /*  tack onto tail of our MPT adapter list  */
+       /* tack onto tail of our MPT adapter list */
        Q_ADD_TAIL(&MptAdapters, ioc, MPT_ADAPTER);
 
        /* Set lookup ptr. */
@@ -1106,115 +1169,168 @@ mpt_adapter_install(struct pci_dev *pdev)
        if (ioc->chip_type == FC929)
                mpt_detect_929_bound_ports(ioc, pdev);
 
-       /*  Get current [raw] IOC state  */
-       ioc_state = GetIocState(ioc, 0);
-       dhsprintk((KERN_INFO MYNAM ": %s initial [raw] state=%08x\n", ioc->name, ioc_state));
+       if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP)) != 0) {
+               printk(KERN_WARNING MYNAM ": WARNING - %s did not initialize properly! (%d)\n",
+                               ioc->name, r);
+       }
 
-       /*
-        *  Check to see if IOC got left/stuck in doorbell handshake
-        *  grip of death.  If so, hard reset the IOC.
-        */
-       if (ioc_state & MPI_DOORBELL_ACTIVE) {
-               statefault = 1;
-               printk(KERN_WARNING MYNAM ": %s: Uh-oh, unexpected doorbell active!\n",
+       return r;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *     mpt_do_ioc_recovery - Initialize or recover MPT adapter.
+ *     @ioc: Pointer to MPT adapter structure
+ *     @reason: Event word / reason
+ *
+ *     This routine performs all the steps necessary to bring the IOC
+ *     to a OPERATIONAL state.
+ *
+ *     This routine also pre-fetches the LAN MAC address of a Fibre Channel
+ *     MPT adapter.
+ *
+ *     Returns 0 for success.
+ */
+static int
+mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason)
+{
+       int      hard_reset_done = 0;
+       int      alt_ioc_ready = 0;
+       int      hard;
+       int      r;
+       int      i;
+       int      handlers;
+
+       printk(KERN_INFO MYNAM ": Initiating %s %s\n",
+                       ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
+
+       /* Disable reply interrupts */
+       CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
+       ioc->active = 0;
+       /* NOTE: Access to IOC's request FreeQ is now blocked! */
+
+// FIXME? Cleanup all IOC requests here! (or below?)
+// But watch out for event associated request?
+
+       hard = HardReset;
+       if (ioc->alt_ioc && (reason == MPT_HOSTEVENT_IOC_BRINGUP))
+               hard = 0;
+
+       if ((hard_reset_done = MakeIocReady(ioc, hard)) < 0) {
+               printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
                                ioc->name);
+               return -1;
        }
 
-       /*
-        *  Check to see if IOC is in FAULT state.
-        *  If so, hard reset the IOC.
-        */
-       if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
-               statefault = 2;
-               printk(KERN_WARNING MYNAM ": %s: Uh-oh, IOC is in FAULT state!!!\n",
-                               ioc->name);
-               printk(KERN_WARNING "           FAULT code = %04xh\n",
-                               ioc_state & MPI_DOORBELL_DATA_MASK);
+// NEW!
+#if 0                                          // Kiss-of-death!?!
+       if (ioc->alt_ioc) {
+// Grrr... Hold off any alt-IOC interrupts (and events) while
+// handshaking to <this> IOC, needed because?
+               /* Disable alt-IOC's reply interrupts for a bit ... */
+               alt_ioc_intmask = CHIPREG_READ32(&ioc->alt_ioc->chip->IntMask);
+               CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
+               ioc->alt_ioc->active = 0;
+               /* NOTE: Access to alt-IOC's request FreeQ is now blocked! */
        }
+#endif
 
-       if (HardReset || statefault) {
-               if ((r = KickStart(ioc)) != 0) {
-                       r = -ENODEV;
-                       goto ioc_up_fail;
-               }
+       if (hard_reset_done && ioc->alt_ioc) {
+               if ((r = MakeIocReady(ioc->alt_ioc, 0)) == 0)
+                       alt_ioc_ready = 1;
+               else
+                       printk(KERN_WARNING MYNAM ": alt-%s: (%d) Not ready WARNING!\n",
+                                       ioc->alt_ioc->name, r);
+       }
+
+       if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
+               /* Get IOC facts! */
+               if ((r = GetIocFacts(ioc)) != 0)
+                       return -2;
+               MptDisplayIocCapabilities(ioc);
        }
 
        /*
-        *  Loop here waiting for IOC to come READY.
+        * Call each currently registered protocol IOC reset handler
+        * with pre-reset indication.
+        * NOTE: If we're doing _IOC_BRINGUP, there can be no
+        * MptResetHandlers[] registered yet.
         */
-       i = 0;
-       cntdn = HZ * 10;
-       while ((ioc_state = GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
-               if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
-                       /*
-                        *  BIOS or previous driver load left IOC in OP state.
-                        *  Reset messaging FIFOs.
-                        */
-                       dprintk((KERN_WARNING MYNAM ": %s: Sending IOC msg unit reset!\n", ioc->name));
-                       if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET)) != 0) {
-                               printk(KERN_ERR MYNAM ": %s: ERROR - IOC msg unit reset failed!\n", ioc->name);
-                               r = -ENODEV;
-                               goto ioc_up_fail;
-                       }
-               } else if (ioc_state == MPI_IOC_STATE_RESET) {
-                       /*
-                        *  Something is wrong.  Try to get IOC back
-                        *  to a known state.
-                        */
-                       dprintk((KERN_WARNING MYNAM ": %s: Sending IO unit reset!\n", ioc->name));
-                       if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET)) != 0) {
-                               printk(KERN_ERR MYNAM ": %s: ERROR - IO unit reset failed!\n", ioc->name);
-                               r = -ENODEV;
-                               goto ioc_up_fail;
+       if (hard_reset_done) {
+               r = handlers = 0;
+               for (i=MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
+                       if (MptResetHandlers[i]) {
+                               dprintk((KERN_INFO MYNAM ": %s: Calling IOC pre_reset handler #%d\n",
+                                               ioc->name, i));
+                               r += (*(MptResetHandlers[i]))(ioc, MPT_IOC_PRE_RESET);
+                               handlers++;
+
+                               if (alt_ioc_ready) {
+                                       dprintk((KERN_INFO MYNAM ": %s: Calling alt-IOC pre_reset handler #%d\n",
+                                                       ioc->alt_ioc->name, i));
+                                       r += (*(MptResetHandlers[i]))(ioc->alt_ioc, MPT_IOC_PRE_RESET);
+                                       handlers++;
+                               }
                        }
                }
+               /* FIXME?  Examine results here? */
+       }
 
-               i++; cntdn--;
-               if (!cntdn) {
-                       printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
-                                       ioc->name, (i+5)/HZ);
-                       r = -ETIME;
-                       goto ioc_up_fail;
-               }
+       // May need to check/upload firmware & data here!
 
-               current->state = TASK_INTERRUPTIBLE;
-               schedule_timeout(1);
+       if ((r = SendIocInit(ioc)) != 0)
+               return -3;
+// NEW!
+       if (alt_ioc_ready) {
+               if ((r = SendIocInit(ioc->alt_ioc)) != 0) {
+                       alt_ioc_ready = 0;
+                       printk(KERN_WARNING MYNAM ": alt-%s: (%d) init failure WARNING!\n",
+                                       ioc->alt_ioc->name, r);
+               }
        }
 
-       if (statefault) {
-               printk(KERN_WARNING MYNAM ": %s: Whew!  Recovered from %s\n",
-                               ioc->name, statefault==1 ? "stuck handshake" : "IOC FAULT");
+       /*
+        * Call each currently registered protocol IOC reset handler
+        * with post-reset indication.
+        * NOTE: If we're doing _IOC_BRINGUP, there can be no
+        * MptResetHandlers[] registered yet.
+        */
+       if (hard_reset_done) {
+               r = handlers = 0;
+               for (i=MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
+                       if (MptResetHandlers[i]) {
+                               dprintk((KERN_INFO MYNAM ": %s: Calling IOC post_reset handler #%d\n",
+                                               ioc->name, i));
+                               r += (*(MptResetHandlers[i]))(ioc, MPT_IOC_POST_RESET);
+                               handlers++;
+
+                               if (alt_ioc_ready) {
+                                       dprintk((KERN_INFO MYNAM ": %s: Calling alt-IOC post_reset handler #%d\n",
+                                                       ioc->alt_ioc->name, i));
+                                       r += (*(MptResetHandlers[i]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
+                                       handlers++;
+                               }
+                       }
+               }
+               /* FIXME?  Examine results here? */
        }
 
-       /*  Enable! (reply interrupt)  */
-       CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
-       ioc->active = 1;
-
-       /*  Get IOC facts! (first time, ioc->facts0 and ioc->pfacts0)  */
-       if ((r = GetIocFacts(ioc)) != 0)
-               goto ioc_up_fail;
-
-       /* Does IocFacts.EventState need any looking at / attention here? */
-
-       if ((r = SendIocInit(ioc)) != 0)
-               goto ioc_up_fail;
-
        /*
-        *  Prime reply & request queues!
-        *  (mucho alloc's)
+        * Prime reply & request queues!
+        * (mucho alloc's)
         */
        if ((r = PrimeIocFifos(ioc)) != 0)
-               goto ioc_up_fail;
-
-       /*  Get IOC facts again! (2nd time, ioc->factsN and ioc->pfactsN)  */
-       if ((r = GetIocFacts(ioc)) != 0)
-               goto ioc_up_fail;
-
-       /* Does IocFacts.EventState need any looking at / attention here? */
+               return -4;
+// NEW!
+       if (alt_ioc_ready && ((r = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
+               printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
+                               ioc->alt_ioc->name, r);
+       }
 
-       MptDisplayIocCapabilities(ioc);
+// FIXME! Cleanup all IOC (and alt-IOC?) requests here!
 
-       if (ioc->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
+       if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
+           (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
                /*
                 *  Pre-fetch the ports LAN MAC address!
                 *  (LANPage1_t stuff)
@@ -1229,19 +1345,34 @@ mpt_adapter_install(struct pci_dev *pdev)
 #endif
        }
 
+       /* Enable! (reply interrupt) */
+       CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
+       ioc->active = 1;
+
+// NEW!
+#if 0                                          // Kiss-of-death!?!
+       if (alt_ioc_ready && (r==0)) {
+               /* (re)Enable alt-IOC! (reply interrupt) */
+               dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
+                               ioc->alt_ioc->name));
+               CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
+               ioc->alt_ioc->active = 1;
+       }
+#endif
+
        /* NEW!  20010120 -sralston
         *  Enable MPT base driver management of EventNotification
         *  and EventAck handling.
         */
-       (void) SendEventNotification(ioc, 1);   /* 1=Enable EventNotification */
+       if (!ioc->facts.EventState)
+               (void) SendEventNotification(ioc, 1);   /* 1=Enable EventNotification */
+// NEW!
+// FIXME!?!
+//     if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState) {
+//             (void) SendEventNotification(ioc->alt_ioc, 1);  /* 1=Enable EventNotification */
+//     }
 
        return 0;
-
-ioc_up_fail:
-       //Q_DEL_ITEM(ioc);
-       //mpt_adapter_dispose(ioc);
-       mpt_adapter_disable(ioc);
-       return r;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1297,20 +1428,25 @@ mpt_detect_929_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
 /*
  *     mpt_adapter_disable - Disable misbehaving MPT adapter.
  *     @this: Pointer to MPT adapter structure
+ *     @free: Free up alloc'd reply, request, etc.
  */
 static void
-mpt_adapter_disable(MPT_ADAPTER *this)
+mpt_adapter_disable(MPT_ADAPTER *this, int freeup)
 {
        if (this != NULL) {
                int sz;
 
+               /* Disable the FW */
+               if (SendIocReset(this, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET) != 0)
+                       (void) KickStart(this, 1);
+
                /* Disable adapter interrupts! */
                CHIPREG_WRITE32(&this->chip->IntMask, 0xFFFFFFFF);
+               this->active = 0;
                /* Clear any lingering interrupt */
                CHIPREG_WRITE32(&this->chip->IntStatus, 0);
-               this->active = 0;
 
-               if (this->reply_alloc != NULL) {
+               if (freeup && this->reply_alloc != NULL) {
                        sz = (this->reply_sz * this->reply_depth) + 128;
                        pci_free_consistent(this->pcidev, sz,
                                        this->reply_alloc, this->reply_alloc_dma);
@@ -1319,7 +1455,7 @@ mpt_adapter_disable(MPT_ADAPTER *this)
                        this->alloc_total -= sz;
                }
 
-               if (this->req_alloc != NULL) {
+               if (freeup && this->req_alloc != NULL) {
                        sz = (this->req_sz * this->req_depth) + 128;
                        /*
                         *  Rounding UP to nearest 4-kB boundary here...
@@ -1332,7 +1468,7 @@ mpt_adapter_disable(MPT_ADAPTER *this)
                        this->alloc_total -= sz;
                }
 
-               if (this->sense_buf_pool != NULL) {
+               if (freeup && this->sense_buf_pool != NULL) {
                        sz = (this->req_depth * 256);
                        pci_free_consistent(this->pcidev, sz,
                                        this->sense_buf_pool, this->sense_buf_pool_dma);
@@ -1359,7 +1495,7 @@ mpt_adapter_dispose(MPT_ADAPTER *this)
 
                sz_first = this->alloc_total;
 
-               mpt_adapter_disable(this);
+               mpt_adapter_disable(this, 1);
 
                if (this->pci_irq != -1) {
                        free_irq(this->pci_irq, this);
@@ -1401,17 +1537,17 @@ MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
                printk("%s: ", ioc->prod_name+3);
        printk("Capabilities={");
 
-       if (ioc->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
+       if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
                printk("Initiator");
                i++;
        }
 
-       if (ioc->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
+       if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
                printk("%sTarget", i ? "," : "");
                i++;
        }
 
-       if (ioc->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
+       if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
                printk("%sLAN", i ? "," : "");
                i++;
        }
@@ -1420,7 +1556,7 @@ MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
        /*
         *  This would probably evoke more questions than it's worth
         */
-       if (ioc->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
+       if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
                printk("%sLogBusAddr", i ? "," : "");
                i++;
        }
@@ -1429,6 +1565,113 @@ MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
        printk("}\n");
 }
 
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *     MakeIocReady - Get IOC to a READY state, using KickStart if needed.
+ *     @ioc: Pointer to MPT_ADAPTER structure
+ *     @kick: Force hard KickStart of IOC
+ *
+ *     Returns 0 for already-READY, 1 for hard reset success,
+ *     else negative for failure.
+ */
+static int
+MakeIocReady(MPT_ADAPTER *ioc, int force)
+{
+       u32      ioc_state;
+       int      statefault = 0;
+       int      cntdn;
+       int      hard_reset_done = 0;
+       int      r;
+       int      i;
+
+       /* Get current [raw] IOC state  */
+       ioc_state = GetIocState(ioc, 0);
+       dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
+
+       /*
+        *      Check to see if IOC got left/stuck in doorbell handshake
+        *      grip of death.  If so, hard reset the IOC.
+        */
+       if (ioc_state & MPI_DOORBELL_ACTIVE) {
+               statefault = 1;
+               printk(KERN_WARNING MYNAM ": %s: Uh-oh, unexpected doorbell active!\n",
+                               ioc->name);
+       }
+
+       /* Is it already READY? */
+       if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
+               return 0;
+
+       /*
+        *      Check to see if IOC is in FAULT state.
+        */
+       if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
+               statefault = 2;
+               printk(KERN_WARNING MYNAM ": %s: Uh-oh, IOC is in FAULT state!!!\n",
+                               ioc->name);
+               printk(KERN_WARNING "           FAULT code = %04xh\n",
+                               ioc_state & MPI_DOORBELL_DATA_MASK);
+       }
+
+       /*
+        *      Hmmm...  Did it get left operational?
+        */
+       if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
+               statefault = 3;
+               dprintk((KERN_WARNING MYNAM ": %s: Hmmm... IOC operational unexpected\n",
+                               ioc->name));
+       }
+
+       hard_reset_done = KickStart(ioc, statefault||force);
+       if (hard_reset_done < 0)
+               return -1;
+
+       /*
+        *  Loop here waiting for IOC to come READY.
+        */
+       i = 0;
+       cntdn = HZ * 15;
+       while ((ioc_state = GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
+               if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
+                       /*
+                        *  BIOS or previous driver load left IOC in OP state.
+                        *  Reset messaging FIFOs.
+                        */
+                       if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET)) != 0) {
+                               printk(KERN_ERR MYNAM ": %s: ERROR - IOC msg unit reset failed!\n", ioc->name);
+                               return -2;
+                       }
+               } else if (ioc_state == MPI_IOC_STATE_RESET) {
+                       /*
+                        *  Something is wrong.  Try to get IOC back
+                        *  to a known state.
+                        */
+                       if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET)) != 0) {
+                               printk(KERN_ERR MYNAM ": %s: ERROR - IO unit reset failed!\n", ioc->name);
+                               return -3;
+                       }
+               }
+
+               i++; cntdn--;
+               if (!cntdn) {
+                       printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
+                                       ioc->name, (i+5)/HZ);
+                       return -ETIME;
+               }
+
+               current->state = TASK_INTERRUPTIBLE;
+               schedule_timeout(1);
+       }
+
+       if (statefault < 3) {
+               printk(KERN_WARNING MYNAM ": %s: Whew!  Recovered from %s\n",
+                               ioc->name,
+                               statefault==1 ? "stuck handshake" : "IOC FAULT");
+       }
+
+       return hard_reset_done;
+}
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *     GetIocState - Get the current state of a MPT adapter.
@@ -1471,7 +1714,7 @@ GetIocFacts(MPT_ADAPTER *ioc)
        int                      reply_sz;
        u32                      status;
 
-       /*  IOC *must* NOT be in RESET state!  */
+       /* IOC *must* NOT be in RESET state! */
        if (ioc->last_state == MPI_IOC_STATE_RESET) {
                printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
                                ioc->name,
@@ -1479,44 +1722,45 @@ GetIocFacts(MPT_ADAPTER *ioc)
                return -44;
        }
 
-       facts = &ioc->facts0;
-       /*  Nth (2,3,...) time thru? (been here, done that?)  */
-       if (ioc->facts0.Function == MPI_FUNCTION_IOC_FACTS) {
-               facts = &ioc->factsN;
-       }
+       facts = &ioc->facts;
 
-       /*  Destination (reply area)...  */
+       /* Destination (reply area)... */
        reply_sz = sizeof(*facts);
        memset(facts, 0, reply_sz);
 
-       /*  Request area (get_facts on the stack right now!)  */
+       /* Request area (get_facts on the stack right now!) */
        req_sz = sizeof(get_facts);
        memset(&get_facts, 0, req_sz);
 
        get_facts.Function = MPI_FUNCTION_IOC_FACTS;
-       /*  Assert: All other get_facts fields are zero!  */
+       /* Assert: All other get_facts fields are zero! */
 
-       dprintk((KERN_INFO MYNAM ": %s: Sending IocFacts%s request\n",
-                       ioc->name, facts == &ioc->facts0 ? "0" : "N" ));
+       dprintk((KERN_INFO MYNAM ": %s: Sending get IocFacts request\n", ioc->name));
 
        /* No non-zero fields in the get_facts request are greater than
         * 1 byte in size, so we can just fire it off as is.
         */
        r = HandShakeReqAndReply(ioc,
                        req_sz, (u32*)&get_facts,
-                       reply_sz, (u16*)facts);
+                       reply_sz, (u16*)facts, 3);
        if (r != 0)
                return r;
 
        /*
-        *  Now byte swap the necessary fields before any further
-        *  inspection of reply contents.
+        * Now byte swap (GRRR) the necessary fields before any further
+        * inspection of reply contents.
         *
-        *  But need to do some sanity checks on MsgLength (byte) field
-        *  to make sure we don't zero IOC's req_sz!
+        * But need to do some sanity checks on MsgLength (byte) field
+        * to make sure we don't zero IOC's req_sz!
         */
        /* Did we get a valid reply? */
        if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
+               /*
+                * If not been here, done that, save off first WhoInit value
+                */
+               if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
+                       ioc->FirstWhoInit = facts->WhoInit;
+
                facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
                facts->MsgContext = le32_to_cpu(facts->MsgContext);
                facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
@@ -1537,9 +1781,9 @@ GetIocFacts(MPT_ADAPTER *ioc)
                                le16_to_cpu(facts->CurReplyFrameSize);
 
                /*
-                *  Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
-                *  Older MPI-1.00.xx struct had 13 dwords, and enlarged
-                *  to 14 in MPI-1.01.0x.
+                * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
+                * Older MPI-1.00.xx struct had 13 dwords, and enlarged
+                * to 14 in MPI-1.01.0x.
                 */
                if (facts->MsgLength >= sizeof(IOCFactsReply_t)/sizeof(u32) && facts->MsgVersion > 0x0100) {
                        facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
@@ -1548,7 +1792,7 @@ GetIocFacts(MPT_ADAPTER *ioc)
 
                if (facts->RequestFrameSize) {
                        /*
-                        *  Set values for this IOC's REQUEST queue size & depth...
+                        * Set values for this IOC's REQUEST queue size & depth...
                         */
                        ioc->req_sz = MIN(MPT_REQ_SIZE, facts->RequestFrameSize * 4);
 
@@ -1582,8 +1826,8 @@ GetIocFacts(MPT_ADAPTER *ioc)
                dprintk((KERN_INFO MYNAM ": %s: req_sz  =%3d, req_depth  =%4d\n",
                                ioc->name, ioc->req_sz, ioc->req_depth));
 
-               /*  Get port facts!  */
-               if ( (r = GetPortFacts(ioc)) != 0 )
+               /* Get port facts! */
+               if ( (r = GetPortFacts(ioc, 0)) != 0 )
                        return r;
        } else {
                printk(KERN_ERR MYNAM ": %s: ERROR - Invalid IOC facts reply!\n",
@@ -1598,11 +1842,12 @@ GetIocFacts(MPT_ADAPTER *ioc)
 /*
  *     GetPortFacts - Send PortFacts request to MPT adapter.
  *     @ioc: Pointer to MPT_ADAPTER structure
+ *     @portnum: Port number
  *
  *     Returns 0 for success, non-zero for failure.
  */
 static int
-GetPortFacts(MPT_ADAPTER *ioc)
+GetPortFacts(MPT_ADAPTER *ioc, int portnum)
 {
        PortFacts_t              get_pfacts;
        PortFactsReply_t        *pfacts;
@@ -1610,7 +1855,7 @@ GetPortFacts(MPT_ADAPTER *ioc)
        int                      req_sz;
        int                      reply_sz;
 
-       /*  IOC *must* NOT be in RESET state!  */
+       /* IOC *must* NOT be in RESET state! */
        if (ioc->last_state == MPI_IOC_STATE_RESET) {
                printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
                                ioc->name,
@@ -1618,31 +1863,28 @@ GetPortFacts(MPT_ADAPTER *ioc)
                return -4;
        }
 
-       pfacts = &ioc->pfacts0;
-       /*  Nth (2,3,...) time thru? (been here, done that?)  */
-       if (ioc->pfacts0.Function == MPI_FUNCTION_PORT_FACTS) {
-               pfacts = &ioc->pfactsN;
-       }
+       pfacts = &ioc->pfacts[portnum];
 
-       /*  Destination (reply area)...  */
+       /* Destination (reply area)...  */
        reply_sz = sizeof(*pfacts);
        memset(pfacts, 0, reply_sz);
 
-       /*  Request area (get_pfacts on the stack right now!)  */
+       /* Request area (get_pfacts on the stack right now!) */
        req_sz = sizeof(get_pfacts);
        memset(&get_pfacts, 0, req_sz);
 
        get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
-       /*  Assert: All other get_pfacts fields are zero!  */
+       get_pfacts.PortNumber = portnum;
+       /* Assert: All other get_pfacts fields are zero! */
 
-       dprintk((KERN_INFO MYNAM ": %s: Sending PortFacts%s request\n",
-                       ioc->name, pfacts == &ioc->pfacts0 ? "0" : "N" ));
+       dprintk((KERN_INFO MYNAM ": %s: Sending get PortFacts(%d) request\n",
+                       ioc->name, portnum));
 
        /* No non-zero fields in the get_pfacts request are greater than
         * 1 byte in size, so we can just fire it off as is.
         */
        i = HandShakeReqAndReply(ioc, req_sz, (u32*)&get_pfacts,
-                               reply_sz, (u16*)pfacts);
+                               reply_sz, (u16*)pfacts, 3);
        if (i != 0)
                return i;
 
@@ -1702,7 +1944,7 @@ SendIocInit(MPT_ADAPTER *ioc)
        dprintk((KERN_INFO MYNAM ": %s: Sending IOCInit (req @ %p)\n", ioc->name, &ioc_init));
 
        r = HandShakeReqAndReply(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
-                       sizeof(MPIDefaultReply_t), (u16*)&init_reply);
+                       sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10);
        if (r != 0)
                return r;
 
@@ -1775,7 +2017,7 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum)
                        ioc->name, portnum, &port_enable));
 
        i = HandShakeReqAndReply(ioc, req_sz, (u32*)&port_enable,
-                       reply_sz, (u16*)&reply_buf);
+                       reply_sz, (u16*)&reply_buf, 65);
        if (i != 0)
                return i;
 
@@ -1790,24 +2032,28 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum)
 /*
  *     KickStart - Perform hard reset of MPT adapter.
  *     @ioc: Pointer to MPT_ADAPTER structure
+ *     @force: Force hard reset
  *
  *     This routine places MPT adapter in diagnostic mode via the
  *     WriteSequence register, and then performs a hard reset of adapter
  *     via the Diagnostic register.
  *
- *     Returns 0 for success, non-zero for failure.
+ *     Returns 0 for soft reset success, 1 for hard reset success,
+ *     else a negative value for failure.
  */
 static int
-KickStart(MPT_ADAPTER *ioc)
+KickStart(MPT_ADAPTER *ioc, int force)
 {
-       int r;
+       int hard_reset_done = 0;
        u32 ioc_state;
        int cnt = 0;
 
        dprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
 
-       if (ioc->chip_type == FC909) {
-               r = mpt_fc9x9_reset(ioc);
+       hard_reset_done = mpt_fc9x9_reset(ioc, force);
+#if 0
+       if (ioc->chip_type == FC909 || ioc->chip-type == FC919) {
+               hard_reset_done = mpt_fc9x9_reset(ioc, force);
        } else if (ioc->chip_type == FC929) {
                unsigned long delta;
 
@@ -1815,15 +2061,12 @@ KickStart(MPT_ADAPTER *ioc)
                dprintk((KERN_INFO MYNAM ": %s: 929 KickStart, last=%ld, delta = %ld\n",
                                ioc->name, ioc->last_kickstart, delta));
                if ((ioc->sod_reset == 0) || (delta >= 10*HZ))
-                       r = mpt_fc9x9_reset(ioc);
+                       hard_reset_done = mpt_fc9x9_reset(ioc, ignore);
                else {
                        dprintk((KERN_INFO MYNAM ": %s: Skipping KickStart (delta=%ld)!\n",
                                        ioc->name, delta));
                        return 0;
                }
-       /* TODO! Add FC919!
-       } else if (ioc->chip_type == FC919) {
-        */
        /* TODO! Add C1030!
        } else if (ioc->chip_type == C1030) {
         */
@@ -1832,9 +2075,10 @@ KickStart(MPT_ADAPTER *ioc)
                                ioc->name, ioc->chip_type);
                return -5;
        }
+#endif
 
-       if (r != 0)
-               return -r;
+       if (hard_reset_done < 0)
+               return hard_reset_done;
 
        dprintk((KERN_INFO MYNAM ": %s: Diagnostic reset successful\n",
                        ioc->name));
@@ -1843,7 +2087,7 @@ KickStart(MPT_ADAPTER *ioc)
                if ((ioc_state = GetIocState(ioc, 1)) == MPI_IOC_STATE_READY) {
                        dprintk((KERN_INFO MYNAM ": %s: KickStart successful! (cnt=%d)\n",
                                        ioc->name, cnt));
-                       return 0;
+                       return hard_reset_done;
                }
                /* udelay(10000) ? */
                current->state = TASK_INTERRUPTIBLE;
@@ -1867,52 +2111,112 @@ KickStart(MPT_ADAPTER *ioc)
  *     Returns 0 for success, non-zero for failure.
  */
 static int
-mpt_fc9x9_reset(MPT_ADAPTER *ioc)
+mpt_fc9x9_reset(MPT_ADAPTER *ioc, int ignore)
 {
-       u32 diagval;
+       u32 diag0val;
+       int hard_reset_done = 0;
 
        /* Use "Diagnostic reset" method! (only thing available!) */
 
-       /*
-        * Extra read to handle 909 B.0 chip problem with reset
-        * logic not finishing the RAM access before hard reset hits.
-        * (? comment taken from NT SYMMPI source)
-        */
-       (void) CHIPREG_READ32(&ioc->chip->Fubar);
+       diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+#ifdef MPT_DEBUG
+{
+       u32 diag1val = 0;
+       if (ioc->alt_ioc)
+               diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+       dprintk((KERN_INFO MYNAM ": %s: DBG1: diag0=%08x, diag1=%08x\n",
+                       ioc->name, diag0val, diag1val));
+}
+#endif
+       if (diag0val & MPI_DIAG_DRWE) {
+               dprintk((KERN_INFO MYNAM ": %s: DiagWriteEn bit already set\n",
+                               ioc->name));
+       } else {
+               /* Write magic sequence to WriteSequence register */
+               CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
+               CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
+               CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
+               CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
+               CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
+               dprintk((KERN_INFO MYNAM ": %s: Wrote magic DiagWriteEn sequence [spot#1]\n",
+                               ioc->name));
+       }
 
-       /*
-        * Write magic sequence to WriteSequence register.
-        * But, send 0x0F first to insure a reset to the beginning of the sequence.
-        */
-       CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_KEY_VALUE_MASK);
-
-       /* Now write magic sequence */
-       CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
-       CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
-       CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
-       CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
-       CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
-       dprintk((KERN_INFO MYNAM ": %s: Wrote magic DiagWriteEn sequence\n",
-                       ioc->name));
+       diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+#ifdef MPT_DEBUG
+{
+       u32 diag1val = 0;
+       if (ioc->alt_ioc)
+               diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+       dprintk((KERN_INFO MYNAM ": %s: DbG2: diag0=%08x, diag1=%08x\n",
+                       ioc->name, diag0val, diag1val));
+}
+#endif
+       if (!ignore && (diag0val & MPI_DIAG_RESET_HISTORY)) {
+               dprintk((KERN_INFO MYNAM ": %s: Skipping due to ResetHistory bit set!\n",
+                               ioc->name));
+       } else {
+               /*
+                * Now hit the reset bit in the Diagnostic register
+                * (THE BIG HAMMER!)
+                */
+               CHIPREG_WRITE32(&ioc->chip->Diagnostic, MPI_DIAG_RESET_ADAPTER);
+               hard_reset_done = 1;
+               dprintk((KERN_INFO MYNAM ": %s: Diagnostic reset performed\n",
+                               ioc->name));
 
-       /* Now hit the reset bit in the Diagnostic register */
-       CHIPREG_WRITE32(&ioc->chip->Diagnostic, MPI_DIAG_RESET_ADAPTER);
+               /* want udelay(100) */
+               current->state = TASK_INTERRUPTIBLE;
+               schedule_timeout(1);
 
-       udelay(100);
+               /* Write magic sequence to WriteSequence register */
+               CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
+               CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
+               CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
+               CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
+               CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
+               dprintk((KERN_INFO MYNAM ": %s: Wrote magic DiagWriteEn sequence [spot#2]\n",
+                               ioc->name));
+       }
 
-       if ((diagval = CHIPREG_READ32(&ioc->chip->Diagnostic)) &
-                               (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_DISABLE_ARM)) {
-               printk(KERN_ERR MYNAM ": %s: ERROR - Diagnostic reset FAILED!\n",
+       /* Clear RESET_HISTORY bit! */
+       CHIPREG_WRITE32(&ioc->chip->Diagnostic, 0x0);
+
+       diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+#ifdef MPT_DEBUG
+{
+       u32 diag1val = 0;
+       if (ioc->alt_ioc)
+               diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+       dprintk((KERN_INFO MYNAM ": %s: DbG3: diag0=%08x, diag1=%08x\n",
+                       ioc->name, diag0val, diag1val));
+}
+#endif
+       if (diag0val & MPI_DIAG_RESET_HISTORY) {
+               printk(KERN_WARNING MYNAM ": %s: WARNING - ResetHistory bit failed to clear!\n",
                                ioc->name);
-               return -9;
        }
 
-       /* TODO!
-        * Cleanup all event stuff for this IOC;
-        * re-issue EventNotification request if needed.
+       diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+#ifdef MPT_DEBUG
+{
+       u32 diag1val = 0;
+       if (ioc->alt_ioc)
+               diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+       dprintk((KERN_INFO MYNAM ": %s: DbG4: diag0=%08x, diag1=%08x\n",
+                       ioc->name, diag0val, diag1val));
+}
+#endif
+       if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
+               printk(KERN_ERR MYNAM ": %s: ERROR - Diagnostic reset FAILED! (%02xh)\n",
+                               ioc->name, diag0val);
+               return -3;
+       }
+
+       /*
+        * Reset flag that says we've enabled event notification
         */
-       if (ioc->factsN.Function)
-               ioc->factsN.EventState = 0;
+       ioc->facts.EventState = 0;
 
        /* NEW!  20010220 -sralston
         * Try to avoid redundant resets of the 929.
@@ -1924,7 +2228,7 @@ mpt_fc9x9_reset(MPT_ADAPTER *ioc)
                ioc->alt_ioc->last_kickstart = ioc->last_kickstart;
        }
 
-       return 0;
+       return hard_reset_done;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1943,18 +2247,18 @@ SendIocReset(MPT_ADAPTER *ioc, u8 reset_type)
 {
        int r;
 
-       printk(KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
-                       ioc->name, reset_type);
+       dprintk((KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
+                       ioc->name, reset_type));
        CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
-       if ((r = WaitForDoorbellAck(ioc)) < 0)
+       if ((r = WaitForDoorbellAck(ioc, 2)) < 0)
                return r;
 
        /* TODO!
         *  Cleanup all event stuff for this IOC; re-issue EventNotification
         *  request if needed.
         */
-       if (ioc->factsN.Function)
-               ioc->factsN.EventState = 0;
+       if (ioc->facts.Function)
+               ioc->facts.EventState = 0;
 
        return 0;
 }
@@ -2125,6 +2429,7 @@ out_fail:
  *     @req: Pointer to MPT request frame
  *     @replyBytes: Expected size of the reply in bytes
  *     @u16reply: Pointer to area where reply should be written
+ *     @maxwait: Max wait time for a reply (in seconds)
  *
  *     NOTES: It is the callers responsibility to byte-swap fields in the
  *     request which are greater than 1 byte in size.  It is also the
@@ -2134,7 +2439,7 @@ out_fail:
  *     Returns 0 for success, non-zero for failure.
  */
 static int
-HandShakeReqAndReply(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u16 *u16reply)
+HandShakeReqAndReply(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u16 *u16reply, int maxwait)
 {
        MPIDefaultReply_t *mptReply;
        int failcnt = 0;
@@ -2160,7 +2465,7 @@ HandShakeReqAndReply(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u
        /*
         * Wait for IOC's doorbell handshake int
         */
-       if ((t = WaitForDoorbellInt(ioc)) < 0)
+       if ((t = WaitForDoorbellInt(ioc, 2)) < 0)
                failcnt++;
 
        dhsprintk((KERN_INFO MYNAM ": %s: HandShake request start, WaitCnt=%d%s\n",
@@ -2172,7 +2477,7 @@ HandShakeReqAndReply(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u
         * our handshake request.
         */
        CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
-       if (!failcnt && (t = WaitForDoorbellAck(ioc)) < 0)
+       if (!failcnt && (t = WaitForDoorbellAck(ioc, 2)) < 0)
                failcnt++;
 
        if (!failcnt) {
@@ -2190,7 +2495,7 @@ HandShakeReqAndReply(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u
                                    (req_as_bytes[(i*4) + 3] << 24));
 
                        CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
-                       if ((t = WaitForDoorbellAck(ioc)) < 0)
+                       if ((t = WaitForDoorbellAck(ioc, 2)) < 0)
                                failcnt++;
                }
 
@@ -2203,7 +2508,7 @@ HandShakeReqAndReply(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u
                /*
                 * Wait for completion of doorbell handshake reply from the IOC
                 */
-               if (!failcnt && (t = WaitForDoorbellReply(ioc)) < 0)
+               if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait)) < 0)
                        failcnt++;
 
                /*
@@ -2223,16 +2528,17 @@ HandShakeReqAndReply(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u
  *     WaitForDoorbellAck - Wait for IOC to clear the IOP_DOORBELL_STATUS bit
  *     in it's IntStatus register.
  *     @ioc: Pointer to MPT_ADAPTER structure
+ *     @howlong: How long to wait (in seconds)
  *
- *     This routine waits (up to ~30 seconds max) for IOC doorbell
+ *     This routine waits (up to ~2 seconds max) for IOC doorbell
  *     handshake ACKnowledge.
  *
  *     Returns a negative value on failure, else wait loop count.
  */
 static int
-WaitForDoorbellAck(MPT_ADAPTER *ioc)
+WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong)
 {
-       int cntdn = HZ * 30;                    /* ~30 seconds */
+       int cntdn = HZ * howlong;
        int count = 0;
        u32 intstat;
 
@@ -2261,15 +2567,16 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc)
  *     WaitForDoorbellInt - Wait for IOC to set the HIS_DOORBELL_INTERRUPT bit
  *     in it's IntStatus register.
  *     @ioc: Pointer to MPT_ADAPTER structure
+ *     @howlong: How long to wait (in seconds)
  *
- *     This routine waits (up to ~30 seconds max) for IOC doorbell interrupt.
+ *     This routine waits (up to ~2 seconds max) for IOC doorbell interrupt.
  *
  *     Returns a negative value on failure, else wait loop count.
  */
 static int
-WaitForDoorbellInt(MPT_ADAPTER *ioc)
+WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong)
 {
-       int cntdn = HZ * 30;                    /* ~30 seconds */
+       int cntdn = HZ * howlong;
        int count = 0;
        u32 intstat;
 
@@ -2297,6 +2604,7 @@ WaitForDoorbellInt(MPT_ADAPTER *ioc)
 /*
  *     WaitForDoorbellReply - Wait for and capture a IOC handshake reply.
  *     @ioc: Pointer to MPT_ADAPTER structure
+ *     @howlong: How long to wait (in seconds)
  *
  *     This routine polls the IOC for a handshake reply, 16 bits at a time.
  *     Reply is cached to IOC private area large enough to hold a maximum
@@ -2305,7 +2613,7 @@ WaitForDoorbellInt(MPT_ADAPTER *ioc)
  *     Returns a negative value on failure, else size of reply in WORDS.
  */
 static int
-WaitForDoorbellReply(MPT_ADAPTER *ioc)
+WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong)
 {
        int u16cnt = 0;
        int failcnt = 0;
@@ -2319,11 +2627,18 @@ WaitForDoorbellReply(MPT_ADAPTER *ioc)
        /*
         * Get first two u16's so we can look at IOC's intended reply MsgLength
         */
-       for (u16cnt=0; !failcnt && u16cnt < 2; u16cnt++) {
-               if ((t = WaitForDoorbellInt(ioc)) < 0)
-                       failcnt++;
-               hs_reply[u16cnt] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
+       u16cnt=0;
+       if ((t = WaitForDoorbellInt(ioc, howlong)) < 0) {
+               failcnt++;
+       } else {
+               hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
                CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+               if ((t = WaitForDoorbellInt(ioc, 2)) < 0)
+                       failcnt++;
+               else {
+                       hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
+                       CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+               }
        }
 
        dhsprintk((KERN_INFO MYNAM ": %s: First handshake reply word=%08x%s\n",
@@ -2335,7 +2650,7 @@ WaitForDoorbellReply(MPT_ADAPTER *ioc)
         * reply 16 bits at a time.
         */
        for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
-               if ((t = WaitForDoorbellInt(ioc)) < 0)
+               if ((t = WaitForDoorbellInt(ioc, 2)) < 0)
                        failcnt++;
                hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
                /* don't overflow our IOC hs_reply[] buffer! */
@@ -2344,7 +2659,7 @@ WaitForDoorbellReply(MPT_ADAPTER *ioc)
                CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
        }
 
-       if (!failcnt && (t = WaitForDoorbellInt(ioc)) < 0)
+       if (!failcnt && (t = WaitForDoorbellInt(ioc, 2)) < 0)
                failcnt++;
        CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
 
@@ -2428,7 +2743,7 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
                        ioc->name));
 
        i = HandShakeReqAndReply(ioc, req_sz, (u32*)&config_req,
-                               reply_sz, (u16*)&config_reply);
+                               reply_sz, (u16*)&config_reply, 3);
        pci_unmap_single(ioc->pcidev, page0_dma, data_sz, PCI_DMA_FROMDEVICE);
        if (i != 0)
                return i;
@@ -2472,7 +2787,7 @@ GetLanConfigPages(MPT_ADAPTER *ioc)
                        ioc->name));
 
        i = HandShakeReqAndReply(ioc, req_sz, (u32*)&config_req,
-                               reply_sz, (u16*)&config_reply);
+                               reply_sz, (u16*)&config_reply, 3);
        pci_unmap_single(ioc->pcidev, page1_dma, data_sz, PCI_DMA_FROMDEVICE);
        if (i != 0)
                return i;
@@ -2564,7 +2879,6 @@ SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
        return len;                     \
 }
 
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *     procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
@@ -2653,6 +2967,9 @@ procmpt_destroy(void)
 {
        MPT_ADAPTER *ioc;
 
+       if (!procmpt_root_dir)
+               return 0;
+
        /*
         *      BEWARE: If/when MPT_PROCFS_MPTBASEDIR changes from "mpt"
         *      (single level) to multi level (e.g. "driver/message/fusion")
@@ -2685,6 +3002,7 @@ procmpt_destroy(void)
 
        if (atomic_read((atomic_t *)&procmpt_root_dir->count) == 0) {
                remove_proc_entry(MPT_PROCFS_MPTBASEDIR, 0);
+               procmpt_root_dir = NULL;
                return 0;
        }
 
@@ -2724,7 +3042,7 @@ procmpt_read_summary(char *page, char **start, off_t off, int count, int *eof, v
 
 // Too verbose!
 //             mpt_print_ioc_facts(ioc, out, &more, 0);
-               mpt_print_ioc_summary(ioc, out, &more, 0);
+               mpt_print_ioc_summary(ioc, out, &more, 0, 1);
 
                out += more;
                if ((out-page) >= count) {
@@ -2784,15 +3102,15 @@ procmpt_read_dbg(char *page, char **start, off_t off, int count, int *eof, void
 static void
 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
 {
-       if ((ioc->facts0.FWVersion & 0xF000) == 0xE000)
+       if ((ioc->facts.FWVersion & 0xF000) == 0xE000)
                sprintf(buf, " (Exp %02d%02d)",
-                       (ioc->facts0.FWVersion & 0x0F00) >> 8,  /* Month */
-                       ioc->facts0.FWVersion & 0x001F);        /* Day */
+                       (ioc->facts.FWVersion & 0x0F00) >> 8,   /* Month */
+                       ioc->facts.FWVersion & 0x001F);         /* Day */
        else
                buf[0] ='\0';
 
        /* insider hack! */
-       if (ioc->facts0.FWVersion & 0x0080) {
+       if (ioc->facts.FWVersion & 0x0080) {
                strcat(buf, " [MDBG]");
        }
 }
@@ -2804,17 +3122,17 @@ mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
  *     @buffer: Pointer to buffer where IOC summary info should be written
  *     @size: Pointer to number of bytes we wrote (set by this routine)
  *     @len: Offset at which to start writing in buffer
+ *     @showlan: Display LAN stuff?
  *
  *     This routine writes (english readable) ASCII text, which represents
  *     a summary of IOC information, to a buffer.
  */
 void
-mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len)
+mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
 {
        char expVer[32];
        int y;
 
-
        mpt_get_fw_exp_ver(expVer, ioc);
 
        /*
@@ -2824,17 +3142,20 @@ mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len)
                        ioc->name,
                        ioc->prod_name,
                        MPT_FW_REV_MAGIC_ID_STRING,     /* "FwRev=" or somesuch */
-                       ioc->facts0.FWVersion,
+                       ioc->facts.FWVersion,
                        expVer,
-                       ioc->facts0.NumberOfPorts,
+                       ioc->facts.NumberOfPorts,
                        ioc->req_depth);
 
-       if (ioc->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
+       if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
                u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
                y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
                        a[5], a[4], a[3], a[2], a[1], a[0]);
        }
 
+       if (ioc->pci_irq < 100)
+               y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
+
        if (!ioc->active)
                y += sprintf(buffer+len+y, " (disabled)");
 
@@ -2861,32 +3182,34 @@ mpt_print_ioc_facts(MPT_ADAPTER *ioc, char *buffer, int *size, int len)
        char iocName[16];
        int sz;
        int y;
-
+       int p;
 
        mpt_get_fw_exp_ver(expVer, ioc);
 
        strcpy(iocName, ioc->name);
        y = sprintf(buffer+len, "%s:\n", iocName);
 
-       y += sprintf(buffer+len+y, "  ProductID = 0x%04x\n", ioc->facts0.ProductID);
-       y += sprintf(buffer+len+y, "  PortNumber = %d (of %d)\n",
-               ioc->pfacts0.PortNumber+1,
-               ioc->facts0.NumberOfPorts);
-       if (ioc->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
-               u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
-               y += sprintf(buffer+len+y, "  LanAddr = 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
-                       a[5], a[4], a[3], a[2], a[1], a[0]);
+       y += sprintf(buffer+len+y, "  ProductID = 0x%04x\n", ioc->facts.ProductID);
+       for (p=0; p < ioc->facts.NumberOfPorts; p++) {
+               y += sprintf(buffer+len+y, "  PortNumber = %d (of %d)\n",
+                       p+1,
+                       ioc->facts.NumberOfPorts);
+               if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
+                       u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
+                       y += sprintf(buffer+len+y, "  LanAddr = 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
+                               a[5], a[4], a[3], a[2], a[1], a[0]);
+               }
        }
-       y += sprintf(buffer+len+y, "  FWVersion = 0x%04x%s\n", ioc->facts0.FWVersion, expVer);
-       y += sprintf(buffer+len+y, "  MsgVersion = 0x%04x\n", ioc->facts0.MsgVersion);
-       y += sprintf(buffer+len+y, "  WhoInit = 0x%02x\n", ioc->facts0.WhoInit);
-       y += sprintf(buffer+len+y, "  EventState = 0x%02x\n", ioc->facts0.EventState);
+       y += sprintf(buffer+len+y, "  FWVersion = 0x%04x%s\n", ioc->facts.FWVersion, expVer);
+       y += sprintf(buffer+len+y, "  MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
+       y += sprintf(buffer+len+y, "  FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
+       y += sprintf(buffer+len+y, "  EventState = 0x%02x\n", ioc->facts.EventState);
        y += sprintf(buffer+len+y, "  CurrentHostMfaHighAddr = 0x%08x\n",
-                       ioc->facts0.CurrentHostMfaHighAddr);
+                       ioc->facts.CurrentHostMfaHighAddr);
        y += sprintf(buffer+len+y, "  CurrentSenseBufferHighAddr = 0x%08x\n",
-                       ioc->facts0.CurrentSenseBufferHighAddr);
-       y += sprintf(buffer+len+y, "  MaxChainDepth = 0x%02x frames\n", ioc->facts0.MaxChainDepth);
-       y += sprintf(buffer+len+y, "  MinBlockSize = 0x%02x bytes\n", 4*ioc->facts0.BlockSize);
+                       ioc->facts.CurrentSenseBufferHighAddr);
+       y += sprintf(buffer+len+y, "  MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
+       y += sprintf(buffer+len+y, "  MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
 
        y += sprintf(buffer+len+y, "  RequestFrames @ 0x%p (Dma @ 0x%08x)\n",
                                        ioc->req_alloc, ioc->req_alloc_dma);
@@ -2898,8 +3221,8 @@ mpt_print_ioc_facts(MPT_ADAPTER *ioc, char *buffer, int *size, int len)
        y += sprintf(buffer+len+y, "    {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
                                        ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
        y += sprintf(buffer+len+y, "    {MaxReqSz=%d}   {MaxReqDepth=%d}\n",
-                                       4*ioc->facts0.RequestFrameSize,
-                                       ioc->facts0.GlobalCredits);
+                                       4*ioc->facts.RequestFrameSize,
+                                       ioc->facts.GlobalCredits);
 
        y += sprintf(buffer+len+y, "  ReplyFrames   @ 0x%p (Dma @ 0x%08x)\n",
                                        ioc->reply_alloc, ioc->reply_alloc_dma);
@@ -2907,8 +3230,8 @@ mpt_print_ioc_facts(MPT_ADAPTER *ioc, char *buffer, int *size, int len)
        y += sprintf(buffer+len+y, "    {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
                                        ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
        y += sprintf(buffer+len+y, "    {MaxRepSz=%d}   {MaxRepDepth=%d}\n",
-                                       ioc->factsN.CurReplyFrameSize,
-                                       ioc->facts0.ReplyQueueDepth);
+                                       ioc->facts.CurReplyFrameSize,
+                                       ioc->facts.ReplyQueueDepth);
 
        *size = y;
 }
@@ -3045,8 +3368,8 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply
                        /* CHECKME! What if evState unexpectedly says OFF (0)? */
 
                        /* Update EventState field in cached IocFacts */
-                       if (ioc->factsN.Function) {
-                               ioc->factsN.EventState = evState;
+                       if (ioc->facts.Function) {
+                               ioc->facts.EventState = evState;
                        }
                }
                break;
@@ -3182,6 +3505,9 @@ mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
        case MPI_IOCLOGINFO_FC_LINK_LINK_NOT_ESTABLISHED:
                desc = "Not synchronized to signal or still negotiating (possible cable problem)";
                break;
+       case MPI_IOCLOGINFO_FC_LINK_CRC_ERROR:
+               desc = "CRC check detected error on received frame";
+               break;
        }
 
        printk(KERN_INFO MYNAM ": %s: LogInfo(0x%08x): SubCl={%s}",
@@ -3259,6 +3585,8 @@ EXPORT_SYMBOL(mpt_register);
 EXPORT_SYMBOL(mpt_deregister);
 EXPORT_SYMBOL(mpt_event_register);
 EXPORT_SYMBOL(mpt_event_deregister);
+EXPORT_SYMBOL(mpt_reset_register);
+EXPORT_SYMBOL(mpt_reset_deregister);
 EXPORT_SYMBOL(mpt_get_msg_frame);
 EXPORT_SYMBOL(mpt_put_msg_frame);
 EXPORT_SYMBOL(mpt_free_msg_frame);
@@ -3299,6 +3627,7 @@ int __init fusion_init(void)
                MptCallbacks[i] = NULL;
                MptDriverClass[i] = MPTUNKNOWN_DRIVER;
                MptEvHandlers[i] = NULL;
+               MptResetHandlers[i] = NULL;
        }
 
        /* NEW!  20010120 -sralston
@@ -3323,23 +3652,9 @@ int __init fusion_init(void)
 static void fusion_exit(void)
 {
        MPT_ADAPTER *this;
-       int i;
 
        dprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
 
-       /*
-        *  Paranoia; disable interrupts on all MPT adapters.
-        */
-       for (i=0; i<MPT_MAX_ADAPTERS; i++) {
-               if ((this = mpt_adapters[i]) != NULL) {
-                       /* Disable adapter interrupts! */
-                       CHIPREG_WRITE32(&this->chip->IntMask, 0xFFFFFFFF);
-                       /* Clear any lingering interrupt */
-                       CHIPREG_WRITE32(&this->chip->IntStatus, 0);
-                       this->active = 0;
-               }
-       }
-
        /* Whups?  20010120 -sralston
         *  Moved this *above* removal of all MptAdapters!
         */
index 68fc7acff0229f516db9747cd4842b61fad6ebe3..d19402a58f151d854aacfc9312280c4b690f08fa 100644 (file)
@@ -12,7 +12,7 @@
  *  Originally By: Steven J. Ralston
  *  (mailto:Steve.Ralston@lsil.com)
  *
- *  $Id: mptbase.h,v 1.38 2001/03/22 10:54:30 sralston Exp $
+ *  $Id: mptbase.h,v 1.46.2.2.2.1 2001/08/24 20:07:05 sralston Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -63,8 +63,8 @@
 #include "lsi/mpi_init.h"      /* SCSI Host (initiator) protocol support */
 #include "lsi/mpi_lan.h"       /* LAN over FC protocol support */
 
-//#include "lsi/mpi_fc.h"      /* Fibre Channel (lowlevel) support */
-//#include "lsi/mpi_targ.h"    /* SCSI/FCP Target protcol support */
+#include "lsi/mpi_fc.h"                /* Fibre Channel (lowlevel) support */
+#include "lsi/mpi_targ.h"      /* SCSI/FCP Target protcol support */
 #include "lsi/fc_log.h"
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -77,9 +77,8 @@
 #define COPYRIGHT      "Copyright (c) 1999-2001 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON       "1.00.11"
-#define MPT_LINUX_VERSION_EXP          "0.09.66-EXP"
-#define MPT_LINUX_PACKAGE_NAME         "@(#)mptlinux-1.00.11"
+#define MPT_LINUX_VERSION_COMMON       "1.02.01"
+#define MPT_LINUX_PACKAGE_NAME         "@(#)mptlinux-1.02.01"
 #define WHAT_MAGIC_STRING              "@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
@@ -91,6 +90,7 @@
  */
 #define MPT_MAX_ADAPTERS               16
 #define MPT_MAX_PROTOCOL_DRIVERS       8
+#define MPT_MAX_FC_DEVICES             255
 
 #define MPT_MISCDEV_BASENAME           "mptctl"
 #define MPT_MISCDEV_PATHNAME           "/dev/" MPT_MISCDEV_BASENAME
@@ -262,8 +262,6 @@ typedef struct _MPT_ADAPTER
        struct _MPT_ADAPTER     *back;
        int                      id;            /* Unique adapter id {0,1,2,...} */
        int                      pci_irq;
-       IOCFactsReply_t          facts0;
-       IOCFactsReply_t          factsN;
        char                     name[32];      /* "iocN"             */
        char                    *prod_name;     /* "LSIFC9x9"         */
        u32                      mem_phys;      /* == f4020000 (mmap) */
@@ -275,10 +273,6 @@ typedef struct _MPT_ADAPTER
        int                      active;
        int                      sod_reset;
        unsigned long            last_kickstart;
-       PortFactsReply_t         pfacts0;
-       PortFactsReply_t         pfactsN;
-       LANPage0_t               lan_cnfg_page0;
-       LANPage1_t               lan_cnfg_page1;
        u8                      *reply_alloc;           /* Reply frames alloc ptr */
        dma_addr_t               reply_alloc_dma;
        MPT_FRAME_HDR           *reply_frames;          /* Reply frames - rounded up! */
@@ -292,24 +286,30 @@ typedef struct _MPT_ADAPTER
        dma_addr_t               req_frames_dma;
        int                      req_depth;
        int                      req_sz;
-       spinlock_t               FreeQlock;
        MPT_Q_TRACKER            FreeQ;
+       spinlock_t               FreeQlock;
                /* Pool of SCSI sense buffers for commands coming from
                 * the SCSI mid-layer.  We have one 256 byte sense buffer
                 * for each REQ entry.
                 */
        u8                      *sense_buf_pool;
        dma_addr_t               sense_buf_pool_dma;
-       int                      hs_reply_idx;
-       u32                      hs_req[MPT_MAX_FRAME_SIZE/sizeof(u32)];
-       u16                      hs_reply[MPT_MAX_FRAME_SIZE/sizeof(u16)];
        struct pci_dev          *pcidev;
-       struct _MPT_ADAPTER     *alt_ioc;
 /*     atomic_t                 userCnt;       */
        u8                      *memmap;
        int                      mtrr_reg;
        struct Scsi_Host        *sh;
        struct proc_dir_entry   *ioc_dentry;
+       struct _MPT_ADAPTER     *alt_ioc;
+       int                      hs_reply_idx;
+       u32                      hs_req[MPT_MAX_FRAME_SIZE/sizeof(u32)];
+       u16                      hs_reply[MPT_MAX_FRAME_SIZE/sizeof(u16)];
+       IOCFactsReply_t          facts;
+       PortFactsReply_t         pfacts[2];
+       LANPage0_t               lan_cnfg_page0;
+       LANPage1_t               lan_cnfg_page1;
+       u8                       FirstWhoInit;
+       u8                       pad1[3];
 } MPT_ADAPTER;
 
 
@@ -324,26 +324,25 @@ typedef struct _MPT_ADAPTER_TRACKER {
  *    0 = not Ok ...
  */
 typedef int (*MPT_CALLBACK)(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
+
 typedef int (*MPT_EVHANDLER)(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply);
+typedef int (*MPT_RESETHANDLER)(MPT_ADAPTER *ioc, int reset_phase);
+/* reset_phase defs */
+#define MPT_IOC_PRE_RESET              0
+#define MPT_IOC_POST_RESET             1
 
 /*
- *  Fibre Channel (SCSI) target device...
+ * Invent MPT host event (super-set of MPI Events)
+ * Fitted to 1030's 64-byte [max] request frame size
  */
-typedef struct _FC_TARGET {
-       struct _FC_TARGET       *forw;
-       struct _FC_TARGET       *back;
-       int                      bus_id;
-       int                      target_id;
-       int                      lun_exists[32];
-       u8                       inquiry_data[36];
-       u8                       last_sense[256];
-} FC_TARGET;
-
-typedef struct _FCDEV_TRACKER {
-       FC_TARGET       *head;
-       FC_TARGET       *tail;
-} FCDEV_TRACKER;
+typedef struct _MPT_HOST_EVENT {
+       EventNotificationReply_t         MpiEvent;      /* 8 32-bit words! */
+       u32                              pad[6];
+       void                            *next;
+} MPT_HOST_EVENT;
 
+#define MPT_HOSTEVENT_IOC_BRINGUP      0x91
+#define MPT_HOSTEVENT_IOC_RECOVER      0x92
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -523,6 +522,8 @@ extern int   mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass);
 extern void     mpt_deregister(int cb_idx);
 extern int      mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc);
 extern void     mpt_event_deregister(int cb_idx);
+extern int      mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func);
+extern void     mpt_reset_deregister(int cb_idx);
 extern int      mpt_register_ascqops_strings(/*ASCQ_Table_t*/void *ascqTable, int ascqtbl_sz, const char **opsTable);
 extern void     mpt_deregister_ascqops_strings(void);
 extern MPT_FRAME_HDR   *mpt_get_msg_frame(int handle, int iocid);
@@ -532,7 +533,7 @@ extern int   mpt_send_handshake_request(int handle, int iocid, int reqBytes, u32
 extern int      mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp);
 extern MPT_ADAPTER     *mpt_adapter_find_first(void);
 extern MPT_ADAPTER     *mpt_adapter_find_next(MPT_ADAPTER *prev);
-extern void     mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len);
+extern void     mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan);
 extern void     mpt_print_ioc_facts(MPT_ADAPTER *ioc, char *buf, int *size, int len);
 
 /*
index a939104e818708ec349d410afb65fa3e5e2e00d8..5809cee210cf3b0b68cac2e98b35eb35a641d69d 100644 (file)
@@ -27,7 +27,7 @@
  *  Originally By: Steven J. Ralston, Noah Romer
  *  (mailto:Steve.Ralston@lsil.com)
  *
- *  $Id: mptctl.c,v 1.23 2001/03/21 19:42:31 sralston Exp $
+ *  $Id: mptctl.c,v 1.25.4.1 2001/08/24 20:07:06 sralston Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -204,6 +204,22 @@ mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
        return 1;
 }
 
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ *  struct file_operations functionality. 
+ *  Members:
+ *     llseek, write, read, ioctl, open, release
+ */
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9)
+static loff_t
+mptctl_llseek(struct file *file, loff_t offset, int origin)
+{
+       return -ESPIPE;
+}
+#define no_llseek mptctl_llseek
+#endif
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 static ssize_t
 mptctl_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
@@ -335,8 +351,8 @@ mpt_ioctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen)
        SGESimple32_t   *sgl;
        SGESimple32_t   *sgOut, *sgIn;
        dma_addr_t       sgl_dma;
-       struct buflist  *buflist;
-       struct buflist  *bl;
+       struct buflist  *buflist = NULL;
+       struct buflist  *bl = NULL;
        int              numfrags = 0;
        int              maxfrags;
        int              n = 0;
@@ -421,7 +437,7 @@ mpt_ioctl_do_fw_download(int ioc, char *ufwbuf, size_t fwlen)
        sgIn = sgl;
        bl = buflist;
        for (i=0; i < numfrags; i++) {
-               nib = (sgIn->FlagsLength & 0xF0000000) >> 28;
+               nib = (le32_to_cpu(sgIn->FlagsLength) & 0xF0000000) >> 28;
                /* skip ignore/chain. */
                if (nib == 0 || nib == 3) {
                        ;
@@ -654,7 +670,7 @@ free_and_fail:
                        u8 *kptr;
                        int len;
 
-                       if ((sglbuf[i].FlagsLength >> 24) == 0x30)
+                       if ((le32_to_cpu(sglbuf[i].FlagsLength) >> 24) == 0x30)
                                continue;
 
                        dma_addr = le32_to_cpu(sglbuf[i].Address);
@@ -679,12 +695,12 @@ kfree_sgl(SGESimple32_t *sgl, dma_addr_t sgl_dma, struct buflist *buflist, MPT_A
        int              dir;
        int              n = 0;
 
-       if (sg->FlagsLength & 0x04000000)
+       if (le32_to_cpu(sg->FlagsLength) & 0x04000000)
                dir = PCI_DMA_TODEVICE;
        else
                dir = PCI_DMA_FROMDEVICE;
 
-       nib = (sg->FlagsLength & 0xF0000000) >> 28;
+       nib = (le32_to_cpu(sg->FlagsLength) & 0xF0000000) >> 28;
        while (! (nib & 0x4)) { /* eob */
                /* skip ignore/chain. */
                if (nib == 0 || nib == 3) {
@@ -703,7 +719,7 @@ kfree_sgl(SGESimple32_t *sgl, dma_addr_t sgl_dma, struct buflist *buflist, MPT_A
                }
                sg++;
                bl++;
-               nib = (sg->FlagsLength & 0xF0000000) >> 28;
+               nib = (le32_to_cpu(sg->FlagsLength) & 0xF0000000) >> 28;
        }
 
        /* we're at eob! */
@@ -1081,10 +1097,14 @@ mpt_ioctl_scsi_cmd(unsigned long arg)
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 
-static struct file_operations mptctl_fops = {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,51)
-       owner:          THIS_MODULE,
+#define        owner_THIS_MODULE  owner:               THIS_MODULE,
+#else
+#define        owner_THIS_MODULE
 #endif
+
+static struct file_operations mptctl_fops = {
+       owner_THIS_MODULE
        llseek:         no_llseek,
        read:           mptctl_read,
        write:          mptctl_write,
@@ -1162,48 +1182,6 @@ sparc32_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd,
        return ret;
 }
 
-#if 0          /* { */
-static int
-sparc32_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd,
-                       unsigned long arg, struct file *filp)
-{
-       struct mpt_fw_xfer32 kfw32;
-       struct mpt_fw_xfer kfw;
-       mm_segment_t old_fs;
-       int ret;
-
-       dprintk((KERN_INFO MYNAM "::sparc32_mptfwxfer_ioctl() called\n"));
-
-       if (copy_from_user(&kfw32, (char *)arg, sizeof(kfw32)))
-               return -EFAULT;
-
-       /* Verify intended MPT adapter */
-       iocnumX = kfw32.iocnum & 0xFF;
-       if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
-           (iocp == NULL)) {
-               printk(KERN_ERR MYNAM "::sparc32_mptfwxfer_ioctl @%d - ioc%d not found!\n",
-                               __LINE__, iocnumX);
-               return -ENODEV;
-       }
-
-       if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
-               return ret;
-
-       kfw.iocnum = iocnum;
-       kfw.fwlen = kfw32.fwlen;
-       kfw.bufp = (void *)(unsigned long)kfw32.bufp;
-
-       old_fs = get_fs();
-       set_fs(KERNEL_DS);
-       ret = sys_ioctl(fd, MPTFWDOWNLOAD, (unsigned long)&kfw);
-       set_fs(old_fs);
-
-       up(&mptctl_syscall_sem_ioc[iocp->id]);
-
-       return ret;
-}
-#endif         /* #if 0 } */
-
 #endif         /*} linux >= 2.3.x */
 #endif         /*} sparc */
 
@@ -1228,8 +1206,7 @@ int __init mptctl_init(void)
        if (++where && err) goto out_fail;
        err = register_ioctl32_conversion(MPTRWPERF_RESET, NULL);
        if (++where && err) goto out_fail;
-       err = register_ioctl32_conversion(MPTFWDOWNLOAD32,
-                                         sparc32_mptfwxfer_ioctl);
+       err = register_ioctl32_conversion(MPTFWDOWNLOAD32, sparc32_mptfwxfer_ioctl);
        if (++where && err) goto out_fail;
 #endif         /*} linux >= 2.3.x */
 #endif         /*} sparc */
@@ -1247,7 +1224,7 @@ int __init mptctl_init(void)
         *  Install our handler
         */
        ++where;
-       if ((mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER)) < 0) {
+       if ((mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER)) <= 0) {
                printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
                misc_deregister(&mptctl_miscdev);
                err = -EBUSY;
@@ -1275,6 +1252,16 @@ out_fail:
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 void mptctl_exit(void)
 {
+
+#if defined(__sparc__) && defined(__sparc_v9__)                /*{*/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)                /*{*/
+       unregister_ioctl32_conversion(MPTRWPERF);
+       unregister_ioctl32_conversion(MPTRWPERF_CHK);
+       unregister_ioctl32_conversion(MPTRWPERF_RESET);
+       unregister_ioctl32_conversion(MPTFWDOWNLOAD32);
+#endif         /*} linux >= 2.3.x */
+#endif         /*} sparc */
+
        misc_deregister(&mptctl_miscdev);
        printk(KERN_INFO MYNAM ": /dev/%s @ (major,minor=%d,%d)\n",
                         mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
index f619f2f12588cccf1675730ddaa84d283bd0b31a..542ac00eb1e54ab7500fca90909e33464b2e138e 100644 (file)
@@ -26,7 +26,7 @@
  *  Copyright (c) 2000-2001 LSI Logic Corporation
  *  Originally By: Noah Romer
  *
- *  $Id: mptlan.c,v 1.25 2001/03/02 22:12:04 sralston Exp $
+ *  $Id: mptlan.c,v 1.32.2.2 2001/07/12 19:43:33 nromer Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *  Fusion MPT LAN private structures
  */
 
+struct NAA_Hosed {
+       u16 NAA;
+       u8 ieee[FC_ALEN];
+       struct NAA_Hosed *next;
+};
+
 struct BufferControl {
        struct sk_buff  *skb;
        dma_addr_t      dma;
@@ -153,6 +159,7 @@ static int  mpt_lan_receive_post_reply(struct net_device *dev,
 static int  mpt_lan_send_turbo(struct net_device *dev, u32 tmsg);
 static int  mpt_lan_send_reply(struct net_device *dev,
                               LANSendReply_t *pSendRep);
+static int  mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase);
 static int  mpt_lan_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
 static unsigned short mpt_lan_type_trans(struct sk_buff *skb,
                                         struct net_device *dev);
@@ -168,6 +175,9 @@ static u32 tx_max_out_p = 127 - 16;
 
 static struct net_device *mpt_landev[MPT_MAX_ADAPTERS+1];
 
+static struct NAA_Hosed *mpt_bad_naa = NULL;
+rwlock_t bad_naa_lock;
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  * Fusion MPT LAN external data
@@ -316,6 +326,41 @@ lan_reply (MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
        return FreeReqFrame;
 }
 
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+static int
+mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
+{
+       struct net_device *dev = mpt_landev[ioc->id];
+       struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
+
+       dprintk((KERN_INFO MYNAM ": IOC %s_reset routed to LAN driver!\n",
+                       reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"));
+
+       if (priv->mpt_rxfidx == NULL)
+               return (1);
+
+       if (reset_phase == MPT_IOC_PRE_RESET) {
+               int i;
+               unsigned long flags;
+               
+               netif_stop_queue(dev);
+
+               atomic_set(&priv->buckets_out, 0);
+
+               /* Reset Rx Free Tail index and re-populate the queue. */
+               spin_lock_irqsave(&priv->rxfidx_lock, flags);
+               priv->mpt_rxfidx_tail = -1;
+               for (i = 0; i < priv->max_buckets_out; i++)
+                       priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = i;
+               spin_unlock_irqrestore(&priv->rxfidx_lock, flags);
+       } else {
+               mpt_lan_post_receive_buckets(dev);
+               netif_wake_queue(dev);
+       }
+
+       return 1;
+}
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 static int
 mpt_lan_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
@@ -356,7 +401,19 @@ mpt_lan_open(struct net_device *dev)
        struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
        int i;
 
-       mpt_lan_reset(dev);
+       if (mpt_lan_reset(dev) != 0) {
+               MPT_ADAPTER *mpt_dev = priv->mpt_dev;
+               
+               printk (KERN_WARNING MYNAM "/lan_open: lan_reset failed.");
+               
+               if (mpt_dev->active)
+                       printk ("The ioc is active. Perhaps it needs to be"
+                               " reset?\n");
+               else
+                       printk ("The ioc in inactive, most likely in the "
+                               "process of being reset. Please try again in "
+                               "a moment.\n");
+       }
 
        priv->mpt_txfidx = kmalloc(priv->tx_max_out * sizeof(int), GFP_KERNEL);
        if (priv->mpt_txfidx == NULL)
@@ -402,7 +459,10 @@ mpt_lan_open(struct net_device *dev)
                        IOC_AND_NETDEV_NAMES_s_s(dev));
 
        if (mpt_event_register(LanCtx, mpt_lan_event_process) != 0) {
-               /* FIXME! */
+               printk (KERN_WARNING MYNAM "/lo: Unable to register for Event"
+                       " Notifications. This is a bad thing! We're not going "
+                       "to go ahead, but I'd be leery of system stability at "
+                       "this point.\n");
        }
 
        netif_start_queue(dev);
@@ -422,6 +482,8 @@ out:        return -ENOMEM;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* Send a LanReset message to the FW. This should result in the FW returning
+   any buckets it still has. */
 static int
 mpt_lan_reset(struct net_device *dev)
 {
@@ -660,6 +722,8 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev)
        dma_addr_t dma;
        unsigned long flags;
        int ctx;
+       struct NAA_Hosed *nh;
+       u16 cur_naa = 0x1000;
 
        dioprintk((KERN_INFO MYNAM ": %s called, skb_addr = %p\n",
                        __FUNCTION__, skb));
@@ -707,8 +771,10 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev)
        priv->SendCtl[ctx].len = skb->len;
 
        /* Message Header */
+       pSendReq->Reserved    = 0;
        pSendReq->Function    = MPI_FUNCTION_LAN_SEND;
        pSendReq->ChainOffset = 0;
+       pSendReq->Reserved2   = 0;
        pSendReq->MsgFlags    = 0;
        pSendReq->PortNumber  = priv->pnum;
 
@@ -725,7 +791,26 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev)
 //                     IOC_AND_NETDEV_NAMES_s_s(dev),
 //                     ctx, skb, skb->data));
 
-       pTrans->TransactionDetails[0] = cpu_to_le32((0x1000          << 16) |
+       /* Munge the NAA for Tx packets to QLogic boards, which don't follow
+          RFC 2625. The longer I look at this, the more my opinion of Qlogic
+          drops. */
+       read_lock_irq(&bad_naa_lock);
+       for (nh = mpt_bad_naa; nh != NULL; nh=nh->next) {
+               if ((nh->ieee[0] == skb->mac.raw[0]) &&
+                   (nh->ieee[1] == skb->mac.raw[1]) &&
+                   (nh->ieee[2] == skb->mac.raw[2]) &&
+                   (nh->ieee[3] == skb->mac.raw[3]) &&
+                   (nh->ieee[4] == skb->mac.raw[4]) &&
+                   (nh->ieee[5] == skb->mac.raw[5])) {
+                       cur_naa = nh->NAA;
+                       dprintk ((KERN_INFO "mptlan/sdu_send: using NAA value "
+                                 "= %04x.\n", cur_naa));
+                       break;
+               }
+       }
+       read_unlock_irq(&bad_naa_lock);
+
+       pTrans->TransactionDetails[0] = cpu_to_le32((cur_naa         << 16) |
                                                    (skb->mac.raw[0] <<  8) |
                                                    (skb->mac.raw[1] <<  0));
        pTrans->TransactionDetails[1] = cpu_to_le32((skb->mac.raw[2] << 24) |
@@ -735,9 +820,15 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev)
 
        pSimple = (SGESimple64_t *) &pTrans->TransactionDetails[2];
 
+       /* If we ever decide to send more than one Simple SGE per LANSend, then
+          we will need to make sure that LAST_ELEMENT only gets set on the 
+          last one. Otherwise, bad voodoo and evil funkiness will commence. */
        pSimple->FlagsLength = cpu_to_le32(
-                       ((MPI_SGE_FLAGS_END_OF_BUFFER |
+                       ((MPI_SGE_FLAGS_LAST_ELEMENT | 
+                         MPI_SGE_FLAGS_END_OF_BUFFER |
                          MPI_SGE_FLAGS_SIMPLE_ELEMENT |
+                         MPI_SGE_FLAGS_SYSTEM_ADDRESS |
+                         MPI_SGE_FLAGS_HOST_TO_IOC |
                          MPI_SGE_FLAGS_64_BIT_ADDRESSING |
                          MPI_SGE_FLAGS_END_OF_LIST) << MPI_SGE_FLAGS_SHIFT) |
                        skb->len);
@@ -1252,12 +1343,12 @@ mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum)
        priv->total_posted = 0;
        priv->total_received = 0;
        priv->max_buckets_out = max_buckets_out;
-       if (mpt_dev->pfacts0.MaxLanBuckets < max_buckets_out)
-               priv->max_buckets_out = mpt_dev->pfacts0.MaxLanBuckets;
+       if (mpt_dev->pfacts[0].MaxLanBuckets < max_buckets_out)
+               priv->max_buckets_out = mpt_dev->pfacts[0].MaxLanBuckets;
 
        dprintk((KERN_INFO MYNAM "@%d: MaxLanBuckets=%d, max_buckets_out/priv=%d/%d\n",
                        __LINE__,
-                       mpt_dev->pfacts0.MaxLanBuckets,
+                       mpt_dev->pfacts[0].MaxLanBuckets,
                        max_buckets_out,
                        priv->max_buckets_out));
 
@@ -1316,7 +1407,11 @@ mpt_lan_init (void)
 
        show_mptmod_ver(LANAME, LANVER);
 
-       if ((LanCtx = mpt_register(lan_reply, MPTLAN_DRIVER)) < 0) {
+       /* Init the global r/w lock for the bad_naa list. We want to do this 
+          before any boards are initialized and may be used. */
+       rwlock_init(&bad_naa_lock);
+
+       if ((LanCtx = mpt_register(lan_reply, MPTLAN_DRIVER)) <= 0) {
                printk (KERN_ERR MYNAM ": Failed to register with MPT base driver\n");
                return -EBUSY;
        }
@@ -1326,6 +1421,15 @@ mpt_lan_init (void)
 
        dprintk((KERN_INFO MYNAM ": assigned context of %d\n", LanCtx));
 
+       if (mpt_reset_register(LanCtx, mpt_lan_ioc_reset) == 0) {
+               dprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n"));
+       } else {
+               printk(KERN_ERR MYNAM ": Eieee! unable to register a reset "
+                      "handler with mptbase! The world is at an end! "
+                      "Everything is fading to black! Goodbye.\n");
+               return -EBUSY;
+       }
+
        for (j = 0; j < MPT_MAX_ADAPTERS; j++) {
                mpt_landev[j] = NULL;
        }
@@ -1333,14 +1437,14 @@ mpt_lan_init (void)
 
        curadapter = mpt_adapter_find_first();
        while (curadapter != NULL) {
-               for (i = 0; i < curadapter->facts0.NumberOfPorts; i++) {
+               for (i = 0; i < curadapter->facts.NumberOfPorts; i++) {
                        printk (KERN_INFO MYNAM ": %s: PortNum=%x, ProtocolFlags=%02Xh (%c%c%c%c)\n",
                                        curadapter->name,
-                                       curadapter->pfacts0.PortNumber,
-                                       curadapter->pfacts0.ProtocolFlags,
-                                       MPT_PROTOCOL_FLAGS_c_c_c_c(curadapter->pfacts0.ProtocolFlags));
+                                       curadapter->pfacts[i].PortNumber,
+                                       curadapter->pfacts[i].ProtocolFlags,
+                                       MPT_PROTOCOL_FLAGS_c_c_c_c(curadapter->pfacts[i].ProtocolFlags));
 
-                       if (curadapter->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
+                       if (curadapter->pfacts[i].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
                                dev = mpt_register_lan_device (curadapter, i);
                                if (dev != NULL) {
                                        printk (KERN_INFO MYNAM ": %s: Fusion MPT LAN device registered as '%s'\n",
@@ -1361,7 +1465,7 @@ mpt_lan_init (void)
                                } else {
                                        printk (KERN_ERR MYNAM ": %s: Unable to register port%d as a LAN device\n",
                                                        curadapter->name,
-                                                       curadapter->pfacts0.PortNumber);
+                                                       curadapter->pfacts[i].PortNumber);
                                }
                        } else {
                                printk (KERN_INFO MYNAM ": %s: Hmmm... LAN protocol seems to be disabled on this adapter port!\n",
@@ -1379,6 +1483,8 @@ void __init mpt_lan_exit(void)
 {
        int i;
 
+       mpt_reset_deregister(LanCtx);
+
        for (i = 0; mpt_landev[i] != NULL; i++) {
                struct net_device *dev = mpt_landev[i];
 
@@ -1411,6 +1517,7 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev)
 {
        struct mpt_lan_ohdr *fch = (struct mpt_lan_ohdr *)skb->data;
        struct fcllc *fcllc;
+       u16 source_naa = fch->stype, found = 0;
 
        skb->mac.raw = skb->data;
        skb_pull(skb, sizeof(struct mpt_lan_ohdr));
@@ -1444,11 +1551,80 @@ mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev)
                }
        }
 
+       fcllc = (struct fcllc *)skb->data;
+
+       /* Workaround for QLogic not following RFC 2625 in regards to the NAA
+          value. */
+
+       if ((source_naa & 0xF000) == 0)
+               source_naa = swab16(source_naa);
+
+       if (fcllc->ethertype == htons(ETH_P_ARP))
+           dprintk ((KERN_INFO "mptlan/type_trans: got arp req/rep w/ naa of "
+                     "%04x.\n", source_naa));
+
+       if ((fcllc->ethertype == htons(ETH_P_ARP)) && 
+          ((source_naa >> 12) !=  MPT_LAN_NAA_RFC2625)){
+               struct NAA_Hosed *nh, *prevnh;
+               int i;
+
+               dprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep from "
+                         "system with non-RFC 2625 NAA value (%04x).\n",
+                         source_naa));
+
+               write_lock_irq(&bad_naa_lock);
+               for (prevnh = nh = mpt_bad_naa; nh != NULL;
+                    prevnh=nh, nh=nh->next) {
+                       if ((nh->ieee[0] == fch->saddr[0]) &&
+                           (nh->ieee[1] == fch->saddr[1]) &&
+                           (nh->ieee[2] == fch->saddr[2]) &&
+                           (nh->ieee[3] == fch->saddr[3]) &&
+                           (nh->ieee[4] == fch->saddr[4]) &&
+                           (nh->ieee[5] == fch->saddr[5])) {
+                               found = 1;
+                               dprintk ((KERN_INFO "mptlan/type_trans: ARP Re"
+                                        "q/Rep w/ bad NAA from system already"
+                                        " in DB.\n"));
+                               break;
+                       }
+               }
+               
+               if ((!found) && (nh == NULL)) {
+
+                       nh = kmalloc(sizeof(struct NAA_Hosed), GFP_KERNEL);
+                       dprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep w/"
+                                " bad NAA from system not yet in DB.\n"));
+
+                       if (nh != NULL) {
+                               nh->next = NULL;
+                               if (!mpt_bad_naa)
+                                       mpt_bad_naa = nh;
+                               if (prevnh)
+                                       prevnh->next = nh;
+                               
+                               nh->NAA = source_naa; /* Set the S_NAA value. */
+                               for (i = 0; i < FC_ALEN; i++)
+                                       nh->ieee[i] = fch->saddr[i];
+                               dprintk ((KERN_INFO "Got ARP from %02x:%02x:%02x:%02x:"
+                                         "%02x:%02x with non-compliant S_NAA value.\n",
+                                         fch->saddr[0], fch->saddr[1], fch->saddr[2],
+                                         fch->saddr[3], fch->saddr[4],fch->saddr[5]));
+                       } else {
+                               printk (KERN_ERR "mptlan/type_trans: Unable to"
+                                       " kmalloc a NAA_Hosed struct.\n");
+                       }
+               } else if (!found) {
+                       printk (KERN_ERR "mptlan/type_trans: found not"
+                               " set, but nh isn't null. Evil "
+                               "funkiness abounds.\n");
+               }
+               write_unlock_irq(&bad_naa_lock);
+       }
+               
+
        /* Strip the SNAP header from ARP packets since we don't 
         * pass them through to the 802.2/SNAP layers.
         */
-       fcllc = (struct fcllc *)skb->data;
-
        if (fcllc->dsap == EXTENDED_SAP &&
                (fcllc->ethertype == htons(ETH_P_IP) ||
                 fcllc->ethertype == htons(ETH_P_ARP))) {
index c32cfa01f2c18043bb961861f207b0593ff3d443..10f2976dff64b5eb86461842bcd00c2b7bda84b8 100644 (file)
@@ -51,6 +51,9 @@ MODULE_DESCRIPTION(LANAME);
 #define MPT_LAN_MAX_MTU                65280           /* RFC2625 */
 #define MPT_LAN_MTU             16128          /* be nice to slab allocator */
 
+#define MPT_LAN_NAA_RFC2625     0x1
+#define MPT_LAN_NAA_QLOGIC      0x2
+
 /* MPT LAN Reset and Suspend Resource Flags Defines */
 
 #define MPT_LAN_RESOURCE_FLAG_RETURN_POSTED_BUCKETS    0x01
index d1a21e1e0c43954b90e409323f38054f6a2c8b38..74a76bc75c317ccb738f7b87ba2c4729e23d2fa7 100644 (file)
@@ -19,7 +19,7 @@
  *  Original author: Steven J. Ralston
  *  (mailto:Steve.Ralston@lsil.com)
  *
- *  $Id: mptscsih.c,v 1.24 2001/03/22 08:45:08 sralston Exp $
+ *  $Id: mptscsih.c,v 1.29 2001/06/18 18:59:05 sralston Exp $
  */
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
@@ -95,7 +95,6 @@ typedef struct _MPT_SCSI_HOST {
        u8                       *SgHunks;
        dma_addr_t                SgHunksDMA;
        u32                       qtag_tick;
-       FCDEV_TRACKER             TargetsQ;
 } MPT_SCSI_HOST;
 
 typedef struct _MPT_SCSI_DEV {
@@ -119,6 +118,7 @@ static int  mptscsih_io_direction(Scsi_Cmnd *cmd);
 static void    copy_sense_data(Scsi_Cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
 static u32     SCPNT_TO_MSGCTX(Scsi_Cmnd *sc);
 
+static int     mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
 static int     mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
 
 
@@ -205,7 +205,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r)
                        dprintk((KERN_INFO MYNAM ": *NEW* SCSI device (%d:%d:%d)!\n",
                                           sc->device->id, sc->device->lun, sc->device->channel));
                        if ((sc->device->hostdata = kmalloc(sizeof(MPT_SCSI_DEV), GFP_ATOMIC)) == NULL) {
-                               printk(KERN_ERR MYNAM ": ERROR: kmalloc(%d) FAILED!\n", (int)sizeof(MPT_SCSI_DEV));
+                               printk(KERN_ERR MYNAM ": ERROR - kmalloc(%d) FAILED!\n", (int)sizeof(MPT_SCSI_DEV));
                        } else {
                                memset(sc->device->hostdata, 0, sizeof(MPT_SCSI_DEV));
                                mpt_sdev = (MPT_SCSI_DEV *) sc->device->hostdata;
@@ -555,8 +555,14 @@ mptscsih_detect(Scsi_Host_Template *tpnt)
        if (! BeenHereDoneThat++) {
                show_mptmod_ver(my_NAME, my_VERSION);
 
-               ScsiDoneCtx = mpt_register(mptscsih_io_done, MPTSCSIH_DRIVER);
-               ScsiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSCSIH_DRIVER);
+               if ((ScsiDoneCtx = mpt_register(mptscsih_io_done, MPTSCSIH_DRIVER)) <= 0) {
+                       printk(KERN_ERR MYNAM ": Failed to register callback1 with MPT base driver\n");
+                       return mpt_scsi_hosts;
+               }
+               if ((ScsiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSCSIH_DRIVER)) <= 0) {
+                       printk(KERN_ERR MYNAM ": Failed to register callback2 with MPT base driver\n");
+                       return mpt_scsi_hosts;
+               }
 
 #ifndef MPT_SCSI_USE_NEW_EH
                Q_INIT(&mpt_scsih_taskQ, MPT_FRAME_HDR);
@@ -568,6 +574,12 @@ mptscsih_detect(Scsi_Host_Template *tpnt)
                } else {
                        /* FIXME! */
                }
+
+               if (mpt_reset_register(ScsiDoneCtx, mptscsih_ioc_reset) == 0) {
+                       dprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n"));
+               } else {
+                       /* FIXME! */
+               }
        }
 
        dprintk((KERN_INFO MYNAM ": mpt_scsih_detect()\n"));
@@ -582,7 +594,7 @@ mptscsih_detect(Scsi_Host_Template *tpnt)
                 *  Added sanity check on SCSI Initiator-mode enabled
                 *  for this MPT adapter.
                 */
-               if (!(this->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR)) {
+               if (!(this->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR)) {
                        printk(KERN_ERR MYNAM ": Skipping %s because SCSI Initiator mode is NOT enabled!\n",
                                        this->name);
                        this = mpt_adapter_find_next(this);
@@ -612,10 +624,18 @@ mptscsih_detect(Scsi_Host_Template *tpnt)
 
                        /* Yikes!  This is important!
                         * Otherwise, by default, linux only scans target IDs 0-7!
+                        *
+                        * BUG FIX!  20010618 -sralston & pdelaney
+                        * FC919 testing was encountering "duplicate" FC devices,
+                        * as it turns out because the 919 was returning 512
+                        * for PortFacts.MaxDevices, causing a wraparound effect
+                        * in SCSI IO requests.  So instead of using:
+                        *     sh->max_id = this->pfacts[0].MaxDevices - 1
+                        * we'll use a definitive max here.
                         */
-                       sh->max_id = this->pfacts0.MaxDevices - 1;
+                       sh->max_id = MPT_MAX_FC_DEVICES;
 
-                       sh->this_id = this->pfacts0.PortSCSIID;
+                       sh->this_id = this->pfacts[0].PortSCSIID;
 
                        restore_flags(flags);
 
@@ -730,6 +750,9 @@ mptscsih_release(struct Scsi_Host *host)
 #if 0
                        mptscsih_flush_pending();
 #endif
+                       mpt_reset_deregister(ScsiDoneCtx);
+                       dprintk((KERN_INFO MYNAM ": Deregistered for IOC reset notifications\n"));
+
                        mpt_event_deregister(ScsiDoneCtx);
                        dprintk((KERN_INFO MYNAM ": Deregistered for IOC event notifications\n"));
 
@@ -765,7 +788,7 @@ mptscsih_info(struct Scsi_Host *SChost)
 
        h = (MPT_SCSI_HOST *)SChost->hostdata;
        info_kbuf[0] = '\0';
-       mpt_print_ioc_summary(h->ioc, info_kbuf, &size, 0);
+       mpt_print_ioc_summary(h->ioc, info_kbuf, &size, 0, 0);
        info_kbuf[size-1] = '\0';
 
        return info_kbuf;
@@ -1235,7 +1258,6 @@ mptscsih_qcmd(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
                dprintk((KERN_INFO MYNAM ": Queue depth now %d.\n", max_qd));
        }
 
-       mb();
        dmfprintk((KERN_INFO MYNAM ": Issued SCSI cmd (%p)\n", SCpnt));
 
        return 0;
@@ -1265,6 +1287,7 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
        u32             *msg;
        u32              ctx2abort;
        int              i;
+       unsigned long    flags;
 
        printk(KERN_WARNING MYNAM ": Attempting _ABORT SCSI IO (=%p)\n", SCpnt);
        printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));
@@ -1309,41 +1332,59 @@ mptscsih_abort(Scsi_Cmnd * SCpnt)
         *       the controller, so it does not matter. -DaveM
         */
        ctx2abort = SCPNT_TO_MSGCTX(SCpnt);
-       dprintk((KERN_INFO MYNAM ":DbG: ctx2abort = %08x\n", ctx2abort));
-       pScsiTm->TaskMsgContext = ctx2abort;
-
-       wmb();
+       if (ctx2abort == -1) {
+               printk(KERN_ERR MYNAM ": ERROR - ScsiLookup fail(#2) for SCpnt=%p\n", SCpnt);
+               SCpnt->result = DID_SOFT_ERROR << 16;
+               spin_lock_irqsave(&io_request_lock, flags);
+               SCpnt->scsi_done(SCpnt);
+               spin_unlock_irqrestore(&io_request_lock, flags);
+               mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+       } else {
+               dprintk((KERN_INFO MYNAM ":DbG: ctx2abort = %08x\n", ctx2abort));
+               pScsiTm->TaskMsgContext = ctx2abort;
 
-/* MPI v0.10 requires SCSITaskMgmt requests be sent via Doorbell/handshake
-       mpt_put_msg_frame(hd->ioc->id, mf);
-*/
-/* FIXME!  Check return status! */
-       (void) mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id, sizeof(SCSITaskMgmt_t), msg);
 
-       wmb();
+               /* MPI v0.10 requires SCSITaskMgmt requests be sent via Doorbell/handshake
+                       mpt_put_msg_frame(hd->ioc->id, mf);
+               */
+               if ((i = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id,
+                                       sizeof(SCSITaskMgmt_t), msg))
+                   != 0) {
+                       printk(KERN_WARNING MYNAM
+                                       ": WARNING[2] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n",
+                                       i, mf, SCpnt);
+                       SCpnt->result = DID_SOFT_ERROR << 16;
+                       spin_lock_irqsave(&io_request_lock, flags);
+                       SCpnt->scsi_done(SCpnt);
+                       spin_unlock_irqrestore(&io_request_lock, flags);
+                       mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+               }
+       }
 
-       return SUCCESS;
+       //return SUCCESS;
+       return FAILED;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
- *     mptscsih_bus_reset - Perform a SCSI BUS_RESET!  new_eh variant
+ *     mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
  *     @SCpnt: Pointer to Scsi_Cmnd structure, IO which reset is due to
  *
- *     (linux Scsi_Host_Template.eh_bus_reset_handler routine)
+ *     (linux Scsi_Host_Template.eh_dev_reset_handler routine)
  *
  *     Returns SUCCESS or FAILED.
  */
 int
-mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
+mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
 {
        MPT_FRAME_HDR   *mf;
        SCSITaskMgmt_t  *pScsiTm;
        MPT_SCSI_HOST   *hd;
        u32             *msg;
        int              i;
+       unsigned long    flags;
 
-       printk(KERN_WARNING MYNAM ": Attempting _BUS_RESET (%p)\n", SCpnt);
+       printk(KERN_WARNING MYNAM ": Attempting _TARGET_RESET (%p)\n", SCpnt);
        printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));
 
        hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata;
@@ -1356,7 +1397,7 @@ mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
        }
 
        pScsiTm = (SCSITaskMgmt_t *) mf;
-       msg = (u32 *) mf;
+       msg = (u32*)mf;
 
        pScsiTm->TargetID = SCpnt->target;
        pScsiTm->Bus = hd->port;
@@ -1364,10 +1405,11 @@ mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
        pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
 
        pScsiTm->Reserved = 0;
-       pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS;
+       pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
        pScsiTm->Reserved1 = 0;
        pScsiTm->MsgFlags = 0;
 
+       /* _TARGET_RESET goes to LUN 0 always! */
        for (i = 0; i < 8; i++)
                pScsiTm->LUN[i] = 0;
 
@@ -1377,38 +1419,47 @@ mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
 
        pScsiTm->TaskMsgContext = cpu_to_le32(0);
 
-       wmb();
-
 /* MPI v0.10 requires SCSITaskMgmt requests be sent via Doorbell/handshake
        mpt_put_msg_frame(hd->ioc->id, mf);
 */
 /* FIXME!  Check return status! */
-       (void) mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id, sizeof(SCSITaskMgmt_t), msg);
-
-       wmb();
+       if ((i = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id,
+                               sizeof(SCSITaskMgmt_t), msg))
+           != 0) {
+               printk(KERN_WARNING MYNAM
+                               ": WARNING[3] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n",
+                               i, mf, SCpnt);
+               SCpnt->result = DID_SOFT_ERROR << 16;
+               spin_lock_irqsave(&io_request_lock, flags);
+               SCpnt->scsi_done(SCpnt);
+               spin_unlock_irqrestore(&io_request_lock, flags);
+               mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+       }
 
-       return SUCCESS;
+       //return SUCCESS;
+       return FAILED;
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
- *     mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
+ *     mptscsih_bus_reset - Perform a SCSI BUS_RESET!  new_eh variant
  *     @SCpnt: Pointer to Scsi_Cmnd structure, IO which reset is due to
  *
- *     (linux Scsi_Host_Template.eh_dev_reset_handler routine)
+ *     (linux Scsi_Host_Template.eh_bus_reset_handler routine)
  *
  *     Returns SUCCESS or FAILED.
  */
 int
-mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
+mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
 {
        MPT_FRAME_HDR   *mf;
        SCSITaskMgmt_t  *pScsiTm;
        MPT_SCSI_HOST   *hd;
        u32             *msg;
        int              i;
+       unsigned long    flags;
 
-       printk(KERN_WARNING MYNAM ": Attempting _TARGET_RESET (%p)\n", SCpnt);
+       printk(KERN_WARNING MYNAM ": Attempting _BUS_RESET (%p)\n", SCpnt);
        printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));
 
        hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata;
@@ -1421,7 +1472,7 @@ mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
        }
 
        pScsiTm = (SCSITaskMgmt_t *) mf;
-       msg = (u32*)mf;
+       msg = (u32 *) mf;
 
        pScsiTm->TargetID = SCpnt->target;
        pScsiTm->Bus = hd->port;
@@ -1429,11 +1480,10 @@ mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
        pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
 
        pScsiTm->Reserved = 0;
-       pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
+       pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS;
        pScsiTm->Reserved1 = 0;
        pScsiTm->MsgFlags = 0;
 
-       /* _TARGET_RESET goes to LUN 0 always! */
        for (i = 0; i < 8; i++)
                pScsiTm->LUN[i] = 0;
 
@@ -1443,15 +1493,22 @@ mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
 
        pScsiTm->TaskMsgContext = cpu_to_le32(0);
 
-       wmb();
-
 /* MPI v0.10 requires SCSITaskMgmt requests be sent via Doorbell/handshake
        mpt_put_msg_frame(hd->ioc->id, mf);
 */
 /* FIXME!  Check return status! */
-       (void) mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id, sizeof(SCSITaskMgmt_t), msg);
-
-       wmb();
+       if ((i = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id,
+                               sizeof(SCSITaskMgmt_t), msg))
+           != 0) {
+               printk(KERN_WARNING MYNAM
+                               ": WARNING[4] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n",
+                               i, mf, SCpnt);
+               SCpnt->result = DID_SOFT_ERROR << 16;
+               spin_lock_irqsave(&io_request_lock, flags);
+               SCpnt->scsi_done(SCpnt);
+               spin_unlock_irqrestore(&io_request_lock, flags);
+               mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+       }
 
        return SUCCESS;
 }
@@ -1646,6 +1703,9 @@ mptscsih_taskmgmt_bh(void *sc)
        spin_unlock_irqrestore(&mpt_scsih_taskQ_lock, flags);
 
        while (1) {
+               current->state = TASK_INTERRUPTIBLE;
+               schedule_timeout(HZ/4);
+
                /*
                 *  We MUST remove item from taskQ *before* we format the
                 *  frame as a SCSITaskMgmt request and send it down to the IOC.
@@ -1664,9 +1724,10 @@ mptscsih_taskmgmt_bh(void *sc)
 
                SCpnt = (Scsi_Cmnd*)mf->u.frame.linkage.argp1;
                if (SCpnt == NULL) {
-                       printk(KERN_ERR MYNAM ": ERROR: TaskMgmt has NULL SCpnt! (%p:%p)\n", mf, SCpnt);
+                       printk(KERN_ERR MYNAM ": ERROR - TaskMgmt has NULL SCpnt! (%p:%p)\n", mf, SCpnt);
                        continue;
                }
+               hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata;
                pScsiTm = (SCSITaskMgmt_t *) mf;
 
                for (i = 0; i < 8; i++) {
@@ -1674,9 +1735,9 @@ mptscsih_taskmgmt_bh(void *sc)
                }
 
                task_type = mf->u.frame.linkage.arg1;
-               if (task_type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
-               {
-                       printk(KERN_WARNING MYNAM ": Attempting _ABORT SCSI IO! (mf:sc=%p:%p)\n", mf, SCpnt);
+               if (task_type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
+                       printk(KERN_WARNING MYNAM ": Attempting _ABORT SCSI IO! (mf=%p:sc=%p)\n",
+                                       mf, SCpnt);
 
                        /* Most important!  Set TaskMsgContext to SCpnt's MsgContext!
                         * (the IO to be ABORT'd)
@@ -1686,11 +1747,20 @@ mptscsih_taskmgmt_bh(void *sc)
                         *       the controller, so it does not matter. -DaveM
                         */
                        ctx2abort = SCPNT_TO_MSGCTX(SCpnt);
+                       if (ctx2abort == -1) {
+                               printk(KERN_ERR MYNAM ": ERROR - ScsiLookup fail(#1) for SCpnt=%p\n", SCpnt);
+                               SCpnt->result = DID_SOFT_ERROR << 16;
+                               spin_lock_irqsave(&io_request_lock, flags);
+                               SCpnt->scsi_done(SCpnt);
+                               spin_unlock_irqrestore(&io_request_lock, flags);
+                               mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+                               continue;
+                       }
                        pScsiTm->LUN[1] = SCpnt->lun;
                }
                else if (task_type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
                {
-                       printk(KERN_WARNING MYNAM ": Attempting _BUS_RESET! (against SCSI IO mf:sc=%p:%p)\n", mf, SCpnt);
+                       printk(KERN_WARNING MYNAM ": Attempting _BUS_RESET! (against SCSI IO mf=%p:sc=%p)\n", mf, SCpnt);
                }
 #if 0
                else if (task_type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {}
@@ -1699,8 +1769,6 @@ mptscsih_taskmgmt_bh(void *sc)
 
                printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));
 
-               hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata;
-
                pScsiTm->TargetID = SCpnt->target;
                pScsiTm->Bus = hd->port;
                pScsiTm->ChainOffset = 0;
@@ -1725,15 +1793,22 @@ mptscsih_taskmgmt_bh(void *sc)
                 *              mpt_put_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
                 *  SCSITaskMgmt requests MUST be sent ONLY via
                 *  Doorbell/handshake now.   :-(
-                *
-                *  FIXME!  Check return status!
                 */
-               (void) mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id, sizeof(SCSITaskMgmt_t), (u32*)mf);
-
-               /* Spin-Wait for TaskMgmt complete!!! */
-               while (mpt_scsih_active_taskmgmt_mf != NULL) {
-                       current->state = TASK_INTERRUPTIBLE;
-                       schedule_timeout(HZ/2);
+               if ((i = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id,
+                                       sizeof(SCSITaskMgmt_t), (u32*) mf))
+                   != 0) {
+                       printk(KERN_WARNING MYNAM ": WARNING[1] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n", i, mf, SCpnt);
+                       SCpnt->result = DID_SOFT_ERROR << 16;
+                       spin_lock_irqsave(&io_request_lock, flags);
+                       SCpnt->scsi_done(SCpnt);
+                       spin_unlock_irqrestore(&io_request_lock, flags);
+                       mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+               } else {
+                       /* Spin-Wait for TaskMgmt complete!!! */
+                       while (mpt_scsih_active_taskmgmt_mf != NULL) {
+                               current->state = TASK_INTERRUPTIBLE;
+                               schedule_timeout(HZ/4);
+                       }
                }
        }
 
@@ -2003,6 +2078,22 @@ SCPNT_TO_MSGCTX(Scsi_Cmnd *sc)
 #endif
 
 
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+static int
+mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
+{
+       dprintk((KERN_INFO MYNAM ": IOC %s_reset routed to SCSI host driver!\n",
+                       reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"));
+
+       if (reset_phase == MPT_IOC_PRE_RESET) {
+               /* FIXME! Do pre-reset cleanup */
+       } else {
+               /* FIXME! Do post-reset cleanup */
+       }
+
+       return 1;               /* currently means nothing really */
+}
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 static int
 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
index fbb4e37154bf6c7b0d01479db6ffb9b92b4edb79..421b6e3667bdb0c60e2c3f995b0c17f957492861 100644 (file)
@@ -8,7 +8,7 @@
  *  Written By: Steven J. Ralston (19960517)
  *  (mailto:Steve.Ralston@lsil.com)
  *
- *  $Id: scsi3.h,v 1.4 2001/01/06 15:54:25 sralston Exp $
+ *  $Id: scsi3.h,v 1.5 2001/04/06 14:31:32 sralston Exp $
  */
 
 #ifndef SCSI3_H_INCLUDED
 #define CMD_WriteVerify        0x2E
 #define CMD_Verify             0x2F
 #define CMD_ReadDefectData     0x37
+#define CMD_ReadLong           0x3E
 #define CMD_LogSelect          0x4C
 #define CMD_LogSense           0x4D
 #define CMD_ModeSelect10       0x55
 #define CMD_Reserve10          0x56
 #define CMD_Release10          0x57
 #define CMD_ModeSense10        0x5A
+#define CMD_PersistReserveIn   0x5E
+#define CMD_PersistReserveOut  0x5F
 #define CMD_ReportLuns         0xA0
 
 /*
index 189dcce81b307c349c20b9631e73875462b93522..ae7f4d415fc306dbd4fc016253d83f34cfb0630d 100644 (file)
@@ -165,9 +165,16 @@ static struct net_device *init_netdev(struct net_device *dev, int sizeof_priv,
        setup(dev);
        
        if (new_device) {
+               int err;
+
                rtnl_lock();
-               register_netdevice(dev);
+               err = register_netdevice(dev);
                rtnl_unlock();
+
+               if (err < 0) {
+                       kfree(dev);
+                       dev = NULL;
+               }
        }
        return dev;
 }
index 0c67cc0208e05c3cd6b25aebb619fbf7ded1028c..ed6cd16d2cc87369ed8a90829e03442ad1a9fac7 100644 (file)
@@ -575,7 +575,6 @@ static int process_xmt_interrupt(struct net_device *dev)
        outb(0xff, EDLC_XCLR);  /* Clear all pending xmit IRQ's */
        
        if (xmit_stat & XS_COLL){
-                printk("ether collision\n"); /* FIXME: remove */
                PRINTK((KERN_DEBUG "%s: collision detected, retransmitting\n", 
                        dev->name));
                outw(NI5010_BUFSIZE - lp->o_pkt_size, IE_GP);
index 78919f3312d528b1d75094833ed09a9d6a666587..7b2e236b3eaafb68fc192d401b319cea4a5c9cf1 100644 (file)
        - Initialize the TxMode register properly
        - Don't dereference dev->priv after freeing it
 
+       LK1.3.4 (Ion Badulescu)
+       - Fixed initialization timing problems
+       - Fixed interrupt mask definitions
+
 TODO:
        - implement tx_timeout() properly
 */
 
 #define DRV_NAME       "starfire"
-#define DRV_VERSION    "1.03+LK1.3.3"
-#define DRV_RELDATE    "July 05, 2001"
+#define DRV_VERSION    "1.03+LK1.3.4"
+#define DRV_RELDATE    "August 14, 2001"
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <asm/processor.h>             /* Processor type for cache alignment. */
+#include <asm/uaccess.h>
+#include <asm/io.h>
 
 /*
  * Adaptec's license for their Novell drivers (which is where I got the
@@ -124,6 +140,10 @@ TODO:
 #define ZEROCOPY
 #endif
 
+#ifdef HAS_FIRMWARE
+#include "starfire_firmware.h"
+#endif /* HAS_FIRMWARE */
+
 /* The user-configurable values.
    These may be modified when a driver module is loaded.*/
 
@@ -196,22 +216,6 @@ static int full_duplex[MAX_UNITS] = {0, };
 #define skb_first_frag_len(skb)        (skb->len)
 #endif /* not ZEROCOPY */
 
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <asm/processor.h>             /* Processor type for cache alignment. */
-#include <asm/uaccess.h>
-#include <asm/io.h>
-
-#ifdef HAS_FIRMWARE
-#include "starfire_firmware.h"
-#endif /* HAS_FIRMWARE */
-
 /* 2.2.x compatibility code */
 #if LINUX_VERSION_CODE < 0x20300
 
@@ -242,7 +246,6 @@ static int full_duplex[MAX_UNITS] = {0, };
 /* These identify the driver base version and may not be removed. */
 static char version[] __devinitdata =
 KERN_INFO "starfire.c:v1.03 7/26/2000  Written by Donald Becker <becker@scyld.com>\n"
-KERN_INFO " Updates and info at http://www.scyld.com/network/starfire.html\n"
 KERN_INFO " (unofficial 2.2/2.4 kernel port, version " DRV_VERSION ", " DRV_RELDATE ")\n";
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
@@ -417,7 +420,7 @@ enum intr_status_bits {
        /* not quite bits */
        IntrRxDone=IntrRxQ2Done | IntrRxQ1Done,
        IntrRxEmpty=IntrRxDescQ1Low | IntrRxDescQ2Low,
-       IntrNormalMask=0xf0, IntrAbnormalMask=0x3f0e,
+       IntrNormalMask=0xff00, IntrAbnormalMask=0x3ff00fe,
 };
 
 /* Bits in the RxFilterMode register. */
@@ -656,10 +659,7 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
 
 #ifdef ZEROCOPY
        /* Starfire can do SG and TCP/UDP checksumming */
-       dev->features |= NETIF_F_SG;
-#ifdef HAS_FIRMWARE
-       dev->features |= NETIF_F_IP_CSUM;
-#endif /* HAS_FIRMWARE */
+       dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
 #endif /* ZEROCOPY */
 
        /* Serial EEPROM reads are hidden by the hardware. */
@@ -745,7 +745,7 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
                int mii_status;
                for (phy = 0; phy < 32 && phy_idx < PHY_CNT; phy++) {
                        mdio_write(dev, phy, MII_BMCR, BMCR_RESET);
-                       udelay(500);
+                       mdelay(100);
                        boguscnt = 1000;
                        while (--boguscnt > 0)
                                if ((mdio_read(dev, phy, MII_BMCR) & BMCR_RESET) == 0)
@@ -768,6 +768,14 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
                np->phy_cnt = phy_idx;
        }
 
+#ifdef ZEROCOPY
+       printk(KERN_INFO "%s: scatter-gather and hardware TCP cksumming enabled.\n",
+              dev->name,
+#else  /* not ZEROCOPY */
+       printk(KERN_INFO "%s: scatter-gather and hardware TCP cksumming disabled.\n",
+              dev->name);
+#endif /* not ZEROCOPY */
+
        return 0;
 
 err_out_cleardev:
@@ -931,6 +939,7 @@ static int netdev_open(struct net_device *dev)
        /* Configure the PCI bus bursts and FIFO thresholds. */
        np->tx_mode = 0x0C04;           /* modified when link is up. */
        writel(0x8000 | np->tx_mode, ioaddr + TxMode);
+       udelay(1000);
        writel(np->tx_mode, ioaddr + TxMode);
        np->tx_threshold = 4;
        writel(np->tx_threshold, ioaddr + TxThreshold);
@@ -1546,6 +1555,7 @@ static void netdev_media_change(struct net_device *dev)
                if (np->tx_mode != new_tx_mode) {
                        np->tx_mode = new_tx_mode;
                        writel(np->tx_mode | 0x8000, ioaddr + TxMode);
+                       udelay(1000);
                        writel(np->tx_mode, ioaddr + TxMode);
                }
        } else {
diff --git a/drivers/net/starfire_firmware.pl b/drivers/net/starfire_firmware.pl
new file mode 100644 (file)
index 0000000..0c82b80
--- /dev/null
@@ -0,0 +1,31 @@
+#!/usr/bin/perl
+
+# This script can be used to generate a new starfire_firmware.h
+# from GFP_RX.DAT and GFP_TX.DAT, files included with the DDK
+# and also with the Novell drivers.
+
+open FW, "GFP_RX.DAT" || die;
+open FWH, ">starfire_firmware.h" || die;
+
+printf(FWH "static u32 firmware_rx[] = {\n");
+$counter = 0;
+while ($foo = <FW>) {
+  chomp;
+  printf(FWH "  0x%s, 0x0000%s,\n", substr($foo, 4, 8), substr($foo, 0, 4));
+  $counter++;
+}
+
+close FW;
+open FW, "GFP_TX.DAT" || die;
+
+printf(FWH "};\t/* %d Rx instructions */\n#define FIRMWARE_RX_SIZE %d\n\nstatic u32 firmware_tx[] = {\n", $counter, $counter);
+$counter = 0;
+while ($foo = <FW>) {
+  chomp;
+  printf(FWH "  0x%s, 0x0000%s,\n", substr($foo, 4, 8), substr($foo, 0, 4));
+  $counter++;
+}
+
+close FW;
+printf(FWH "};\t/* %d Tx instructions */\n#define FIRMWARE_TX_SIZE %d\n", $counter, $counter);
+close(FWH);
index 67c24feec39c5b9d28a3eccb6e5536af597ceac3..dc7a5c13d1e0c3b9a2c51d546783645fe07932eb 100644 (file)
        - Manfred Spraul: use "singlecopy" for unaligned buffers
                          don't allocate bounce buffers for !ReqTxAlign cards
 
+       LK1.1.11:
+       - David Woodhouse: Set dev->base_addr before the first time we call
+                                          wait_for_reset(). It's a lot happier that way.
+                                          Free np->tx_bufs only if we actually allocated it.
 */
 
 
@@ -151,7 +155,7 @@ static const int multicast_filter_limit = 32;
 
 /* These identify the driver base version and may not be removed. */
 static char version[] __devinitdata =
-KERN_INFO "via-rhine.c:v1.10-LK1.1.10  07/12/2001  Written by Donald Becker\n"
+KERN_INFO "via-rhine.c:v1.10-LK1.1.11  20/08/2001  Written by Donald Becker\n"
 KERN_INFO "  http://www.scyld.com/network/via-rhine.html\n";
 
 static char shortname[] __devinitdata = "via-rhine";
@@ -584,6 +588,8 @@ static int __devinit via_rhine_init_one (struct pci_dev *pdev,
 
        /* Reset the chip to erase previous misconfiguration. */
        writew(CmdReset, ioaddr + ChipCmd);
+
+       dev->base_addr = ioaddr;
        wait_for_reset(dev, shortname);
 
        /* Reload the station address from the EEPROM. */
@@ -609,7 +615,6 @@ static int __devinit via_rhine_init_one (struct pci_dev *pdev,
                writeb(readb(ioaddr + ConfigA) & 0xFE, ioaddr + ConfigA);
        }
 
-       dev->base_addr = ioaddr;
        dev->irq = pdev->irq;
 
        np = dev->priv;
@@ -758,8 +763,11 @@ void free_ring(struct net_device* dev)
                            TX_RING_SIZE * sizeof(struct tx_desc),
                            np->rx_ring, np->rx_ring_dma);
 
-       pci_free_consistent(np->pdev, PKT_BUF_SZ * TX_RING_SIZE,
-                                               np->tx_bufs, np->tx_bufs_dma);
+       if (np->tx_bufs)
+               pci_free_consistent(np->pdev, PKT_BUF_SZ * TX_RING_SIZE,
+                                                       np->tx_bufs, np->tx_bufs_dma);
+
+       np->tx_bufs = NULL;
 
 }
 
index edee6c5e04feced733ed068335c7c00695f1784f..3d977689bee8620afd4b4b658b0249191598909b 100644 (file)
@@ -1,3 +1,13 @@
+2001-08-30  Tim Waugh  <twaugh@redhat.com>
+
+       * parport_serial.c (parport_serial_pci_probe): Clean-up on partial
+       registration failure.
+
+2001-08-14  Tim Waugh  <twaugh@redhat.com>
+
+       * parport_pc.c (parport_pc_init_superio): Allow for more than one
+       SuperIO device.  Patch from Rich Lio (ITE).
+
 2001-08-11  Tim Waugh  <twaugh@redhat.com>
 
        * parport_pc.c: Support for Titan Electronics cards.
index e5e9d5aabcafe06e2e5570d69a1f4ef88fc3e812..a0e8000d06a778e2a2c54a3b8930877268b975cd 100644 (file)
@@ -2756,17 +2756,20 @@ static int __init parport_pc_init_superio (int autoirq, int autodma)
 {
        const struct pci_device_id *id;
        struct pci_dev *pdev;
+       int ret = 0;
 
        pci_for_each_dev(pdev) {
                id = pci_match_device (parport_pc_pci_tbl, pdev);
                if (id == NULL || id->driver_data >= last_sio)
                        continue;
 
-               return parport_pc_superio_info[id->driver_data].probe
-                       (pdev, autoirq, autodma);
+               if (parport_pc_superio_info[id->driver_data].probe
+                       (pdev, autoirq, autodma)) {
+                       ret++;
+               }
        }
 
-       return 0; /* zero devices found */
+       return ret; /* number of devices found */
 }
 #else
 static struct pci_driver parport_pc_pci_driver;
index 7509a993f8e7c920af99ea6812d85943628a1cde..4a3172950469dde550cc8d1899160665c68c74c4 100644 (file)
@@ -296,7 +296,16 @@ static int __devinit parport_serial_pci_probe (struct pci_dev *dev,
                return err;
        }
 
-       if (serial_register (dev, id) + parport_register (dev, id)) {
+       if (parport_register (dev, id)) {
+               pci_set_drvdata (dev, NULL);
+               kfree (priv);
+               return -ENODEV;
+       }
+
+       if (serial_register (dev, id)) {
+               int i;
+               for (i = 0; i < priv->num_par; i++)
+                       parport_pc_unregister_port (priv->port[i]);
                pci_set_drvdata (dev, NULL);
                kfree (priv);
                return -ENODEV;
index 4aff48a3c3f5d759fa50a195968982eaeeae715d..b1f338e0aea579ddc91e9c2a30fed590a477d839 100644 (file)
        0620  620 Host
        0630  630 Host
        0730  730 Host
+       0735  735 Host
        0900  SiS900 10/100 Ethernet
                1039 0900  SiS900 10/100 Ethernet Adapter
        3602  83C602
                1569 6326  SiS6326 GUI Accelerator
        7001  7001
        7007  OHCI Compliant FireWire Controller
+       7012  SiS7012 PCI Audio Accelerator
        7016  SiS7016 10/100 Ethernet Adapter
                1039 7016  SiS7016 10/100 Ethernet Adapter
        7018  SiS PCI Audio Accelerator
 103a  Seiko Epson Corporation
 103b  Tatung Co. of America
 103c  Hewlett-Packard Company
+       1005  A4977A Visualize EG
        1030  J2585A
        1031  J2585B
                103c 1040  J2973A DeskDirect 10BaseT NIC
        0505  VT82C505
        0561  VT82C561
        0571  Bus Master IDE
-       0576  VT82C576 3V [Apollo Master]
+       0576  VT82C576 [Apollo Master]
        0585  VT82C585VP [Apollo VP1/VPX]
        0586  VT82C586/A/B PCI-to-ISA [Apollo VP]
                1106 0000  MVP3 ISA Bridge
        0926  VT82C926 [Amazon]
        1000  VT82C570MV
        1106  VT82C570MV
-       1571  VT82C416MV
+       1571  VT82C576 IDE [Apollo Master]
        1595  VT82C595/97 [Apollo VP2/97]
        3038  UHCI USB
                1234 0925  MVP3 USB Controller
        3074  VT8233 PCI to ISA Bridge
        3091  VT8633 [Apollo Pro266]
        3099  VT8367 [KT266]
+       3109  VT8233C PCI to ISA Bridge
        5030  VT82C596 ACPI [Apollo PRO]
        6100  VT85C100A [Rhine II]
        8231  VT8231 [PCI-to-ISA Bridge]
 11d2  Intercom Inc.
 11d3  Trancell Systems Inc
 11d4  Analog Devices
+       1889  AD1889 sound chip
 11d5  Ikon Corporation
        0115  10115
        0117  10117
index 1da6748ad47053a413469396f9fb89febf8abe5a..5e9804c83cc077ccd31f12bfd77fd94a5a12ff22 100644 (file)
@@ -449,7 +449,7 @@ tubmakemin(int irq, s390_dev_info_t *dp)
                        
                        tub3270_con_devno = dp->devno;
                        tubp->cmd = TBC_CONOPEN;
-                       tubp->flags |= TUB_OPEN_STET;
+                       tubp->flags |= TUB_OPEN_STET | TUB_INPUT_HACK;
                        tty3270_size(tubp, &flags);
                        tty3270_aid_init(tubp);
                        tty3270_scl_init(tubp);
index ec0df1343eeb980c37992a206aaaafb452cdc525..823e1c38377af2a172f70cf303cab98b5448abdb 100644 (file)
@@ -42,11 +42,11 @@ void fs3270_devfs_register(tub_t *tubp)
 {
        char name[16];
 
-       sprintf(name, "tub%x", tubp->devno);
+       sprintf(name, "tub%.3x", tubp->devno);
        devfs_register(fs3270_devfs_dir, name, DEVFS_FL_DEFAULT,
                       IBM_FS3270_MAJOR, tubp->minor,
                       S_IFCHR | S_IRUSR | S_IWUSR, &fs3270_fops, NULL);
-       sprintf(name, "tty%x", tubp->devno);
+       sprintf(name, "tty%.3x", tubp->devno);
        tty_register_devfs_name(&tty3270_driver, 0, tubp->minor,
                                fs3270_devfs_dir, name);
 }
@@ -56,12 +56,12 @@ void fs3270_devfs_unregister(tub_t *tubp)
        char name[16];
        devfs_handle_t handle;
 
-       sprintf(name, "tub%x", tubp->devno);
+       sprintf(name, "tub%.3x", tubp->devno);
        handle = devfs_find_handle (fs3270_devfs_dir, name,
                                    IBM_FS3270_MAJOR, tubp->minor,
                                    DEVFS_SPECIAL_CHR, 0);
        devfs_unregister (handle);
-       sprintf(name, "tty%x", tubp->devno);
+       sprintf(name, "tty%.3x", tubp->devno);
        handle = devfs_find_handle (fs3270_devfs_dir, name,
                                    IBM_TTY3270_MAJOR, tubp->minor,
                                    DEVFS_SPECIAL_CHR, 0);
@@ -88,7 +88,7 @@ fs3270_init(void)
        fs3270_devfs_tub = 
                devfs_register(fs3270_devfs_dir, "tub", DEVFS_FL_DEFAULT,
                               IBM_FS3270_MAJOR, 0,
-                              S_IFCHR | S_IRUSR | S_IWUSR
+                              S_IFCHR | S_IRUGO | S_IWUGO
                               &fs3270_fops, NULL);
 #else
        rc = register_chrdev(IBM_FS3270_MAJOR, "fs3270", &fs3270_fops);
index 806b42bcfaecd7f1c3c577e0cb2119ac1c0caff2..ff47efdf4bee2ee16293d5c846de717750062c53 100644 (file)
@@ -282,6 +282,7 @@ typedef struct tub_s {
 #define        TUB_UNSOL_DE    0x0200
 #define        TUB_OPEN_STET   0x0400          /* No screen clear on open */
 #define        TUB_UE_BUSY     0x0800
+#define        TUB_INPUT_HACK  0x1000          /* Early init of command line */
 
 #ifdef CONFIG_TN3270_CONSOLE
 /*
@@ -372,7 +373,7 @@ extern inline tub_t *INODE2TUB(struct inode *ip)
                if (MAJOR(current->tty->device) == IBM_TTY3270_MAJOR)
                        minor = MINOR(current->tty->device);
        }
-       if (minor >= tubnummins && minor > 0)
+       if (minor <= tubnummins && minor > 0)
                tubp = (*tubminors)[minor];
        return tubp;
 }
index 262c6f5277ce8ff939d1a632e93c13d01b9b8bf9..b5ff8ae603f2759ec195c7f3c73766e85d4153e0 100644 (file)
@@ -993,7 +993,7 @@ tty3270_show_tube(int minor, char *buf, int count)
        if (tty)
                len += sprintf(buf+len,
                                "    write_wait=%.8x read_wait=%.8x\n",
-                               tty->write_wait, tty->read_wait);
+                               (int)&tty->write_wait, (int)&tty->read_wait);
 
        if (tty && ((mp = tty->termios)))
                len += sprintf(buf+len,"    iflag=%.8x oflag=%.8x "
index 83abeab5b7c62fd34c407c84cf3039b1f9c78658..9447b3dd4020cbbeacfc5a5e1d0bfcb024a70522 100644 (file)
@@ -34,6 +34,8 @@ tty3270_clear_log_area(tub_t *tubp, char **cpp)
        TUB_BUFADR(GEOM_INPUT, cpp);
        *(*cpp)++ = '\0';
        tubp->tty_oucol = tubp->tty_nextlogx = 0;
+       *(*cpp)++ = TO_SBA;
+       TUB_BUFADR(tubp->tty_nextlogx, cpp);
 }
 
 static void
@@ -376,12 +378,16 @@ tty3270_build(tub_t *tubp)
                printk(KERN_WARNING "tty3270_build unknown command %d\n", tubp->cmd);
                return 0;
        case TBC_OPEN:
+tbc_open:
+               tubp->flags &= ~TUB_INPUT_HACK;
                chancmd = TC_EWRITEA;
                tty3270_clear_input_area(tubp, &cp);
                tty3270_set_status_area(tubp, &cp);
                tty3270_clear_log_area(tubp, &cp);
                break;
        case TBC_UPDLOG:
+               if (tubp->flags & TUB_INPUT_HACK)
+                       goto tbc_open;
                chancmd = TC_WRITE;
                writecc = TW_NONE;
                tty3270_update_log_area(tubp, &cp);
index d748be4e4fb17a7c740f00c6e3a0133bc3e86cff..1f116d052ebaa24c2fe08e74c1c662ca8c927578 100644 (file)
    1.02.00.007 - Fix possible null pointer dereferences in tw_ioctl().
                  Remove check for invalid done function pointer from
                  tw_scsi_queue().
+   1.02.00.008 - Set max sectors per io to TW_MAX_SECTORS in tw_findcards().
+                 Add tw_decode_error() for printing readable error messages.
+                 Print some useful information on certain aen codes.
+                 Add tw_decode_bits() for interpreting status register output.
+                 Make scsi_set_pci_device() for kernels >= 2.4.4
+                 Fix bug where aen's could be lost before a reset.
+                 Re-add spinlocks in tw_scsi_detect().
+                 Fix possible null pointer dereference in tw_aen_drain_queue()
+                 during initialization.
+                 Clear pci parity errors during initialization and during io.
 */
 
 #include <linux/module.h>
@@ -135,7 +145,7 @@ static struct notifier_block tw_notifier = {
 };
 
 /* Globals */
-char *tw_driver_version="1.02.00.007";
+char *tw_driver_version="1.02.00.008";
 TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
 int tw_device_extension_count = 0;
 
@@ -147,6 +157,7 @@ int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id)
        TW_Param *param;
        unsigned short aen;
 
+       dprintk(KERN_WARNING "3w-xxxx: tw_aen_complete()\n");
        if (tw_dev->alignment_virtual_address[request_id] == NULL) {
                printk(KERN_WARNING "3w-xxxx: tw_aen_complete(): Bad alignment virtual address.\n");
                return 1;
@@ -154,6 +165,27 @@ int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id)
        param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
        aen = *(unsigned short *)(param->data);
        dprintk(KERN_NOTICE "3w-xxxx: tw_aen_complete(): Queue'd code 0x%x\n", aen);
+
+       /* Print some useful info when certain aen codes come out */
+       switch (aen & 0x0ff) {
+               case TW_AEN_APORT_TIMEOUT:
+                       printk(KERN_WARNING "3w-xxxx: scsi%d: Received drive timeout AEN on port %d, check drive and drive cables.\n", tw_dev->host->host_no,  aen >> 8);
+                       break;
+               case TW_AEN_DRIVE_ERROR:
+                       printk(KERN_WARNING "3w-xxxx: scsi%d: Received drive error AEN on port %d, check/replace cabling, or possible bad drive.\n", tw_dev->host->host_no, aen >> 8);
+                       break;
+               case TW_AEN_SMART_FAIL:
+                       printk(KERN_WARNING "3w-xxxx: scsi%d: Received S.M.A.R.T. threshold AEN on port %d, check drive/cooling, or possible bad drive.\n", tw_dev->host->host_no, aen >> 8);
+                       break;
+               case TW_AEN_SBUF_FAIL:
+                       printk(KERN_WARNING "3w-xxxx: scsi%d: Received SBUF integrity check failure AEN, reseat card or bad card.\n", tw_dev->host->host_no);
+                       break;
+               default:
+                       printk(KERN_WARNING "3w-xxxx: Received AEN 0x%x\n", aen);
+       }
+
+       tw_dev->aen_count++;
+
        /* Now queue the code */
        tw_dev->aen_queue[tw_dev->aen_tail] = aen;
        if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
@@ -201,7 +233,7 @@ int tw_aen_drain_queue(TW_Device_Extension *tw_dev)
        response_que_addr = tw_dev->registers.response_que_addr;
 
        if (tw_poll_status(tw_dev, TW_STATUS_ATTENTION_INTERRUPT, 15)) {
-               printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): No attention interrupt for card %d\n", tw_dev->host->host_no);
+               printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): No attention interrupt for card %d.\n", tw_device_extension_count);
                return 1;
        }
 
@@ -258,6 +290,7 @@ int tw_aen_drain_queue(TW_Device_Extension *tw_dev)
                        status_reg_value = inl(status_reg_addr);
                        if (tw_check_bits(status_reg_value)) {
                                printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unexpected bits.\n");
+                               tw_decode_bits(tw_dev, status_reg_value);
                                return 1;
                        }
                        if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
@@ -322,6 +355,22 @@ int tw_aen_drain_queue(TW_Device_Extension *tw_dev)
                                                dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_QUEUE_FULL.\n");
                                                queue = 1;
                                                break;
+                                       case TW_AEN_APORT_TIMEOUT:
+                                               printk(KERN_WARNING "3w-xxxx: Received drive timeout AEN on port %d, check drive and drive cables.\n", aen >> 8);
+                                               queue = 1;
+                                               break;
+                                       case TW_AEN_DRIVE_ERROR:
+                                               printk(KERN_WARNING "3w-xxxx: Received drive error AEN on port %d, check/replace cabling, or possible bad drive.\n", aen >> 8);
+                                               queue = 1;
+                                               break;
+                                       case TW_AEN_SMART_FAIL:
+                                               printk(KERN_WARNING "3w-xxxx: Received S.M.A.R.T. threshold AEN on port %d, check drive/cooling, or possible bad drive.\n", aen >> 8);
+                                               queue = 1;
+                                               break;
+                                       case TW_AEN_SBUF_FAIL:
+                                               printk(KERN_WARNING "3w-xxxx: Received SBUF integrity check failure AEN, reseat card or bad card.\n");
+                                               queue = 1;
+                                               break;
                                        default:
                                                dprintk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unknown AEN code 0x%x.\n", aen_code);
                                                queue = 1;
@@ -378,6 +427,7 @@ int tw_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
        status_reg_value = inl(status_reg_addr);
        if (tw_check_bits(status_reg_value)) {
                printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Unexpected bits.\n");
+               tw_decode_bits(tw_dev, status_reg_value);
                return 1;
        }
        if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
@@ -552,6 +602,40 @@ static void tw_copy_mem_info(TW_Info *info, char *data, int len)
        }
 } /* End tw_copy_mem_info() */
 
+/* This function will print readable messages from statsu register errors */
+void tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value)
+{
+       dprintk(KERN_WARNING "3w-xxxx: tw_decode_bits()\n");
+       switch (status_reg_value & TW_STATUS_UNEXPECTED_BITS) {
+       case TW_STATUS_PCI_PARITY_ERROR:
+               printk(KERN_WARNING "3w-xxxx: PCI Parity Error: Reseat card, move card, or buggy device on the bus.\n");
+               outl(TW_CONTROL_CLEAR_PARITY_ERROR, tw_dev->registers.control_reg_addr);
+               pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PARITY_ERRORS);
+               break;
+       case TW_STATUS_MICROCONTROLLER_ERROR:
+               printk(KERN_WARNING "3w-xxxx: Microcontroller Error.\n");
+               break;
+  }
+} /* End tw_decode_bits() */
+
+/* This function will print readable messages from flags and status values */
+void tw_decode_error(TW_Device_Extension *tw_dev, unsigned char status, unsigned char flags, unsigned char unit)
+{
+       dprintk(KERN_WARNING "3w-xxxx: tw_decode_error()\n");
+       switch (status) {
+       case 0xc7:
+               switch (flags) {
+               case 0x1b: 
+                       printk(KERN_WARNING "3w-xxxx: scsi%d: Drive timeout on unit %d, check drive and drive cables.\n", tw_dev->host->host_no, unit);
+                       break;
+               case 0x51:
+                       printk(KERN_WARNING "3w-xxxx: scsi%d: Unrecoverable drive error on unit %d, check/replace cabling, or possible bad drive.\n", tw_dev->host->host_no, unit);
+                       break;
+               }
+               break;
+       }
+} /* End tw_decode_error() */
+
 /* This function will disable interrupts on the controller */  
 void tw_disable_interrupts(TW_Device_Extension *tw_dev) 
 {
@@ -575,6 +659,7 @@ int tw_empty_response_que(TW_Device_Extension *tw_dev)
 
        if (tw_check_bits(status_reg_value)) {
                printk(KERN_WARNING "3w-xxxx: tw_empty_response_queue(): Unexpected bits 1.\n");
+               tw_decode_bits(tw_dev, status_reg_value);
                return 1;
        }
   
@@ -583,6 +668,7 @@ int tw_empty_response_que(TW_Device_Extension *tw_dev)
                status_reg_value = inl(status_reg_addr);
                if (tw_check_bits(status_reg_value)) {
                        printk(KERN_WARNING "3w-xxxx: tw_empty_response_queue(): Unexpected bits 2.\n");
+                       tw_decode_bits(tw_dev, status_reg_value);
                        return 1;
                }
        }
@@ -645,6 +731,11 @@ int tw_findcards(Scsi_Host_Template *tw_host)
                        /* Save pci_dev struct to device extension */
                        tw_dev->tw_pci_dev = tw_pci_dev;
 
+                       /* Check for errors and clear them */
+                       status_reg_value = inl(tw_dev->registers.status_reg_addr);
+                       if (TW_STATUS_ERRORS(status_reg_value)) 
+                         tw_decode_bits(tw_dev, status_reg_value);
+                       
                        /* Poll status register for 60 secs for 'Controller Ready' flag */
                        if (tw_poll_status(tw_dev, TW_STATUS_MICROCONTROLLER_READY, 60)) {
                                printk(KERN_WARNING "3w-xxxx: tw_findcards(): Microcontroller not ready for card %d.\n", numcards);
@@ -738,10 +829,18 @@ int tw_findcards(Scsi_Host_Template *tw_host)
                                continue;
                        }
 
+                       /* Set max sectors per io */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
+                       host->max_sectors = TW_MAX_SECTORS;
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
                        scsi_set_pci_device(host, tw_pci_dev);
+#endif
+
                        status_reg_value = inl(tw_dev->registers.status_reg_addr);
 
-                       dprintk(KERN_NOTICE "scsi%d : Found a 3ware Storage Controller at 0x%x, IRQ: %d P-chip: %d.%d\n", host->host_no,
+                       printk(KERN_NOTICE "scsi%d : Found a 3ware Storage Controller at 0x%x, IRQ: %d, P-chip: %d.%d\n", host->host_no,
                                (u32)(tw_pci_dev->resource[0].start), tw_pci_dev->irq, 
                                (status_reg_value & TW_STATUS_MAJOR_VERSION_MASK) >> 28, 
                                (status_reg_value & TW_STATUS_MINOR_VERSION_MASK) >> 24);
@@ -881,6 +980,7 @@ int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits)
                status_reg_value = inl(status_reg_addr);
                if (tw_check_bits(status_reg_value)) {
                        printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected bits.\n");
+                       tw_decode_bits(tw_dev, status_reg_value);
                        return 1;
                }
                if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
@@ -1034,6 +1134,7 @@ int tw_initialize_units(TW_Device_Extension *tw_dev)
                status_reg_value = inl(status_reg_addr);
                if (tw_check_bits(status_reg_value)) {
                        printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected bits.\n");
+                       tw_decode_bits(tw_dev, status_reg_value);
                        return 1;
                }
                if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
@@ -1136,6 +1237,7 @@ int tw_initialize_units(TW_Device_Extension *tw_dev)
                        status_reg_value = inl(status_reg_addr);
                        if (tw_check_bits(status_reg_value)) {
                                printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected bits.\n");
+                               tw_decode_bits(tw_dev, status_reg_value);
                                return 1;
                        }
                        if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
@@ -1143,14 +1245,12 @@ int tw_initialize_units(TW_Device_Extension *tw_dev)
                                request_id = (unsigned char)response_queue.u.response_id;
                                if (request_id != 0) {
                                        /* unexpected request id */
-                                       printk(KERN_WARNING "3w-xxxx: tw_initia
-lize_units(): Unexpected request id.\n");
+                                       printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected request id.\n");
                                        return 1;
                                }
                                if (command_packet->status != 0) {
                                        /* bad response */
-                                       printk(KERN_WARNING "3w-xxxx: tw_initia
-lize_units(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
+                                       printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
                                        return 1;
                                }
                                found = 1;
@@ -1159,8 +1259,7 @@ lize_units(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->sta
                }
                if (found == 0) {
                        /* response never received */
-                       printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): No
- response.\n");
+                       printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): No response.\n");
                        return 1;
                }
 
@@ -1177,12 +1276,12 @@ lize_units(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->sta
        /* Now allocate raid5 bounce buffers */
        if ((num_raid_five != 0) && (tw_dev->tw_pci_dev->device == TW_DEVICE_ID)) {
                for (i=0;i<TW_Q_LENGTH;i++) {
-                       tw_allocate_memory(tw_dev, i, sizeof(TW_Sector)*256, 2);
+                       tw_allocate_memory(tw_dev, i, sizeof(TW_Sector)*TW_MAX_SECTORS, 2);
                        if (tw_dev->bounce_buffer[i] == NULL) {
                                printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bounce buffer allocation failed.\n");
                                return 1;
                        }
-                       memset(tw_dev->bounce_buffer[i], 0, sizeof(TW_Sector)*256);
+                       memset(tw_dev->bounce_buffer[i], 0, sizeof(TW_Sector)*TW_MAX_SECTORS);
                }
        }
   
@@ -1282,12 +1381,17 @@ static void tw_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
                                error = 0;
                                if (command_packet->status != 0) {
                                        printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Bad response, status = 0x%x, flags = 0x%x, unit = 0x%x.\n", command_packet->status, command_packet->flags, command_packet->byte3.unit);
+                                       tw_decode_error(tw_dev, command_packet->status, command_packet->flags, command_packet->byte3.unit);
                                        error = 1;
                                }
                                if (tw_dev->state[request_id] != TW_S_POSTED) {
                                        printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Received a request id (%d) (opcode = 0x%x) that wasn't posted.\n", request_id, command_packet->byte0.opcode);
                                        error = 1;
                                }
+                               if (TW_STATUS_ERRORS(status_reg_value)) {
+                                 tw_decode_bits(tw_dev, status_reg_value);
+                                 error = 1;
+                               }
                                dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Response queue request id: %d.\n", request_id);
                                /* Check for internal command */
                                if (tw_dev->srb[request_id] == 0) {
@@ -1299,6 +1403,7 @@ static void tw_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
                                        status_reg_value = inl(status_reg_addr);
                                        if (tw_check_bits(status_reg_value)) {
                                                printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
+                                               tw_decode_bits(tw_dev, status_reg_value);
                                        }
                } else {
                                switch (tw_dev->srb[request_id]->cmnd[0]) {
@@ -1344,6 +1449,7 @@ static void tw_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
                                        status_reg_value = inl(status_reg_addr);
                                        if (tw_check_bits(status_reg_value)) {
                                                printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
+                                               tw_decode_bits(tw_dev, status_reg_value);
                                        }
                                }
                        }
@@ -1400,7 +1506,7 @@ int tw_ioctl(TW_Device_Extension *tw_dev, int request_id)
        param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
        memset(param, 0, sizeof(TW_Sector));
 
-       dprintk(KERN_NOTICE "opcode = %d table_id = %d parameter_id = %d parameter_size_bytes = %d\n", ioctl->opcode, ioctl->table_id, ioctl->parameter_id,, ioctl->parameter_size_bytes);
+       dprintk(KERN_NOTICE "opcode = %d table_id = %d parameter_id = %d parameter_size_bytes = %d\n", ioctl->opcode, ioctl->table_id, ioctl->parameter_id, ioctl->parameter_size_bytes);
        opcode = ioctl->opcode;
 
        switch (opcode) {
@@ -1571,8 +1677,10 @@ int tw_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
        status_reg_addr = tw_dev->registers.status_reg_addr;
        status_reg_value = inl(status_reg_addr);
 
-       if (tw_check_bits(status_reg_value)) 
+       if (tw_check_bits(status_reg_value)) {
                printk(KERN_WARNING "3w-xxxx: tw_post_command_packet(): Unexpected bits.\n");
+               tw_decode_bits(tw_dev, status_reg_value);
+       }
 
        if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
                /* We successfully posted the command packet */
@@ -1737,13 +1845,17 @@ int tw_scsi_detect(Scsi_Host_Template *tw_host)
        
        dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_detect()\n");
 
+       printk(KERN_WARNING "3ware Storage Controller device driver for Linux v%s.\n", tw_driver_version);
+
        /* Check if the kernel has PCI interface compiled in */
        if (!pci_present()) {
                printk(KERN_WARNING "3w-xxxx: tw_scsi_detect(): No pci interface present.\n");
                return 0;
        }
 
+       spin_unlock_irq(&io_request_lock);
        ret = tw_findcards(tw_host);
+       spin_lock_irq(&io_request_lock);
 
        return ret;
 } /* End tw_scsi_detect() */
@@ -1767,6 +1879,11 @@ int tw_scsi_eh_abort(Scsi_Cmnd *SCpnt)
                return (FAILED);
        }
 
+       /* We have to let AEN requests through before the reset */
+       spin_unlock_irq(&io_request_lock);
+       mdelay(TW_AEN_WAIT_TIME);
+       spin_lock_irq(&io_request_lock);
+
        spin_lock(&tw_dev->tw_lock);
        tw_dev->num_aborts++;
 
@@ -1827,6 +1944,11 @@ int tw_scsi_eh_reset(Scsi_Cmnd *SCpnt)
                return (FAILED);
        }
 
+       /* We have to let AEN requests through before the reset */
+       spin_unlock_irq(&io_request_lock);
+       mdelay(TW_AEN_WAIT_TIME);
+       spin_lock_irq(&io_request_lock);
+
        spin_lock(&tw_dev->tw_lock);
        tw_dev->num_resets++;
 
@@ -2446,6 +2568,7 @@ int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
                status_reg_value = inl(status_reg_addr);
                if (tw_check_bits(status_reg_value)) {
                        printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected bits.\n");
+                       tw_decode_bits(tw_dev, status_reg_value);
                        return 1;
                }
                if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
index d3fbfdf699db9eadee6701059ad5e4fe155e5dea..8b0540db105582ef72b826a5ce8d7c7e4633c695 100644 (file)
@@ -69,6 +69,7 @@
 #define TW_CONTROL_ENABLE_INTERRUPTS          0x00000080
 #define TW_CONTROL_DISABLE_INTERRUPTS         0x00000040
 #define TW_CONTROL_ISSUE_HOST_INTERRUPT               0x00000020
+#define TW_CONTROL_CLEAR_PARITY_ERROR          0x00800000
 
 /* Status register bit definitions */
 #define TW_STATUS_MAJOR_VERSION_MASK          0xF0000000
 #define TW_DEVICE_ID (0x1000)  /* Storage Controller */
 #define TW_DEVICE_ID2 (0x1001)  /* 7000 series controller */
 #define TW_NUMDEVICES 2
+#define TW_PCI_CLEAR_PARITY_ERRORS 0xc100
 
 /* Command packet opcodes */
 #define TW_OP_NOP            0x0
 #define TW_AEN_REBUILD_DONE      0x0005
 #define TW_AEN_QUEUE_FULL        0x00ff
 #define TW_AEN_TABLE_UNDEFINED   0x15
+#define TW_AEN_APORT_TIMEOUT     0x0009
+#define TW_AEN_DRIVE_ERROR       0x000A
+#define TW_AEN_SMART_FAIL        0x000F
+#define TW_AEN_SBUF_FAIL         0x0024
 
 /* Misc defines */
 #define TW_ALIGNMENT                         0x200 /* 16 D-WORDS */
 #define TW_MAX_AEN_TRIES                      100
 #define TW_UNIT_ONLINE                        1
 #define TW_IN_INTR                            1
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,7)
+#define TW_MAX_SECTORS                        256
+#else
+#define TW_MAX_SECTORS                        128
+#endif 
+#define TW_AEN_WAIT_TIME                      1000
 
 /* Macros */
 #define TW_STATUS_ERRORS(x) \
@@ -308,6 +320,8 @@ int tw_check_bits(u32 status_reg_value);
 int tw_check_errors(TW_Device_Extension *tw_dev);
 void tw_clear_attention_interrupt(TW_Device_Extension *tw_dev);
 void tw_clear_host_interrupt(TW_Device_Extension *tw_dev);
+void tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value);
+void tw_decode_error(TW_Device_Extension *tw_dev, unsigned char status, unsigned char flags, unsigned char unit);
 void tw_disable_interrupts(TW_Device_Extension *tw_dev);
 int tw_empty_response_que(TW_Device_Extension *tw_dev);
 void tw_enable_interrupts(TW_Device_Extension *tw_dev);
index 6380bd01808ef53071af92d5a0a961dce6a3d00e..a2a6a3fbe4a9896821908a41f72b67666f61c658 100644 (file)
@@ -433,7 +433,7 @@ static void aha1542_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
        void (*my_done) (Scsi_Cmnd *) = NULL;
        int errstatus, mbi, mbo, mbistatus;
        int number_serviced;
-       unsigned int flags;
+       unsigned long flags;
        struct Scsi_Host *shost;
        Scsi_Cmnd *SCtmp;
        int flag;
diff --git a/drivers/scsi/dpt/dpt_osdutil.h b/drivers/scsi/dpt/dpt_osdutil.h
new file mode 100644 (file)
index 0000000..4b56c04
--- /dev/null
@@ -0,0 +1,358 @@
+/*     BSDI osd_util.h,v 1.8 1998/06/03 19:14:58 karels Exp    */
+
+/*
+ * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source form, with or without modification, are
+ * permitted provided that redistributions of source code must retain the
+ * above copyright notice, this list of conditions and the following disclaimer.
+ *
+ * This software is provided `as is' by Distributed Processing Technology and
+ * any express or implied warranties, including, but not limited to, the
+ * implied warranties of merchantability and fitness for a particular purpose,
+ * are disclaimed. In no event shall Distributed Processing Technology be
+ * liable for any direct, indirect, incidental, special, exemplary or
+ * consequential damages (including, but not limited to, procurement of
+ * substitute goods or services; loss of use, data, or profits; or business
+ * interruptions) however caused and on any theory of liability, whether in
+ * contract, strict liability, or tort (including negligence or otherwise)
+ * arising in any way out of the use of this driver software, even if advised
+ * of the possibility of such damage.
+ *
+ */
+
+#ifndef         __OSD_UTIL_H
+#define         __OSD_UTIL_H
+
+/*File - OSD_UTIL.H
+ ****************************************************************************
+ *
+ *Description:
+ *
+ *      This file contains defines and function prototypes that are
+ *operating system dependent.  The resources defined in this file
+ *are not specific to any particular application.
+ *
+ *Copyright Distributed Processing Technology, Corp.
+ *        140 Candace Dr.
+ *        Maitland, Fl. 32751   USA
+ *        Phone: (407) 830-5522  Fax: (407) 260-5366
+ *        All Rights Reserved
+ *
+ *Author:       Doug Anderson
+ *Date:         1/7/94
+ *
+ *Editors:
+ *
+ *Remarks:
+ *
+ *
+ *****************************************************************************/
+
+
+/*Definitions - Defines & Constants ----------------------------------------- */
+
+/*----------------------------- */
+/* Operating system selections: */
+/*----------------------------- */
+
+/*#define               _DPT_MSDOS      */
+/*#define               _DPT_WIN_3X     */
+/*#define               _DPT_WIN_4X     */
+/*#define               _DPT_WIN_NT     */
+/*#define               _DPT_NETWARE    */
+/*#define               _DPT_OS2        */
+/*#define               _DPT_SCO        */
+/*#define               _DPT_UNIXWARE   */
+/*#define               _DPT_SOLARIS    */
+/*#define               _DPT_NEXTSTEP   */
+/*#define               _DPT_BANYAN     */
+
+/*-------------------------------- */
+/* Include the OS specific defines */
+/*-------------------------------- */
+
+/*#define       OS_SELECTION    From Above List */
+/*#define       SEMAPHORE_T     ??? */
+/*#define       DLL_HANDLE_T    ??? */
+
+#if (defined(KERNEL) && (defined(__FreeBSD__) || defined(__bsdi__)))
+# include        "i386/isa/dpt_osd_defs.h"
+#else
+# include        "osd_defs.h"
+#endif
+
+#ifndef DPT_UNALIGNED
+   #define      DPT_UNALIGNED
+#endif
+
+#ifndef DPT_EXPORT
+   #define      DPT_EXPORT
+#endif
+
+#ifndef DPT_IMPORT
+   #define      DPT_IMPORT
+#endif
+
+#ifndef DPT_RUNTIME_IMPORT
+   #define      DPT_RUNTIME_IMPORT  DPT_IMPORT
+#endif
+
+/*--------------------- */
+/* OS dependent defines */
+/*--------------------- */
+
+#if defined (_DPT_MSDOS) || defined (_DPT_WIN_3X)
+   #define      _DPT_16_BIT
+#else
+   #define      _DPT_32_BIT
+#endif
+
+#if defined (_DPT_SCO) || defined (_DPT_UNIXWARE) || defined (_DPT_SOLARIS) || defined (_DPT_AIX) || defined (SNI_MIPS) || defined (_DPT_BSDI) || defined (_DPT_FREE_BSD) || defined(_DPT_LINUX)
+   #define      _DPT_UNIX
+#endif
+
+#if defined (_DPT_WIN_3x) || defined (_DPT_WIN_4X) || defined (_DPT_WIN_NT) \
+           || defined (_DPT_OS2)
+   #define      _DPT_DLL_SUPPORT
+#endif
+
+#if !defined (_DPT_MSDOS) && !defined (_DPT_WIN_3X) && !defined (_DPT_NETWARE)
+   #define      _DPT_PREEMPTIVE
+#endif
+
+#if !defined (_DPT_MSDOS) && !defined (_DPT_WIN_3X)
+   #define      _DPT_MULTI_THREADED
+#endif
+
+#if !defined (_DPT_MSDOS)
+   #define      _DPT_MULTI_TASKING
+#endif
+
+  /* These exist for platforms that   */
+  /* chunk when accessing mis-aligned */
+  /* data                             */
+#if defined (SNI_MIPS) || defined (_DPT_SOLARIS)
+   #if defined (_DPT_BIG_ENDIAN)
+       #if !defined (_DPT_STRICT_ALIGN)
+            #define _DPT_STRICT_ALIGN
+       #endif
+   #endif
+#endif
+
+  /* Determine if in C or C++ mode */
+#ifdef  __cplusplus
+   #define      _DPT_CPP
+#else
+   #define      _DPT_C
+#endif
+
+/*-------------------------------------------------------------------*/
+/* Under Solaris the compiler refuses to accept code like:           */
+/*   { {"DPT"}, 0, NULL .... },                                      */
+/* and complains about the {"DPT"} part by saying "cannot use { }    */
+/* to initialize char*".                                             */
+/*                                                                   */
+/* By defining these ugly macros we can get around this and also     */
+/* not have to copy and #ifdef large sections of code.  I know that  */
+/* these macros are *really* ugly, but they should help reduce       */
+/* maintenance in the long run.                                      */
+/*                                                                   */
+/*-------------------------------------------------------------------*/
+#if !defined (DPTSQO)
+   #if defined (_DPT_SOLARIS)
+      #define DPTSQO
+      #define DPTSQC
+   #else
+      #define DPTSQO {
+      #define DPTSQC }
+   #endif  /* solaris */
+#endif  /* DPTSQO */
+
+
+/*---------------------- */
+/* OS dependent typedefs */
+/*---------------------- */
+
+#if defined (_DPT_MSDOS) || defined (_DPT_SCO)
+   #define BYTE unsigned char
+   #define WORD unsigned short
+#endif
+
+#ifndef _DPT_TYPEDEFS
+   #define _DPT_TYPEDEFS
+   typedef unsigned char   uCHAR;
+   typedef unsigned short  uSHORT;
+   typedef unsigned int    uINT;
+   typedef unsigned long   uLONG;
+
+   typedef union {
+        uCHAR        u8[4];
+        uSHORT       u16[2];
+        uLONG        u32;
+   } access_U;
+#endif
+
+#if !defined (NULL)
+   #define      NULL    0
+#endif
+
+
+/*Prototypes - function ----------------------------------------------------- */
+
+#ifdef  __cplusplus
+   extern "C" {         /* Declare all these functions as "C" functions */
+#endif
+
+/*------------------------ */
+/* Byte reversal functions */
+/*------------------------ */
+
+  /* Reverses the byte ordering of a 2 byte variable */
+#if (!defined(osdSwap2))
+ uSHORT       osdSwap2(DPT_UNALIGNED uSHORT *);
+#endif  // !osdSwap2
+
+  /* Reverses the byte ordering of a 4 byte variable and shifts left 8 bits */
+#if (!defined(osdSwap3))
+ uLONG        osdSwap3(DPT_UNALIGNED uLONG *);
+#endif  // !osdSwap3
+
+
+#ifdef  _DPT_NETWARE
+   #include "novpass.h" /* For DPT_Bswapl() prototype */
+       /* Inline the byte swap */
+   #ifdef __cplusplus
+        inline uLONG osdSwap4(uLONG *inLong) {
+        return *inLong = DPT_Bswapl(*inLong);
+        }
+   #else
+        #define osdSwap4(inLong)       DPT_Bswapl(inLong)
+   #endif  // cplusplus
+#else
+       /* Reverses the byte ordering of a 4 byte variable */
+# if (!defined(osdSwap4))
+   uLONG        osdSwap4(DPT_UNALIGNED uLONG *);
+# endif  // !osdSwap4
+
+  /* The following functions ALWAYS swap regardless of the *
+   * presence of DPT_BIG_ENDIAN                            */
+
+   uSHORT       trueSwap2(DPT_UNALIGNED uSHORT *);
+   uLONG        trueSwap4(DPT_UNALIGNED uLONG *);
+
+#endif  // netware
+
+
+/*-------------------------------------*
+ * Network order swap functions        *
+ *                                     *
+ * These functions/macros will be used *
+ * by the structure insert()/extract() *
+ * functions.                          *
+ *
+ * We will enclose all structure       *
+ * portability modifications inside    *
+ * #ifdefs.  When we are ready, we     *
+ * will #define DPT_PORTABLE to begin  *
+ * using the modifications.            *
+ *-------------------------------------*/
+uLONG  netSwap4(uLONG val);
+
+#if defined (_DPT_BIG_ENDIAN)
+
+// for big-endian we need to swap
+
+#ifndef NET_SWAP_2
+#define NET_SWAP_2(x) (((x) >> 8) | ((x) << 8))
+#endif  // NET_SWAP_2
+
+#ifndef NET_SWAP_4
+#define NET_SWAP_4(x) netSwap4((x))
+#endif  // NET_SWAP_4
+
+#else
+
+// for little-endian we don't need to do anything
+
+#ifndef NET_SWAP_2
+#define NET_SWAP_2(x) (x)
+#endif  // NET_SWAP_2
+
+#ifndef NET_SWAP_4
+#define NET_SWAP_4(x) (x)
+#endif  // NET_SWAP_4
+
+#endif  // big endian
+
+
+
+/*----------------------------------- */
+/* Run-time loadable module functions */
+/*----------------------------------- */
+
+  /* Loads the specified run-time loadable DLL */
+DLL_HANDLE_T    osdLoadModule(uCHAR *);
+  /* Unloads the specified run-time loadable DLL */
+uSHORT          osdUnloadModule(DLL_HANDLE_T);
+  /* Returns a pointer to a function inside a run-time loadable DLL */
+void *          osdGetFnAddr(DLL_HANDLE_T,uCHAR *);
+
+/*--------------------------------------- */
+/* Mutually exclusive semaphore functions */
+/*--------------------------------------- */
+
+  /* Create a named semaphore */
+SEMAPHORE_T     osdCreateNamedSemaphore(char *);
+  /* Create a mutually exlusive semaphore */
+SEMAPHORE_T     osdCreateSemaphore(void);
+       /* create an event semaphore */
+SEMAPHORE_T              osdCreateEventSemaphore(void);
+       /* create a named event semaphore */
+SEMAPHORE_T             osdCreateNamedEventSemaphore(char *);
+
+  /* Destroy the specified mutually exclusive semaphore object */
+uSHORT          osdDestroySemaphore(SEMAPHORE_T);
+  /* Request access to the specified mutually exclusive semaphore */
+uLONG           osdRequestSemaphore(SEMAPHORE_T,uLONG);
+  /* Release access to the specified mutually exclusive semaphore */
+uSHORT          osdReleaseSemaphore(SEMAPHORE_T);
+       /* wait for a event to happen */
+uLONG                            osdWaitForEventSemaphore(SEMAPHORE_T, uLONG);
+       /* signal an event */
+uLONG                            osdSignalEventSemaphore(SEMAPHORE_T);
+       /* reset the event */
+uLONG                            osdResetEventSemaphore(SEMAPHORE_T);
+
+/*----------------- */
+/* Thread functions */
+/*----------------- */
+
+  /* Releases control to the task switcher in non-preemptive */
+  /* multitasking operating systems. */
+void            osdSwitchThreads(void);
+
+  /* Starts a thread function */
+uLONG   osdStartThread(void *,void *);
+
+/* what is my thread id */
+uLONG osdGetThreadID(void);
+
+/* wakes up the specifed thread */
+void osdWakeThread(uLONG);
+
+/* osd sleep for x miliseconds */
+void osdSleep(uLONG);
+
+#define DPT_THREAD_PRIORITY_LOWEST 0x00
+#define DPT_THREAD_PRIORITY_NORMAL 0x01
+#define DPT_THREAD_PRIORITY_HIGHEST 0x02
+
+uCHAR osdSetThreadPriority(uLONG tid, uCHAR priority);
+
+#ifdef __cplusplus
+   }    /* end the xtern "C" declaration */
+#endif
+
+#endif  /* osd_util_h */
diff --git a/drivers/scsi/dpt/dpti_i2o.h b/drivers/scsi/dpt/dpti_i2o.h
new file mode 100644 (file)
index 0000000..96ca4f6
--- /dev/null
@@ -0,0 +1,464 @@
+#ifndef _SCSI_I2O_H
+#define _SCSI_I2O_H
+
+/* I2O kernel space accessible structures/APIs
+ *
+ * (c) Copyright 1999, 2000 Red Hat Software
+ *
+ * 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 header file defined the I2O APIs/structures for use by
+ * the I2O kernel modules.
+ *
+ */
+
+#ifdef __KERNEL__       /* This file to be included by kernel only */
+
+#include <linux/i2o-dev.h>
+
+#include <asm/semaphore.h> /* Needed for MUTEX init macros */
+#include <linux/config.h>
+#include <linux/notifier.h>
+#include <asm/atomic.h>
+
+
+/*
+ *     Tunable parameters first
+ */
+
+/* How many different OSM's are we allowing */ 
+#define MAX_I2O_MODULES                64
+
+#define I2O_EVT_CAPABILITY_OTHER               0x01
+#define I2O_EVT_CAPABILITY_CHANGED             0x02
+
+#define I2O_EVT_SENSOR_STATE_CHANGED           0x01
+
+//#ifdef __KERNEL__   /* ioctl stuff only thing exported to users */
+
+#define I2O_MAX_MANAGERS       4
+
+#include <asm/semaphore.h> /* Needed for MUTEX init macros */
+
+/*
+ *     I2O Interface Objects
+ */
+
+#include <linux/config.h>
+#include <linux/notifier.h>
+#include <asm/atomic.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
+
+#define DECLARE_MUTEX(name) struct semaphore name=MUTEX
+
+typedef struct wait_queue *adpt_wait_queue_head_t;
+#define ADPT_DECLARE_WAIT_QUEUE_HEAD(wait) adpt_wait_queue_head_t wait = NULL
+typedef struct wait_queue adpt_wait_queue_t;
+#else
+
+#include <linux/wait.h>
+typedef wait_queue_head_t adpt_wait_queue_head_t;
+#define ADPT_DECLARE_WAIT_QUEUE_HEAD(wait) DECLARE_WAIT_QUEUE_HEAD(wait)
+typedef wait_queue_t adpt_wait_queue_t;
+
+#endif
+/*
+ * message structures
+ */
+
+struct i2o_message
+{
+       u8      version_offset;
+       u8      flags;
+       u16     size;
+       u32     target_tid:12;
+       u32     init_tid:12;
+       u32     function:8;     
+       u32     initiator_context;
+       /* List follows */
+};
+
+struct adpt_device;
+struct _adpt_hba;
+struct i2o_device
+{
+       struct i2o_device *next;        /* Chain */
+       struct i2o_device *prev;
+
+       char dev_name[8];               /* linux /dev name if available */
+       i2o_lct_entry lct_data;/* Device LCT information */
+       u32 flags;              
+       struct proc_dir_entry* proc_entry;      /* /proc dir */
+       struct adpt_device *owner;
+       struct _adpt_hba *controller;   /* Controlling IOP */
+};
+
+/*
+ *     Each I2O controller has one of these objects
+ */
+struct i2o_controller
+{
+       char name[16];
+       int unit;
+       int type;
+       int enabled;
+
+       struct notifier_block *event_notifer;   /* Events */
+       atomic_t users;
+       struct i2o_device *devices;             /* I2O device chain */
+       struct i2o_controller *next;            /* Controller chain */
+
+};
+
+/*
+ * I2O System table entry
+ */
+struct i2o_sys_tbl_entry
+{
+       u16     org_id;
+       u16     reserved1;
+       u32     iop_id:12;
+       u32     reserved2:20;
+       u16     seg_num:12;
+       u16     i2o_version:4;
+       u8      iop_state;
+       u8      msg_type;
+       u16     frame_size;
+       u16     reserved3;
+       u32     last_changed;
+       u32     iop_capabilities;
+       u32     inbound_low;
+       u32     inbound_high;
+};
+
+struct i2o_sys_tbl
+{
+       u8      num_entries;
+       u8      version;
+       u16     reserved1;
+       u32     change_ind;
+       u32     reserved2;
+       u32     reserved3;
+       struct i2o_sys_tbl_entry iops[0];
+};     
+
+/*
+ *     I2O classes / subclasses
+ */
+
+/*  Class ID and Code Assignments
+ *  (LCT.ClassID.Version field)
+ */
+#define    I2O_CLASS_VERSION_10                        0x00
+#define    I2O_CLASS_VERSION_11                        0x01
+
+/*  Class code names
+ *  (from v1.5 Table 6-1 Class Code Assignments.)
+ */
+#define    I2O_CLASS_EXECUTIVE                         0x000
+#define    I2O_CLASS_DDM                               0x001
+#define    I2O_CLASS_RANDOM_BLOCK_STORAGE              0x010
+#define    I2O_CLASS_SEQUENTIAL_STORAGE                0x011
+#define    I2O_CLASS_LAN                               0x020
+#define    I2O_CLASS_WAN                               0x030
+#define    I2O_CLASS_FIBRE_CHANNEL_PORT                0x040
+#define    I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL          0x041
+#define    I2O_CLASS_SCSI_PERIPHERAL                   0x051
+#define    I2O_CLASS_ATE_PORT                          0x060
+#define    I2O_CLASS_ATE_PERIPHERAL                    0x061
+#define    I2O_CLASS_FLOPPY_CONTROLLER                 0x070
+#define    I2O_CLASS_FLOPPY_DEVICE                     0x071
+#define    I2O_CLASS_BUS_ADAPTER_PORT                  0x080
+#define    I2O_CLASS_PEER_TRANSPORT_AGENT              0x090
+#define    I2O_CLASS_PEER_TRANSPORT                    0x091
+
+/*  Rest of 0x092 - 0x09f reserved for peer-to-peer classes
+ */
+#define    I2O_CLASS_MATCH_ANYCLASS                    0xffffffff
+
+/*  Subclasses
+ */
+
+#define    I2O_SUBCLASS_i960                           0x001
+#define    I2O_SUBCLASS_HDM                            0x020
+#define    I2O_SUBCLASS_ISM                            0x021
+/* Operation functions */
+
+#define I2O_PARAMS_FIELD_GET   0x0001
+#define I2O_PARAMS_LIST_GET    0x0002
+#define I2O_PARAMS_MORE_GET    0x0003
+#define I2O_PARAMS_SIZE_GET    0x0004
+#define I2O_PARAMS_TABLE_GET   0x0005
+#define I2O_PARAMS_FIELD_SET   0x0006
+#define I2O_PARAMS_LIST_SET    0x0007
+#define I2O_PARAMS_ROW_ADD     0x0008
+#define I2O_PARAMS_ROW_DELETE  0x0009
+#define I2O_PARAMS_TABLE_CLEAR 0x000A
+
+/*
+ *     I2O serial number conventions / formats
+ *     (circa v1.5)
+ */
+
+#define    I2O_SNFORMAT_UNKNOWN                        0
+#define    I2O_SNFORMAT_BINARY                         1
+#define    I2O_SNFORMAT_ASCII                          2
+#define    I2O_SNFORMAT_UNICODE                        3
+#define    I2O_SNFORMAT_LAN48_MAC                      4
+#define    I2O_SNFORMAT_WAN                            5
+
+/* Plus new in v2.0 (Yellowstone pdf doc)
+ */
+
+#define    I2O_SNFORMAT_LAN64_MAC                      6
+#define    I2O_SNFORMAT_DDM                            7
+#define    I2O_SNFORMAT_IEEE_REG64                     8
+#define    I2O_SNFORMAT_IEEE_REG128                    9
+#define    I2O_SNFORMAT_UNKNOWN2                       0xff
+
+/* Transaction Reply Lists (TRL) Control Word structure */
+
+#define TRL_SINGLE_FIXED_LENGTH                0x00
+#define TRL_SINGLE_VARIABLE_LENGTH     0x40
+#define TRL_MULTIPLE_FIXED_LENGTH      0x80
+
+/*
+ *     Messaging API values
+ */
+#define        I2O_CMD_ADAPTER_ASSIGN          0xB3
+#define        I2O_CMD_ADAPTER_READ            0xB2
+#define        I2O_CMD_ADAPTER_RELEASE         0xB5
+#define        I2O_CMD_BIOS_INFO_SET           0xA5
+#define        I2O_CMD_BOOT_DEVICE_SET         0xA7
+#define        I2O_CMD_CONFIG_VALIDATE         0xBB
+#define        I2O_CMD_CONN_SETUP              0xCA
+#define        I2O_CMD_DDM_DESTROY             0xB1
+#define        I2O_CMD_DDM_ENABLE              0xD5
+#define        I2O_CMD_DDM_QUIESCE             0xC7
+#define        I2O_CMD_DDM_RESET               0xD9
+#define        I2O_CMD_DDM_SUSPEND             0xAF
+#define        I2O_CMD_DEVICE_ASSIGN           0xB7
+#define        I2O_CMD_DEVICE_RELEASE          0xB9
+#define        I2O_CMD_HRT_GET                 0xA8
+#define        I2O_CMD_ADAPTER_CLEAR           0xBE
+#define        I2O_CMD_ADAPTER_CONNECT         0xC9
+#define        I2O_CMD_ADAPTER_RESET           0xBD
+#define        I2O_CMD_LCT_NOTIFY              0xA2
+#define        I2O_CMD_OUTBOUND_INIT           0xA1
+#define        I2O_CMD_PATH_ENABLE             0xD3
+#define        I2O_CMD_PATH_QUIESCE            0xC5
+#define        I2O_CMD_PATH_RESET              0xD7
+#define        I2O_CMD_STATIC_MF_CREATE        0xDD
+#define        I2O_CMD_STATIC_MF_RELEASE       0xDF
+#define        I2O_CMD_STATUS_GET              0xA0
+#define        I2O_CMD_SW_DOWNLOAD             0xA9
+#define        I2O_CMD_SW_UPLOAD               0xAB
+#define        I2O_CMD_SW_REMOVE               0xAD
+#define        I2O_CMD_SYS_ENABLE              0xD1
+#define        I2O_CMD_SYS_MODIFY              0xC1
+#define        I2O_CMD_SYS_QUIESCE             0xC3
+#define        I2O_CMD_SYS_TAB_SET             0xA3
+
+#define I2O_CMD_UTIL_NOP               0x00
+#define I2O_CMD_UTIL_ABORT             0x01
+#define I2O_CMD_UTIL_CLAIM             0x09
+#define I2O_CMD_UTIL_RELEASE           0x0B
+#define I2O_CMD_UTIL_PARAMS_GET                0x06
+#define I2O_CMD_UTIL_PARAMS_SET                0x05
+#define I2O_CMD_UTIL_EVT_REGISTER      0x13
+#define I2O_CMD_UTIL_EVT_ACK           0x14
+#define I2O_CMD_UTIL_CONFIG_DIALOG     0x10
+#define I2O_CMD_UTIL_DEVICE_RESERVE    0x0D
+#define I2O_CMD_UTIL_DEVICE_RELEASE    0x0F
+#define I2O_CMD_UTIL_LOCK              0x17
+#define I2O_CMD_UTIL_LOCK_RELEASE      0x19
+#define I2O_CMD_UTIL_REPLY_FAULT_NOTIFY        0x15
+
+#define I2O_CMD_SCSI_EXEC              0x81
+#define I2O_CMD_SCSI_ABORT             0x83
+#define I2O_CMD_SCSI_BUSRESET          0x27
+
+#define I2O_CMD_BLOCK_READ             0x30
+#define I2O_CMD_BLOCK_WRITE            0x31
+#define I2O_CMD_BLOCK_CFLUSH           0x37
+#define I2O_CMD_BLOCK_MLOCK            0x49
+#define I2O_CMD_BLOCK_MUNLOCK          0x4B
+#define I2O_CMD_BLOCK_MMOUNT           0x41
+#define I2O_CMD_BLOCK_MEJECT           0x43
+
+#define I2O_PRIVATE_MSG                        0xFF
+
+/*
+ *     Init Outbound Q status 
+ */
+#define I2O_CMD_OUTBOUND_INIT_IN_PROGRESS      0x01
+#define I2O_CMD_OUTBOUND_INIT_REJECTED         0x02
+#define I2O_CMD_OUTBOUND_INIT_FAILED           0x03
+#define I2O_CMD_OUTBOUND_INIT_COMPLETE         0x04
+
+/*
+ *     I2O Get Status State values 
+ */
+
+#define        ADAPTER_STATE_INITIALIZING              0x01
+#define        ADAPTER_STATE_RESET                     0x02
+#define        ADAPTER_STATE_HOLD                      0x04
+#define ADAPTER_STATE_READY                    0x05
+#define        ADAPTER_STATE_OPERATIONAL               0x08
+#define        ADAPTER_STATE_FAILED                    0x10
+#define        ADAPTER_STATE_FAULTED                   0x11
+       
+/* I2O API function return values */
+
+#define I2O_RTN_NO_ERROR                       0
+#define I2O_RTN_NOT_INIT                       1
+#define I2O_RTN_FREE_Q_EMPTY                   2
+#define I2O_RTN_TCB_ERROR                      3
+#define I2O_RTN_TRANSACTION_ERROR              4
+#define I2O_RTN_ADAPTER_ALREADY_INIT           5
+#define I2O_RTN_MALLOC_ERROR                   6
+#define I2O_RTN_ADPTR_NOT_REGISTERED           7
+#define I2O_RTN_MSG_REPLY_TIMEOUT              8
+#define I2O_RTN_NO_STATUS                      9
+#define I2O_RTN_NO_FIRM_VER                    10
+#define        I2O_RTN_NO_LINK_SPEED                   11
+
+/* Reply message status defines for all messages */
+
+#define I2O_REPLY_STATUS_SUCCESS                       0x00
+#define I2O_REPLY_STATUS_ABORT_DIRTY                   0x01
+#define I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER        0x02
+#define        I2O_REPLY_STATUS_ABORT_PARTIAL_TRANSFER         0x03
+#define        I2O_REPLY_STATUS_ERROR_DIRTY                    0x04
+#define        I2O_REPLY_STATUS_ERROR_NO_DATA_TRANSFER         0x05
+#define        I2O_REPLY_STATUS_ERROR_PARTIAL_TRANSFER         0x06
+#define        I2O_REPLY_STATUS_PROCESS_ABORT_DIRTY            0x08
+#define        I2O_REPLY_STATUS_PROCESS_ABORT_NO_DATA_TRANSFER 0x09
+#define        I2O_REPLY_STATUS_PROCESS_ABORT_PARTIAL_TRANSFER 0x0A
+#define        I2O_REPLY_STATUS_TRANSACTION_ERROR              0x0B
+#define        I2O_REPLY_STATUS_PROGRESS_REPORT                0x80
+
+/* Status codes and Error Information for Parameter functions */
+
+#define I2O_PARAMS_STATUS_SUCCESS              0x00
+#define I2O_PARAMS_STATUS_BAD_KEY_ABORT                0x01
+#define I2O_PARAMS_STATUS_BAD_KEY_CONTINUE     0x02
+#define I2O_PARAMS_STATUS_BUFFER_FULL          0x03
+#define I2O_PARAMS_STATUS_BUFFER_TOO_SMALL     0x04
+#define I2O_PARAMS_STATUS_FIELD_UNREADABLE     0x05
+#define I2O_PARAMS_STATUS_FIELD_UNWRITEABLE    0x06
+#define I2O_PARAMS_STATUS_INSUFFICIENT_FIELDS  0x07
+#define I2O_PARAMS_STATUS_INVALID_GROUP_ID     0x08
+#define I2O_PARAMS_STATUS_INVALID_OPERATION    0x09
+#define I2O_PARAMS_STATUS_NO_KEY_FIELD         0x0A
+#define I2O_PARAMS_STATUS_NO_SUCH_FIELD                0x0B
+#define I2O_PARAMS_STATUS_NON_DYNAMIC_GROUP    0x0C
+#define I2O_PARAMS_STATUS_OPERATION_ERROR      0x0D
+#define I2O_PARAMS_STATUS_SCALAR_ERROR         0x0E
+#define I2O_PARAMS_STATUS_TABLE_ERROR          0x0F
+#define I2O_PARAMS_STATUS_WRONG_GROUP_TYPE     0x10
+
+/* DetailedStatusCode defines for Executive, DDM, Util and Transaction error
+ * messages: Table 3-2 Detailed Status Codes.*/
+
+#define I2O_DSC_SUCCESS                        0x0000
+#define I2O_DSC_BAD_KEY                        0x0002
+#define I2O_DSC_TCL_ERROR                      0x0003
+#define I2O_DSC_REPLY_BUFFER_FULL              0x0004
+#define I2O_DSC_NO_SUCH_PAGE                   0x0005
+#define I2O_DSC_INSUFFICIENT_RESOURCE_SOFT     0x0006
+#define I2O_DSC_INSUFFICIENT_RESOURCE_HARD     0x0007
+#define I2O_DSC_CHAIN_BUFFER_TOO_LARGE         0x0009
+#define I2O_DSC_UNSUPPORTED_FUNCTION           0x000A
+#define I2O_DSC_DEVICE_LOCKED                  0x000B
+#define I2O_DSC_DEVICE_RESET                   0x000C
+#define I2O_DSC_INAPPROPRIATE_FUNCTION         0x000D
+#define I2O_DSC_INVALID_INITIATOR_ADDRESS      0x000E
+#define I2O_DSC_INVALID_MESSAGE_FLAGS          0x000F
+#define I2O_DSC_INVALID_OFFSET                 0x0010
+#define I2O_DSC_INVALID_PARAMETER              0x0011
+#define I2O_DSC_INVALID_REQUEST                0x0012
+#define I2O_DSC_INVALID_TARGET_ADDRESS         0x0013
+#define I2O_DSC_MESSAGE_TOO_LARGE              0x0014
+#define I2O_DSC_MESSAGE_TOO_SMALL              0x0015
+#define I2O_DSC_MISSING_PARAMETER              0x0016
+#define I2O_DSC_TIMEOUT                        0x0017
+#define I2O_DSC_UNKNOWN_ERROR                  0x0018
+#define I2O_DSC_UNKNOWN_FUNCTION               0x0019
+#define I2O_DSC_UNSUPPORTED_VERSION            0x001A
+#define I2O_DSC_DEVICE_BUSY                    0x001B
+#define I2O_DSC_DEVICE_NOT_AVAILABLE           0x001C
+
+/* Device Claim Types */
+#define        I2O_CLAIM_PRIMARY                                       0x01000000
+#define        I2O_CLAIM_MANAGEMENT                                    0x02000000
+#define        I2O_CLAIM_AUTHORIZED                                    0x03000000
+#define        I2O_CLAIM_SECONDARY                                     0x04000000
+/* Message header defines for VersionOffset */
+#define I2OVER15       0x0001
+#define I2OVER20       0x0002
+/* Default is 1.5, FIXME: Need support for both 1.5 and 2.0 */
+#define I2OVERSION     I2OVER15
+#define SGL_OFFSET_0    I2OVERSION
+#define SGL_OFFSET_4    (0x0040 | I2OVERSION)
+#define SGL_OFFSET_5    (0x0050 | I2OVERSION)
+#define SGL_OFFSET_6    (0x0060 | I2OVERSION)
+#define SGL_OFFSET_7    (0x0070 | I2OVERSION)
+#define SGL_OFFSET_8    (0x0080 | I2OVERSION)
+#define SGL_OFFSET_9    (0x0090 | I2OVERSION)
+#define SGL_OFFSET_10   (0x00A0 | I2OVERSION)
+#define SGL_OFFSET_12   (0x00C0 | I2OVERSION)
+
+#define TRL_OFFSET_5    (0x0050 | I2OVERSION)
+#define TRL_OFFSET_6    (0x0060 | I2OVERSION)
+
+ /* msg header defines for MsgFlags */
+#define MSG_STATIC     0x0100
+#define MSG_64BIT_CNTXT        0x0200
+#define MSG_MULTI_TRANS        0x1000
+#define MSG_FAIL       0x2000
+#define MSG_LAST       0x4000
+#define MSG_REPLY      0x8000
+
+ /* minimum size msg */
+#define THREE_WORD_MSG_SIZE    0x00030000
+#define FOUR_WORD_MSG_SIZE     0x00040000
+#define FIVE_WORD_MSG_SIZE     0x00050000
+#define SIX_WORD_MSG_SIZE      0x00060000
+#define SEVEN_WORD_MSG_SIZE    0x00070000
+#define EIGHT_WORD_MSG_SIZE    0x00080000
+#define NINE_WORD_MSG_SIZE     0x00090000
+#define TEN_WORD_MSG_SIZE      0x000A0000
+#define I2O_MESSAGE_SIZE(x)    ((x)<<16)
+
+
+/* Special TID Assignments */
+
+#define ADAPTER_TID            0
+#define HOST_TID               1
+
+#define MSG_FRAME_SIZE         128
+#define NMBR_MSG_FRAMES                128
+
+#define MSG_POOL_SIZE          16384
+
+#define I2O_POST_WAIT_OK       0
+#define I2O_POST_WAIT_TIMEOUT  -ETIMEDOUT
+
+
+#endif /* __KERNEL__ */
+
+#endif /* _SCSI_I2O_H */
diff --git a/drivers/scsi/dpt/dpti_ioctl.h b/drivers/scsi/dpt/dpti_ioctl.h
new file mode 100644 (file)
index 0000000..461a209
--- /dev/null
@@ -0,0 +1,139 @@
+/***************************************************************************
+                          dpti_ioctl.h  -  description
+                             -------------------
+    begin                : Thu Sep 7 2000
+    copyright            : (C) 2001 by Adaptec
+    email                : deanna_bonds@adaptec.com
+
+    See README.dpti for history, notes, license info, and credits
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+/***************************************************************************
+ * This file is generated from  osd_unix.h                                 *
+ * *************************************************************************/
+
+#ifndef _dpti_ioctl_h
+#define _dpti_ioctl_h
+
+// IOCTL interface commands
+
+#ifndef _IOWR
+# define _IOWR(x,y,z)  (((x)<<8)|y)
+#endif
+#ifndef _IOW
+# define _IOW(x,y,z)   (((x)<<8)|y)
+#endif
+#ifndef _IOR
+# define _IOR(x,y,z)   (((x)<<8)|y)
+#endif
+#ifndef _IO
+# define _IO(x,y)      (((x)<<8)|y)
+#endif
+/* EATA PassThrough Command    */
+#define EATAUSRCMD      _IOWR('D',65,EATA_CP)
+/* Set Debug Level If Enabled  */
+#define DPT_DEBUG       _IOW('D',66,int)
+/* Get Signature Structure     */
+#define DPT_SIGNATURE   _IOR('D',67,dpt_sig_S)
+#if defined __bsdi__
+#define DPT_SIGNATURE_PACKED   _IOR('D',67,dpt_sig_S_Packed)
+#endif
+/* Get Number Of DPT Adapters  */
+#define DPT_NUMCTRLS    _IOR('D',68,int)
+/* Get Adapter Info Structure  */
+#define DPT_CTRLINFO    _IOR('D',69,CtrlInfo)
+/* Get Statistics If Enabled   */
+#define DPT_STATINFO    _IO('D',70)
+/* Clear Stats If Enabled      */
+#define DPT_CLRSTAT     _IO('D',71)
+/* Get System Info Structure   */
+#define DPT_SYSINFO     _IOR('D',72,sysInfo_S)
+/* Set Timeout Value           */
+#define DPT_TIMEOUT     _IO('D',73)
+/* Get config Data             */
+#define DPT_CONFIG      _IO('D',74)
+/* Get Blink LED Code          */
+#define DPT_BLINKLED    _IOR('D',75,int)
+/* Get Statistical information (if available) */
+#define DPT_STATS_INFO        _IOR('D',80,STATS_DATA)
+/* Clear the statistical information          */
+#define DPT_STATS_CLEAR       _IO('D',81)
+/* Get Performance metrics */
+#define DPT_PERF_INFO        _IOR('D',82,dpt_perf_t)
+/* Send an I2O command */
+#define I2OUSRCMD      _IO('D',76)
+/* Inform driver to re-acquire LCT information */
+#define I2ORESCANCMD   _IO('D',77)
+/* Inform driver to reset adapter */
+#define I2ORESETCMD    _IO('D',78)
+/* See if the target is mounted */
+#define DPT_TARGET_BUSY        _IOR('D',79, TARGET_BUSY_T)
+
+
+  /* Structure Returned From Get Controller Info                             */
+
+typedef struct {
+       uCHAR    state;            /* Operational state               */
+       uCHAR    id;               /* Host adapter SCSI id            */
+       int      vect;             /* Interrupt vector number         */
+       int      base;             /* Base I/O address                */
+       int      njobs;            /* # of jobs sent to HA            */
+       int      qdepth;           /* Controller queue depth.         */
+       int      wakebase;         /* mpx wakeup base index.          */
+       uLONG    SGsize;           /* Scatter/Gather list size.       */
+       unsigned heads;            /* heads for drives on cntlr.      */
+       unsigned sectors;          /* sectors for drives on cntlr.    */
+       uCHAR    do_drive32;       /* Flag for Above 16 MB Ability    */
+       uCHAR    BusQuiet;         /* SCSI Bus Quiet Flag             */
+       char     idPAL[4];         /* 4 Bytes Of The ID Pal           */
+       uCHAR    primary;          /* 1 For Primary, 0 For Secondary  */
+       uCHAR    eataVersion;      /* EATA Version                    */
+       uLONG    cpLength;         /* EATA Command Packet Length      */
+       uLONG    spLength;         /* EATA Status Packet Length       */
+       uCHAR    drqNum;           /* DRQ Index (0,5,6,7)             */ 
+       uCHAR    flag1;            /* EATA Flags 1 (Byte 9)           */
+       uCHAR    flag2;            /* EATA Flags 2 (Byte 30)          */
+} CtrlInfo;
+
+typedef struct {
+       uSHORT length;          // Remaining length of this
+       uSHORT drvrHBAnum;      // Relative HBA # used by the driver
+       uLONG baseAddr;         // Base I/O address
+       uSHORT blinkState;      // Blink LED state (0=Not in blink LED)
+       uCHAR pciBusNum;        // PCI Bus # (Optional)
+       uCHAR pciDeviceNum;     // PCI Device # (Optional)
+       uSHORT hbaFlags;        // Miscellaneous HBA flags
+       uSHORT Interrupt;       // Interrupt set for this device.
+#   if (defined(_DPT_ARC))
+       uLONG baseLength;
+       ADAPTER_OBJECT *AdapterObject;
+       LARGE_INTEGER DmaLogicalAddress;
+       PVOID DmaVirtualAddress;
+       LARGE_INTEGER ReplyLogicalAddress;
+       PVOID ReplyVirtualAddress;
+#   else
+       uLONG reserved1;        // Reserved for future expansion
+       uLONG reserved2;        // Reserved for future expansion
+       uLONG reserved3;        // Reserved for future expansion
+#   endif
+} drvrHBAinfo_S;
+
+typedef struct TARGET_BUSY
+{
+  uLONG channel;
+  uLONG id;
+  uLONG lun;
+  uLONG isBusy;
+} TARGET_BUSY_T;
+
+#endif
+
diff --git a/drivers/scsi/dpt/dptsig.h b/drivers/scsi/dpt/dptsig.h
new file mode 100644 (file)
index 0000000..95a4cce
--- /dev/null
@@ -0,0 +1,339 @@
+/*     BSDI dptsig.h,v 1.7 1998/06/03 19:15:00 karels Exp      */
+
+/*
+ * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source form, with or without modification, are
+ * permitted provided that redistributions of source code must retain the
+ * above copyright notice, this list of conditions and the following disclaimer.
+ *
+ * This software is provided `as is' by Distributed Processing Technology and
+ * any express or implied warranties, including, but not limited to, the
+ * implied warranties of merchantability and fitness for a particular purpose,
+ * are disclaimed. In no event shall Distributed Processing Technology be
+ * liable for any direct, indirect, incidental, special, exemplary or
+ * consequential damages (including, but not limited to, procurement of
+ * substitute goods or services; loss of use, data, or profits; or business
+ * interruptions) however caused and on any theory of liability, whether in
+ * contract, strict liability, or tort (including negligence or otherwise)
+ * arising in any way out of the use of this driver software, even if advised
+ * of the possibility of such damage.
+ *
+ */
+
+#ifndef __DPTSIG_H_
+#define __DPTSIG_H_
+#ifdef _SINIX_ADDON
+#include "dpt.h"
+#endif
+/* DPT SIGNATURE SPEC AND HEADER FILE                           */
+/* Signature Version 1 (sorry no 'A')                           */
+
+/* to make sure we are talking the same size under all OS's     */
+typedef unsigned char sigBYTE;
+typedef unsigned short sigWORD;
+#if (defined(_MULTI_DATAMODEL) && defined(sun) && !defined(_ILP32))
+typedef uint32_t sigLONG;
+#else
+typedef unsigned long sigLONG;
+#endif
+
+/*
+ * use sigWORDLittleEndian for:
+ *  dsCapabilities
+ *  dsDeviceSupp
+ *  dsAdapterSupp
+ *  dsApplication
+ * use sigLONGLittleEndian for:
+ *      dsOS
+ * so that the sig can be standardised to Little Endian
+ */
+#if (defined(_DPT_BIG_ENDIAN))
+# define sigWORDLittleEndian(x) ((((x)&0xFF)<<8)|(((x)>>8)&0xFF))
+# define sigLONGLittleEndian(x) \
+        ((((x)&0xFF)<<24) |             \
+         (((x)&0xFF00)<<8) |    \
+         (((x)&0xFF0000L)>>8) | \
+         (((x)&0xFF000000L)>>24))
+#else
+# define sigWORDLittleEndian(x) (x)
+# define sigLONGLittleEndian(x) (x)
+#endif
+
+/* must make sure the structure is not word or double-word aligned      */
+/* ---------------------------------------------------------------      */
+/* Borland will ignore the following pragma:                            */
+/* Word alignment is OFF by default.  If in the, IDE make               */
+/* sure that Options | Compiler | Code Generation | Word Alignment      */
+/* is not checked.  If using BCC, do not use the -a option.             */
+
+#ifndef NO_PACK
+#if defined (_DPT_AIX)
+#pragma options align=packed
+#else
+#pragma pack(1)
+#endif  /* aix */
+#endif
+/* For the Macintosh */
+#if STRUCTALIGNMENTSUPPORTED
+#pragma options align=mac68k
+#endif
+
+
+/* Current Signature Version - sigBYTE dsSigVersion; */
+/* ------------------------------------------------------------------ */
+#define SIG_VERSION 1
+
+/* Processor Family - sigBYTE dsProcessorFamily;  DISTINCT VALUES */
+/* ------------------------------------------------------------------ */
+/* What type of processor the file is meant to run on. */
+/* This will let us know whether to read sigWORDs as high/low or low/high. */
+#define PROC_INTEL      0x00    /* Intel 80x86 */
+#define PROC_MOTOROLA   0x01    /* Motorola 68K */
+#define PROC_MIPS4000   0x02    /* MIPS RISC 4000 */
+#define PROC_ALPHA      0x03    /* DEC Alpha */
+#define PROC_POWERPC    0x04    /* IBM Power PC */
+#define PROC_i960       0x05    /* Intel i960 */
+#define PROC_ULTRASPARC 0x06    /* SPARC processor */
+
+/* Specific Minimim Processor - sigBYTE dsProcessor;    FLAG BITS */
+/* ------------------------------------------------------------------ */
+/* Different bit definitions dependent on processor_family */
+
+/* PROC_INTEL: */
+#define PROC_8086       0x01    /* Intel 8086 */
+#define PROC_286        0x02    /* Intel 80286 */
+#define PROC_386        0x04    /* Intel 80386 */
+#define PROC_486        0x08    /* Intel 80486 */
+#define PROC_PENTIUM    0x10    /* Intel 586 aka P5 aka Pentium */
+#define PROC_SEXIUM    0x20    /* Intel 686 aka P6 aka Pentium Pro or MMX */
+
+/* PROC_i960: */
+#define PROC_960RX      0x01    /* Intel 80960RC/RD */
+#define PROC_960HX      0x02    /* Intel 80960HA/HD/HT */
+
+/* PROC_MOTOROLA: */
+#define PROC_68000      0x01    /* Motorola 68000 */
+#define PROC_68010     0x02    /* Motorola 68010 */
+#define PROC_68020      0x04    /* Motorola 68020 */
+#define PROC_68030      0x08    /* Motorola 68030 */
+#define PROC_68040      0x10    /* Motorola 68040 */
+
+/* PROC_POWERPC */
+#define PROC_PPC601            0x01    /* PowerPC 601 */
+#define PROC_PPC603            0x02    /* PowerPC 603 */
+#define PROC_PPC604            0x04    /* PowerPC 604 */
+
+/* PROC_MIPS4000: */
+#define PROC_R4000      0x01    /* MIPS R4000 */
+
+/* Filetype - sigBYTE dsFiletype;       DISTINCT VALUES */
+/* ------------------------------------------------------------------ */
+#define FT_EXECUTABLE   0       /* Executable Program */
+#define FT_SCRIPT       1       /* Script/Batch File??? */
+#define FT_HBADRVR      2       /* HBA Driver */
+#define FT_OTHERDRVR    3       /* Other Driver */
+#define FT_IFS          4       /* Installable Filesystem Driver */
+#define FT_ENGINE       5       /* DPT Engine */
+#define FT_COMPDRVR     6       /* Compressed Driver Disk */
+#define FT_LANGUAGE     7       /* Foreign Language file */
+#define FT_FIRMWARE     8       /* Downloadable or actual Firmware */
+#define FT_COMMMODL     9       /* Communications Module */
+#define FT_INT13        10      /* INT 13 style HBA Driver */
+#define FT_HELPFILE     11      /* Help file */
+#define FT_LOGGER       12      /* Event Logger */
+#define FT_INSTALL      13      /* An Install Program */
+#define FT_LIBRARY      14      /* Storage Manager Real-Mode Calls */
+#define FT_RESOURCE    15      /* Storage Manager Resource File */
+#define FT_MODEM_DB    16      /* Storage Manager Modem Database */
+
+/* Filetype flags - sigBYTE dsFiletypeFlags;    FLAG BITS */
+/* ------------------------------------------------------------------ */
+#define FTF_DLL         0x01    /* Dynamic Link Library */
+#define FTF_NLM         0x02    /* Netware Loadable Module */
+#define FTF_OVERLAYS    0x04    /* Uses overlays */
+#define FTF_DEBUG       0x08    /* Debug version */
+#define FTF_TSR         0x10    /* TSR */
+#define FTF_SYS         0x20    /* DOS Loadable driver */
+#define FTF_PROTECTED   0x40    /* Runs in protected mode */
+#define FTF_APP_SPEC    0x80    /* Application Specific */
+#define FTF_ROM                (FTF_SYS|FTF_TSR)       /* Special Case */
+
+/* OEM - sigBYTE dsOEM;         DISTINCT VALUES */
+/* ------------------------------------------------------------------ */
+#define OEM_DPT         0       /* DPT */
+#define OEM_ATT         1       /* ATT */
+#define OEM_NEC         2       /* NEC */
+#define OEM_ALPHA       3       /* Alphatronix */
+#define OEM_AST         4       /* AST */
+#define OEM_OLIVETTI    5       /* Olivetti */
+#define OEM_SNI         6       /* Siemens/Nixdorf */
+#define OEM_SUN         7       /* SUN Microsystems */
+
+/* Operating System  - sigLONG dsOS;    FLAG BITS */
+/* ------------------------------------------------------------------ */
+#define OS_DOS          0x00000001 /* PC/MS-DOS                                */
+#define OS_WINDOWS      0x00000002 /* Microsoft Windows 3.x            */
+#define OS_WINDOWS_NT   0x00000004 /* Microsoft Windows NT             */
+#define OS_OS2M         0x00000008 /* OS/2 1.2.x,MS 1.3.0,IBM 1.3.x - Monolithic */
+#define OS_OS2L         0x00000010 /* Microsoft OS/2 1.301 - LADDR     */
+#define OS_OS22x        0x00000020 /* IBM OS/2 2.x                     */
+#define OS_NW286        0x00000040 /* Novell NetWare 286               */
+#define OS_NW386        0x00000080 /* Novell NetWare 386               */
+#define OS_GEN_UNIX     0x00000100 /* Generic Unix                     */
+#define OS_SCO_UNIX     0x00000200 /* SCO Unix                         */
+#define OS_ATT_UNIX     0x00000400 /* ATT Unix                         */
+#define OS_UNIXWARE     0x00000800 /* USL Unix                         */
+#define OS_INT_UNIX     0x00001000 /* Interactive Unix                 */
+#define OS_SOLARIS      0x00002000 /* SunSoft Solaris                  */
+#define OS_QNX          0x00004000 /* QNX for Tom Moch                 */
+#define OS_NEXTSTEP     0x00008000 /* NeXTSTEP/OPENSTEP/MACH           */
+#define OS_BANYAN       0x00010000 /* Banyan Vines                     */
+#define OS_OLIVETTI_UNIX 0x00020000/* Olivetti Unix                    */
+#define OS_MAC_OS      0x00040000 /* Mac OS                            */
+#define OS_WINDOWS_95  0x00080000 /* Microsoft Windows '95             */
+#define OS_NW4x                0x00100000 /* Novell Netware 4.x                */
+#define OS_BSDI_UNIX   0x00200000 /* BSDi Unix BSD/OS 2.0 and up       */
+#define OS_AIX_UNIX     0x00400000 /* AIX Unix                         */
+#define OS_FREE_BSD    0x00800000 /* FreeBSD Unix                      */
+#define OS_LINUX       0x01000000 /* Linux                             */
+#define OS_DGUX_UNIX   0x02000000 /* Data General Unix                 */
+#define OS_SINIX_N      0x04000000 /* SNI SINIX-N                      */
+#define OS_PLAN9       0x08000000 /* ATT Plan 9                        */
+#define OS_TSX         0x10000000 /* SNH TSX-32                        */
+
+#define OS_OTHER        0x80000000 /* Other                            */
+
+/* Capabilities - sigWORD dsCapabilities;        FLAG BITS */
+/* ------------------------------------------------------------------ */
+#define CAP_RAID0       0x0001  /* RAID-0 */
+#define CAP_RAID1       0x0002  /* RAID-1 */
+#define CAP_RAID3       0x0004  /* RAID-3 */
+#define CAP_RAID5       0x0008  /* RAID-5 */
+#define CAP_SPAN        0x0010  /* Spanning */
+#define CAP_PASS        0x0020  /* Provides passthrough */
+#define CAP_OVERLAP     0x0040  /* Passthrough supports overlapped commands */
+#define CAP_ASPI        0x0080  /* Supports ASPI Command Requests */
+#define CAP_ABOVE16MB   0x0100  /* ISA Driver supports greater than 16MB */
+#define CAP_EXTEND      0x8000  /* Extended info appears after description */
+#ifdef SNI_MIPS
+#define CAP_CACHEMODE   0x1000  /* dpt_force_cache is set in driver */
+#endif
+
+/* Devices Supported - sigWORD dsDeviceSupp;    FLAG BITS */
+/* ------------------------------------------------------------------ */
+#define DEV_DASD        0x0001  /* DASD (hard drives) */
+#define DEV_TAPE        0x0002  /* Tape drives */
+#define DEV_PRINTER     0x0004  /* Printers */
+#define DEV_PROC        0x0008  /* Processors */
+#define DEV_WORM        0x0010  /* WORM drives */
+#define DEV_CDROM       0x0020  /* CD-ROM drives */
+#define DEV_SCANNER     0x0040  /* Scanners */
+#define DEV_OPTICAL     0x0080  /* Optical Drives */
+#define DEV_JUKEBOX     0x0100  /* Jukebox */
+#define DEV_COMM        0x0200  /* Communications Devices */
+#define DEV_OTHER       0x0400  /* Other Devices */
+#define DEV_ALL         0xFFFF  /* All SCSI Devices */
+
+/* Adapters Families Supported - sigWORD dsAdapterSupp; FLAG BITS */
+/* ------------------------------------------------------------------ */
+#define ADF_2001        0x0001  /* PM2001           */
+#define ADF_2012A       0x0002  /* PM2012A          */
+#define ADF_PLUS_ISA    0x0004  /* PM2011,PM2021    */
+#define ADF_PLUS_EISA   0x0008  /* PM2012B,PM2022   */
+#define ADF_SC3_ISA    0x0010  /* PM2021           */
+#define ADF_SC3_EISA   0x0020  /* PM2022,PM2122, etc */
+#define ADF_SC3_PCI    0x0040  /* SmartCache III PCI */
+#define ADF_SC4_ISA    0x0080  /* SmartCache IV ISA */
+#define ADF_SC4_EISA   0x0100  /* SmartCache IV EISA */
+#define ADF_SC4_PCI    0x0200  /* SmartCache IV PCI */
+#define ADF_SC5_PCI    0x0400  /* Fifth Generation I2O products */
+/*
+ *     Combinations of products
+ */
+#define ADF_ALL_2000   (ADF_2001|ADF_2012A)
+#define ADF_ALL_PLUS   (ADF_PLUS_ISA|ADF_PLUS_EISA)
+#define ADF_ALL_SC3    (ADF_SC3_ISA|ADF_SC3_EISA|ADF_SC3_PCI)
+#define ADF_ALL_SC4    (ADF_SC4_ISA|ADF_SC4_EISA|ADF_SC4_PCI)
+#define ADF_ALL_SC5    (ADF_SC5_PCI)
+/* All EATA Cacheing Products */
+#define ADF_ALL_CACHE  (ADF_ALL_PLUS|ADF_ALL_SC3|ADF_ALL_SC4)
+/* All EATA Bus Mastering Products */
+#define ADF_ALL_MASTER (ADF_2012A|ADF_ALL_CACHE)
+/* All EATA Adapter Products */
+#define ADF_ALL_EATA   (ADF_2001|ADF_ALL_MASTER)
+#define ADF_ALL                ADF_ALL_EATA
+
+/* Application - sigWORD dsApplication;         FLAG BITS */
+/* ------------------------------------------------------------------ */
+#define APP_DPTMGR      0x0001  /* DPT Storage Manager */
+#define APP_ENGINE      0x0002  /* DPT Engine */
+#define APP_SYTOS       0x0004  /* Sytron Sytos Plus */
+#define APP_CHEYENNE    0x0008  /* Cheyenne ARCServe + ARCSolo */
+#define APP_MSCDEX      0x0010  /* Microsoft CD-ROM extensions */
+#define APP_NOVABACK    0x0020  /* NovaStor Novaback */
+#define APP_AIM         0x0040  /* Archive Information Manager */
+
+/* Requirements - sigBYTE dsRequirements;         FLAG BITS             */
+/* ------------------------------------------------------------------   */
+#define REQ_SMARTROM    0x01    /* Requires SmartROM to be present      */
+#define REQ_DPTDDL      0x02    /* Requires DPTDDL.SYS to be loaded     */
+#define REQ_HBA_DRIVER  0x04    /* Requires an HBA driver to be loaded  */
+#define REQ_ASPI_TRAN   0x08    /* Requires an ASPI Transport Modules   */
+#define REQ_ENGINE      0x10    /* Requires a DPT Engine to be loaded   */
+#define REQ_COMM_ENG    0x20    /* Requires a DPT Communications Engine */
+
+/*
+ * You may adjust dsDescription_size with an override to a value less than
+ * 50 so that the structure allocates less real space.
+ */
+#if (!defined(dsDescription_size))
+# define dsDescription_size 50
+#endif
+
+typedef struct dpt_sig {
+    char    dsSignature[6];      /* ALWAYS "dPtSiG" */
+    sigBYTE dsSigVersion;        /* signature version (currently 1) */
+    sigBYTE dsProcessorFamily;   /* what type of processor */
+    sigBYTE dsProcessor;         /* precise processor */
+    sigBYTE dsFiletype;          /* type of file */
+    sigBYTE dsFiletypeFlags;     /* flags to specify load type, etc. */
+    sigBYTE dsOEM;               /* OEM file was created for */
+    sigLONG dsOS;                /* which Operating systems */
+    sigWORD dsCapabilities;      /* RAID levels, etc. */
+    sigWORD dsDeviceSupp;        /* Types of SCSI devices supported */
+    sigWORD dsAdapterSupp;       /* DPT adapter families supported */
+    sigWORD dsApplication;       /* applications file is for */
+    sigBYTE dsRequirements;      /* Other driver dependencies */
+    sigBYTE dsVersion;           /* 1 */
+    sigBYTE dsRevision;          /* 'J' */
+    sigBYTE dsSubRevision;       /* '9'   ' ' if N/A */
+    sigBYTE dsMonth;             /* creation month */
+    sigBYTE dsDay;               /* creation day */
+    sigBYTE dsYear;              /* creation year since 1980 (1993=13) */
+    /* description (NULL terminated) */
+    char  dsDescription[dsDescription_size];
+} dpt_sig_S;
+/* 32 bytes minimum - with no description.  Put NULL at description[0] */
+/* 81 bytes maximum - with 49 character description plus NULL. */
+
+/* This line added at Roycroft's request */
+/* Microsoft's NT compiler gets confused if you do a pack and don't */
+/* restore it. */
+
+#ifndef NO_UNPACK
+#if defined (_DPT_AIX)
+#pragma options align=reset
+#elif defined (UNPACK_FOUR)
+#pragma pack(4)
+#else
+#pragma pack()
+#endif  /* aix */
+#endif
+/* For the Macintosh */
+#if STRUCTALIGNMENTSUPPORTED
+#pragma options align=reset
+#endif
+
+#endif
diff --git a/drivers/scsi/dpt/osd_defs.h b/drivers/scsi/dpt/osd_defs.h
new file mode 100644 (file)
index 0000000..de3ae57
--- /dev/null
@@ -0,0 +1,79 @@
+/*     BSDI osd_defs.h,v 1.4 1998/06/03 19:14:58 karels Exp    */
+/*
+ * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source form, with or without modification, are
+ * permitted provided that redistributions of source code must retain the
+ * above copyright notice, this list of conditions and the following disclaimer.
+ *
+ * This software is provided `as is' by Distributed Processing Technology and
+ * any express or implied warranties, including, but not limited to, the
+ * implied warranties of merchantability and fitness for a particular purpose,
+ * are disclaimed. In no event shall Distributed Processing Technology be
+ * liable for any direct, indirect, incidental, special, exemplary or
+ * consequential damages (including, but not limited to, procurement of
+ * substitute goods or services; loss of use, data, or profits; or business
+ * interruptions) however caused and on any theory of liability, whether in
+ * contract, strict liability, or tort (including negligence or otherwise)
+ * arising in any way out of the use of this driver software, even if advised
+ * of the possibility of such damage.
+ *
+ */
+
+#ifndef                _OSD_DEFS_H
+#define                _OSD_DEFS_H
+
+/*File - OSD_DEFS.H
+ ****************************************************************************
+ *
+ *Description:
+ *
+ *     This file contains the OS dependent defines.  This file is included
+ *in osd_util.h and provides the OS specific defines for that file.
+ *
+ *Copyright Distributed Processing Technology, Corp.
+ *       140 Candace Dr.
+ *       Maitland, Fl. 32751   USA
+ *       Phone: (407) 830-5522  Fax: (407) 260-5366
+ *       All Rights Reserved
+ *
+ *Author:      Doug Anderson
+ *Date:                1/31/94
+ *
+ *Editors:
+ *
+ *Remarks:
+ *
+ *
+ *****************************************************************************/
+
+
+/*Definitions - Defines & Constants ----------------------------------------- */
+
+  /* Define the operating system */
+#if (defined(__linux__))
+# define _DPT_LINUX
+#elif (defined(__bsdi__))
+# define _DPT_BSDI
+#elif (defined(__FreeBSD__))
+# define _DPT_FREE_BSD
+#else
+# define _DPT_SCO
+#endif
+
+#if defined (ZIL_CURSES)
+#define                _DPT_CURSES
+#else
+#define         _DPT_MOTIF
+#endif
+
+  /* Redefine 'far' to nothing - no far pointer type required in UNIX */
+#define                far
+
+  /* Define the mutually exclusive semaphore type */
+#define                SEMAPHORE_T     unsigned int *
+  /* Define a handle to a DLL */
+#define                DLL_HANDLE_T    unsigned int *
+
+#endif
diff --git a/drivers/scsi/dpt/osd_util.h b/drivers/scsi/dpt/osd_util.h
new file mode 100644 (file)
index 0000000..4b56c04
--- /dev/null
@@ -0,0 +1,358 @@
+/*     BSDI osd_util.h,v 1.8 1998/06/03 19:14:58 karels Exp    */
+
+/*
+ * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source form, with or without modification, are
+ * permitted provided that redistributions of source code must retain the
+ * above copyright notice, this list of conditions and the following disclaimer.
+ *
+ * This software is provided `as is' by Distributed Processing Technology and
+ * any express or implied warranties, including, but not limited to, the
+ * implied warranties of merchantability and fitness for a particular purpose,
+ * are disclaimed. In no event shall Distributed Processing Technology be
+ * liable for any direct, indirect, incidental, special, exemplary or
+ * consequential damages (including, but not limited to, procurement of
+ * substitute goods or services; loss of use, data, or profits; or business
+ * interruptions) however caused and on any theory of liability, whether in
+ * contract, strict liability, or tort (including negligence or otherwise)
+ * arising in any way out of the use of this driver software, even if advised
+ * of the possibility of such damage.
+ *
+ */
+
+#ifndef         __OSD_UTIL_H
+#define         __OSD_UTIL_H
+
+/*File - OSD_UTIL.H
+ ****************************************************************************
+ *
+ *Description:
+ *
+ *      This file contains defines and function prototypes that are
+ *operating system dependent.  The resources defined in this file
+ *are not specific to any particular application.
+ *
+ *Copyright Distributed Processing Technology, Corp.
+ *        140 Candace Dr.
+ *        Maitland, Fl. 32751   USA
+ *        Phone: (407) 830-5522  Fax: (407) 260-5366
+ *        All Rights Reserved
+ *
+ *Author:       Doug Anderson
+ *Date:         1/7/94
+ *
+ *Editors:
+ *
+ *Remarks:
+ *
+ *
+ *****************************************************************************/
+
+
+/*Definitions - Defines & Constants ----------------------------------------- */
+
+/*----------------------------- */
+/* Operating system selections: */
+/*----------------------------- */
+
+/*#define               _DPT_MSDOS      */
+/*#define               _DPT_WIN_3X     */
+/*#define               _DPT_WIN_4X     */
+/*#define               _DPT_WIN_NT     */
+/*#define               _DPT_NETWARE    */
+/*#define               _DPT_OS2        */
+/*#define               _DPT_SCO        */
+/*#define               _DPT_UNIXWARE   */
+/*#define               _DPT_SOLARIS    */
+/*#define               _DPT_NEXTSTEP   */
+/*#define               _DPT_BANYAN     */
+
+/*-------------------------------- */
+/* Include the OS specific defines */
+/*-------------------------------- */
+
+/*#define       OS_SELECTION    From Above List */
+/*#define       SEMAPHORE_T     ??? */
+/*#define       DLL_HANDLE_T    ??? */
+
+#if (defined(KERNEL) && (defined(__FreeBSD__) || defined(__bsdi__)))
+# include        "i386/isa/dpt_osd_defs.h"
+#else
+# include        "osd_defs.h"
+#endif
+
+#ifndef DPT_UNALIGNED
+   #define      DPT_UNALIGNED
+#endif
+
+#ifndef DPT_EXPORT
+   #define      DPT_EXPORT
+#endif
+
+#ifndef DPT_IMPORT
+   #define      DPT_IMPORT
+#endif
+
+#ifndef DPT_RUNTIME_IMPORT
+   #define      DPT_RUNTIME_IMPORT  DPT_IMPORT
+#endif
+
+/*--------------------- */
+/* OS dependent defines */
+/*--------------------- */
+
+#if defined (_DPT_MSDOS) || defined (_DPT_WIN_3X)
+   #define      _DPT_16_BIT
+#else
+   #define      _DPT_32_BIT
+#endif
+
+#if defined (_DPT_SCO) || defined (_DPT_UNIXWARE) || defined (_DPT_SOLARIS) || defined (_DPT_AIX) || defined (SNI_MIPS) || defined (_DPT_BSDI) || defined (_DPT_FREE_BSD) || defined(_DPT_LINUX)
+   #define      _DPT_UNIX
+#endif
+
+#if defined (_DPT_WIN_3x) || defined (_DPT_WIN_4X) || defined (_DPT_WIN_NT) \
+           || defined (_DPT_OS2)
+   #define      _DPT_DLL_SUPPORT
+#endif
+
+#if !defined (_DPT_MSDOS) && !defined (_DPT_WIN_3X) && !defined (_DPT_NETWARE)
+   #define      _DPT_PREEMPTIVE
+#endif
+
+#if !defined (_DPT_MSDOS) && !defined (_DPT_WIN_3X)
+   #define      _DPT_MULTI_THREADED
+#endif
+
+#if !defined (_DPT_MSDOS)
+   #define      _DPT_MULTI_TASKING
+#endif
+
+  /* These exist for platforms that   */
+  /* chunk when accessing mis-aligned */
+  /* data                             */
+#if defined (SNI_MIPS) || defined (_DPT_SOLARIS)
+   #if defined (_DPT_BIG_ENDIAN)
+       #if !defined (_DPT_STRICT_ALIGN)
+            #define _DPT_STRICT_ALIGN
+       #endif
+   #endif
+#endif
+
+  /* Determine if in C or C++ mode */
+#ifdef  __cplusplus
+   #define      _DPT_CPP
+#else
+   #define      _DPT_C
+#endif
+
+/*-------------------------------------------------------------------*/
+/* Under Solaris the compiler refuses to accept code like:           */
+/*   { {"DPT"}, 0, NULL .... },                                      */
+/* and complains about the {"DPT"} part by saying "cannot use { }    */
+/* to initialize char*".                                             */
+/*                                                                   */
+/* By defining these ugly macros we can get around this and also     */
+/* not have to copy and #ifdef large sections of code.  I know that  */
+/* these macros are *really* ugly, but they should help reduce       */
+/* maintenance in the long run.                                      */
+/*                                                                   */
+/*-------------------------------------------------------------------*/
+#if !defined (DPTSQO)
+   #if defined (_DPT_SOLARIS)
+      #define DPTSQO
+      #define DPTSQC
+   #else
+      #define DPTSQO {
+      #define DPTSQC }
+   #endif  /* solaris */
+#endif  /* DPTSQO */
+
+
+/*---------------------- */
+/* OS dependent typedefs */
+/*---------------------- */
+
+#if defined (_DPT_MSDOS) || defined (_DPT_SCO)
+   #define BYTE unsigned char
+   #define WORD unsigned short
+#endif
+
+#ifndef _DPT_TYPEDEFS
+   #define _DPT_TYPEDEFS
+   typedef unsigned char   uCHAR;
+   typedef unsigned short  uSHORT;
+   typedef unsigned int    uINT;
+   typedef unsigned long   uLONG;
+
+   typedef union {
+        uCHAR        u8[4];
+        uSHORT       u16[2];
+        uLONG        u32;
+   } access_U;
+#endif
+
+#if !defined (NULL)
+   #define      NULL    0
+#endif
+
+
+/*Prototypes - function ----------------------------------------------------- */
+
+#ifdef  __cplusplus
+   extern "C" {         /* Declare all these functions as "C" functions */
+#endif
+
+/*------------------------ */
+/* Byte reversal functions */
+/*------------------------ */
+
+  /* Reverses the byte ordering of a 2 byte variable */
+#if (!defined(osdSwap2))
+ uSHORT       osdSwap2(DPT_UNALIGNED uSHORT *);
+#endif  // !osdSwap2
+
+  /* Reverses the byte ordering of a 4 byte variable and shifts left 8 bits */
+#if (!defined(osdSwap3))
+ uLONG        osdSwap3(DPT_UNALIGNED uLONG *);
+#endif  // !osdSwap3
+
+
+#ifdef  _DPT_NETWARE
+   #include "novpass.h" /* For DPT_Bswapl() prototype */
+       /* Inline the byte swap */
+   #ifdef __cplusplus
+        inline uLONG osdSwap4(uLONG *inLong) {
+        return *inLong = DPT_Bswapl(*inLong);
+        }
+   #else
+        #define osdSwap4(inLong)       DPT_Bswapl(inLong)
+   #endif  // cplusplus
+#else
+       /* Reverses the byte ordering of a 4 byte variable */
+# if (!defined(osdSwap4))
+   uLONG        osdSwap4(DPT_UNALIGNED uLONG *);
+# endif  // !osdSwap4
+
+  /* The following functions ALWAYS swap regardless of the *
+   * presence of DPT_BIG_ENDIAN                            */
+
+   uSHORT       trueSwap2(DPT_UNALIGNED uSHORT *);
+   uLONG        trueSwap4(DPT_UNALIGNED uLONG *);
+
+#endif  // netware
+
+
+/*-------------------------------------*
+ * Network order swap functions        *
+ *                                     *
+ * These functions/macros will be used *
+ * by the structure insert()/extract() *
+ * functions.                          *
+ *
+ * We will enclose all structure       *
+ * portability modifications inside    *
+ * #ifdefs.  When we are ready, we     *
+ * will #define DPT_PORTABLE to begin  *
+ * using the modifications.            *
+ *-------------------------------------*/
+uLONG  netSwap4(uLONG val);
+
+#if defined (_DPT_BIG_ENDIAN)
+
+// for big-endian we need to swap
+
+#ifndef NET_SWAP_2
+#define NET_SWAP_2(x) (((x) >> 8) | ((x) << 8))
+#endif  // NET_SWAP_2
+
+#ifndef NET_SWAP_4
+#define NET_SWAP_4(x) netSwap4((x))
+#endif  // NET_SWAP_4
+
+#else
+
+// for little-endian we don't need to do anything
+
+#ifndef NET_SWAP_2
+#define NET_SWAP_2(x) (x)
+#endif  // NET_SWAP_2
+
+#ifndef NET_SWAP_4
+#define NET_SWAP_4(x) (x)
+#endif  // NET_SWAP_4
+
+#endif  // big endian
+
+
+
+/*----------------------------------- */
+/* Run-time loadable module functions */
+/*----------------------------------- */
+
+  /* Loads the specified run-time loadable DLL */
+DLL_HANDLE_T    osdLoadModule(uCHAR *);
+  /* Unloads the specified run-time loadable DLL */
+uSHORT          osdUnloadModule(DLL_HANDLE_T);
+  /* Returns a pointer to a function inside a run-time loadable DLL */
+void *          osdGetFnAddr(DLL_HANDLE_T,uCHAR *);
+
+/*--------------------------------------- */
+/* Mutually exclusive semaphore functions */
+/*--------------------------------------- */
+
+  /* Create a named semaphore */
+SEMAPHORE_T     osdCreateNamedSemaphore(char *);
+  /* Create a mutually exlusive semaphore */
+SEMAPHORE_T     osdCreateSemaphore(void);
+       /* create an event semaphore */
+SEMAPHORE_T              osdCreateEventSemaphore(void);
+       /* create a named event semaphore */
+SEMAPHORE_T             osdCreateNamedEventSemaphore(char *);
+
+  /* Destroy the specified mutually exclusive semaphore object */
+uSHORT          osdDestroySemaphore(SEMAPHORE_T);
+  /* Request access to the specified mutually exclusive semaphore */
+uLONG           osdRequestSemaphore(SEMAPHORE_T,uLONG);
+  /* Release access to the specified mutually exclusive semaphore */
+uSHORT          osdReleaseSemaphore(SEMAPHORE_T);
+       /* wait for a event to happen */
+uLONG                            osdWaitForEventSemaphore(SEMAPHORE_T, uLONG);
+       /* signal an event */
+uLONG                            osdSignalEventSemaphore(SEMAPHORE_T);
+       /* reset the event */
+uLONG                            osdResetEventSemaphore(SEMAPHORE_T);
+
+/*----------------- */
+/* Thread functions */
+/*----------------- */
+
+  /* Releases control to the task switcher in non-preemptive */
+  /* multitasking operating systems. */
+void            osdSwitchThreads(void);
+
+  /* Starts a thread function */
+uLONG   osdStartThread(void *,void *);
+
+/* what is my thread id */
+uLONG osdGetThreadID(void);
+
+/* wakes up the specifed thread */
+void osdWakeThread(uLONG);
+
+/* osd sleep for x miliseconds */
+void osdSleep(uLONG);
+
+#define DPT_THREAD_PRIORITY_LOWEST 0x00
+#define DPT_THREAD_PRIORITY_NORMAL 0x01
+#define DPT_THREAD_PRIORITY_HIGHEST 0x02
+
+uCHAR osdSetThreadPriority(uLONG tid, uCHAR priority);
+
+#ifdef __cplusplus
+   }    /* end the xtern "C" declaration */
+#endif
+
+#endif  /* osd_util_h */
diff --git a/drivers/scsi/dpt/sys_info.h b/drivers/scsi/dpt/sys_info.h
new file mode 100644 (file)
index 0000000..d23b70c
--- /dev/null
@@ -0,0 +1,417 @@
+/*     BSDI sys_info.h,v 1.6 1998/06/03 19:14:59 karels Exp    */
+
+/*
+ * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source form, with or without modification, are
+ * permitted provided that redistributions of source code must retain the
+ * above copyright notice, this list of conditions and the following disclaimer.
+ *
+ * This software is provided `as is' by Distributed Processing Technology and
+ * any express or implied warranties, including, but not limited to, the
+ * implied warranties of merchantability and fitness for a particular purpose,
+ * are disclaimed. In no event shall Distributed Processing Technology be
+ * liable for any direct, indirect, incidental, special, exemplary or
+ * consequential damages (including, but not limited to, procurement of
+ * substitute goods or services; loss of use, data, or profits; or business
+ * interruptions) however caused and on any theory of liability, whether in
+ * contract, strict liability, or tort (including negligence or otherwise)
+ * arising in any way out of the use of this driver software, even if advised
+ * of the possibility of such damage.
+ *
+ */
+
+#ifndef         __SYS_INFO_H
+#define         __SYS_INFO_H
+
+/*File - SYS_INFO.H
+ ****************************************************************************
+ *
+ *Description:
+ *
+ *      This file contains structure definitions for the OS dependent
+ *layer system information buffers.
+ *
+ *Copyright Distributed Processing Technology, Corp.
+ *        140 Candace Dr.
+ *        Maitland, Fl. 32751   USA
+ *        Phone: (407) 830-5522  Fax: (407) 260-5366
+ *        All Rights Reserved
+ *
+ *Author:       Don Kemper
+ *Date:         5/10/94
+ *
+ *Editors:
+ *
+ *Remarks:
+ *
+ *
+ *****************************************************************************/
+
+
+/*Include Files ------------------------------------------------------------- */
+
+#include        "osd_util.h"
+
+#ifndef NO_PACK
+#if defined (_DPT_AIX)
+#pragma options align=packed
+#else
+#pragma pack(1)
+#endif  /* aix */
+#endif  // no unpack
+
+
+/*struct - driveParam_S - start
+ *===========================================================================
+ *
+ *Description:
+ *
+ *      This structure defines the drive parameters seen during
+ *booting.
+ *
+ *---------------------------------------------------------------------------*/
+
+#ifdef  __cplusplus
+   struct driveParam_S {
+#else
+   typedef struct  {
+#endif
+
+   uSHORT       cylinders;      /* Upto 1024 */
+   uCHAR        heads;          /* Upto 255 */
+   uCHAR        sectors;        /* Upto 63 */
+
+#ifdef  __cplusplus
+
+//---------- Portability Additions ----------- in sp_sinfo.cpp
+#ifdef DPT_PORTABLE
+       uSHORT          netInsert(dptBuffer_S *buffer);
+       uSHORT          netExtract(dptBuffer_S *buffer);
+#endif // DPT PORTABLE
+//--------------------------------------------
+
+   };
+#else
+   } driveParam_S;
+#endif
+/*driveParam_S - end */
+
+
+/*struct - sysInfo_S - start
+ *===========================================================================
+ *
+ *Description:
+ *
+ *      This structure defines the command system information that
+ *should be returned by every OS dependent layer.
+ *
+ *---------------------------------------------------------------------------*/
+
+/*flags - bit definitions */
+#define SI_CMOS_Valid           0x0001
+#define SI_NumDrivesValid       0x0002
+#define SI_ProcessorValid       0x0004
+#define SI_MemorySizeValid      0x0008
+#define SI_DriveParamsValid     0x0010
+#define SI_SmartROMverValid     0x0020
+#define SI_OSversionValid       0x0040
+#define SI_OSspecificValid      0x0080  /* 1 if OS structure returned */
+#define SI_BusTypeValid         0x0100
+
+#define SI_ALL_VALID            0x0FFF  /* All Std SysInfo is valid */
+#define SI_NO_SmartROM          0x8000
+
+/*busType - definitions */
+#define SI_ISA_BUS      0x00
+#define SI_MCA_BUS      0x01
+#define SI_EISA_BUS     0x02
+#define SI_PCI_BUS      0x04
+
+#ifdef  __cplusplus
+   struct sysInfo_S {
+#else
+   typedef struct  {
+#endif
+
+   uCHAR        drive0CMOS;             /* CMOS Drive 0 Type */
+   uCHAR        drive1CMOS;             /* CMOS Drive 1 Type */
+   uCHAR        numDrives;              /* 0040:0075 contents */
+   uCHAR        processorFamily;        /* Same as DPTSIG's definition */
+   uCHAR        processorType;          /* Same as DPTSIG's definition */
+   uCHAR        smartROMMajorVersion;
+   uCHAR        smartROMMinorVersion;   /* SmartROM version */
+   uCHAR        smartROMRevision;
+   uSHORT       flags;                  /* See bit definitions above */
+   uSHORT       conventionalMemSize;    /* in KB */
+   uLONG        extendedMemSize;        /* in KB */
+   uLONG        osType;                 /* Same as DPTSIG's definition */
+   uCHAR        osMajorVersion;
+   uCHAR        osMinorVersion;         /* The OS version */
+   uCHAR        osRevision;
+#ifdef _SINIX_ADDON
+   uCHAR        busType;                /* See defininitions above */
+   uSHORT       osSubRevision;
+   uCHAR        pad[2];                 /* For alignment */
+#else
+   uCHAR        osSubRevision;
+   uCHAR        busType;                /* See defininitions above */
+   uCHAR        pad[3];                 /* For alignment */
+#endif
+   driveParam_S drives[16];             /* SmartROM Logical Drives */
+
+#ifdef  __cplusplus
+
+//---------- Portability Additions ----------- in sp_sinfo.cpp
+#ifdef DPT_PORTABLE
+       uSHORT          netInsert(dptBuffer_S *buffer);
+       uSHORT          netExtract(dptBuffer_S *buffer);
+#endif // DPT PORTABLE
+//--------------------------------------------
+
+   };
+#else
+   } sysInfo_S;
+#endif
+/*sysInfo_S - end */
+
+
+/*struct - DOS_Info_S - start
+ *===========================================================================
+ *
+ *Description:
+ *
+ *      This structure defines the system information specific to a
+ *DOS workstation.
+ *
+ *---------------------------------------------------------------------------*/
+
+/*flags - bit definitions */
+#define DI_DOS_HIGH             0x01    /* DOS is loaded high */
+#define DI_DPMI_VALID           0x02    /* DPMI version is valid */
+
+#ifdef  __cplusplus
+   struct DOS_Info_S {
+#else
+   typedef struct {
+#endif
+
+   uCHAR        flags;          /* See bit definitions above */
+   uSHORT       driverLocation; /* SmartROM BIOS address */
+   uSHORT       DOS_version;
+   uSHORT       DPMI_version;
+
+#ifdef  __cplusplus
+
+//---------- Portability Additions ----------- in sp_sinfo.cpp
+#ifdef DPT_PORTABLE
+       uSHORT          netInsert(dptBuffer_S *buffer);
+       uSHORT          netExtract(dptBuffer_S *buffer);
+#endif // DPT PORTABLE
+//--------------------------------------------
+
+   };
+#else
+   } DOS_Info_S;
+#endif
+/*DOS_Info_S - end */
+
+
+/*struct - Netware_Info_S - start
+ *===========================================================================
+ *
+ *Description:
+ *
+ *      This structure defines the system information specific to a
+ *Netware machine.
+ *
+ *---------------------------------------------------------------------------*/
+
+#ifdef  __cplusplus
+   struct Netware_Info_S {
+#else
+   typedef struct {
+#endif
+
+   uCHAR        driverName[13];         /* ie PM12NW31.DSK */
+   uCHAR        serverName[48];
+   uCHAR        netwareVersion;         /* The Netware OS version */
+   uCHAR        netwareSubVersion;
+   uCHAR        netwareRevision;
+   uSHORT       maxConnections;         /* Probably  250 or 1000 */
+   uSHORT       connectionsInUse;
+   uSHORT       maxVolumes;
+   uCHAR        unused;
+   uCHAR        SFTlevel;
+   uCHAR        TTSlevel;
+
+   uCHAR        clibMajorVersion;       /* The CLIB.NLM version */
+   uCHAR        clibMinorVersion;
+   uCHAR        clibRevision;
+
+#ifdef  __cplusplus
+
+//---------- Portability Additions ----------- in sp_sinfo.cpp
+#ifdef DPT_PORTABLE
+       uSHORT          netInsert(dptBuffer_S *buffer);
+       uSHORT          netExtract(dptBuffer_S *buffer);
+#endif // DPT PORTABLE
+//--------------------------------------------
+
+   };
+#else
+   } Netware_Info_S;
+#endif
+/*Netware_Info_S - end */
+
+
+/*struct - OS2_Info_S - start
+ *===========================================================================
+ *
+ *Description:
+ *
+ *      This structure defines the system information specific to an
+ *OS/2 machine.
+ *
+ *---------------------------------------------------------------------------*/
+
+#ifdef  __cplusplus
+   struct OS2_Info_S {
+#else
+   typedef struct {
+#endif
+
+   uCHAR        something;
+
+#ifdef  __cplusplus
+
+//---------- Portability Additions ----------- in sp_sinfo.cpp
+#ifdef DPT_PORTABLE
+       uSHORT          netInsert(dptBuffer_S *buffer);
+       uSHORT          netExtract(dptBuffer_S *buffer);
+#endif // DPT PORTABLE
+//--------------------------------------------
+
+   };
+#else
+   } OS2_Info_S;
+#endif
+/*OS2_Info_S - end */
+
+
+/*struct - WinNT_Info_S - start
+ *===========================================================================
+ *
+ *Description:
+ *
+ *      This structure defines the system information specific to a
+ *Windows NT machine.
+ *
+ *---------------------------------------------------------------------------*/
+
+#ifdef  __cplusplus
+   struct WinNT_Info_S {
+#else
+   typedef struct {
+#endif
+
+   uCHAR        something;
+
+#ifdef  __cplusplus
+
+//---------- Portability Additions ----------- in sp_sinfo.cpp
+#ifdef DPT_PORTABLE
+       uSHORT          netInsert(dptBuffer_S *buffer);
+       uSHORT          netExtract(dptBuffer_S *buffer);
+#endif // DPT PORTABLE
+//--------------------------------------------
+
+   };
+#else
+   } WinNT_Info_S;
+#endif
+/*WinNT_Info_S - end */
+
+
+/*struct - SCO_Info_S - start
+ *===========================================================================
+ *
+ *Description:
+ *
+ *      This structure defines the system information specific to an
+ *SCO UNIX machine.
+ *
+ *---------------------------------------------------------------------------*/
+
+#ifdef  __cplusplus
+   struct SCO_Info_S {
+#else
+   typedef struct {
+#endif
+
+   uCHAR        something;
+
+#ifdef  __cplusplus
+
+//---------- Portability Additions ----------- in sp_sinfo.cpp
+#ifdef DPT_PORTABLE
+       uSHORT          netInsert(dptBuffer_S *buffer);
+       uSHORT          netExtract(dptBuffer_S *buffer);
+#endif // DPT PORTABLE
+//--------------------------------------------
+
+   };
+#else
+   } SCO_Info_S;
+#endif
+/*SCO_Info_S - end */
+
+
+/*struct - USL_Info_S - start
+ *===========================================================================
+ *
+ *Description:
+ *
+ *      This structure defines the system information specific to a
+ *USL UNIX machine.
+ *
+ *---------------------------------------------------------------------------*/
+
+#ifdef  __cplusplus
+   struct USL_Info_S {
+#else
+   typedef struct {
+#endif
+
+   uCHAR        something;
+
+#ifdef  __cplusplus
+
+//---------- Portability Additions ----------- in sp_sinfo.cpp
+#ifdef DPT_PORTABLE
+       uSHORT          netInsert(dptBuffer_S *buffer);
+       uSHORT          netExtract(dptBuffer_S *buffer);
+#endif // DPT PORTABLE
+//--------------------------------------------
+
+   };
+#else
+   } USL_Info_S;
+#endif
+/*USL_Info_S - end */
+
+
+  /* Restore default structure packing */
+#ifndef NO_UNPACK
+#if defined (_DPT_AIX)
+#pragma options align=reset
+#elif defined (UNPACK_FOUR)
+#pragma pack(4)
+#else
+#pragma pack()
+#endif  /* aix */
+#endif  // no unpack
+
+#endif  // __SYS_INFO_H
+
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
new file mode 100644 (file)
index 0000000..ddf8c95
--- /dev/null
@@ -0,0 +1,3323 @@
+/***************************************************************************
+                          dpti.c  -  description
+                             -------------------
+    begin                : Thu Sep 7 2000
+    copyright            : (C) 2000 by Adaptec
+    email                : deanna_bonds@adaptec.com
+
+                          July 30, 2001 First version being submitted
+                          for inclusion in the kernel.  V2.4
+
+    See README.dpti for history, notes, license info, and credits
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   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.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+//#define DEBUG 1
+//#define UARTDELAY 1
+
+// On the real kernel ADDR32 should always be zero for 2.4. GFP_HIGH allocates
+// high pages. Keep the macro around because of the broken unmerged ia64 tree
+
+#define ADDR32 (0)
+
+#include <linux/version.h>
+#include <linux/module.h>
+
+MODULE_AUTHOR("Deanna Bonds, with _lots_ of help from Mark Salyzyn");
+MODULE_DESCRIPTION("Adaptec I2O RAID Driver");
+
+////////////////////////////////////////////////////////////////
+
+#include <linux/ioctl.h>       /* For SCSI-Passthrough */
+#include <asm/uaccess.h>
+
+#include <linux/stat.h>
+#include <linux/slab.h>                /* for kmalloc() */
+#include <linux/config.h>      /* for CONFIG_PCI */
+#include <linux/pci.h>         /* for PCI support */
+#include <linux/proc_fs.h>
+#include <linux/blk.h>
+#include <linux/delay.h>       /* for udelay */
+#include <linux/tqueue.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>      /* for printk */
+#include <linux/sched.h>
+#include <linux/reboot.h>
+#include <linux/smp_lock.h>
+
+#include <linux/timer.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/stat.h>
+
+#include <asm/processor.h>     /* for boot_cpu_data */
+#include <asm/pgtable.h>
+#include <asm/io.h>            /* for virt_to_bus, etc. */
+
+#include "scsi.h"
+#include "hosts.h"
+#include "sd.h"
+
+#include "dpt/dptsig.h"
+#include "dpti.h"
+
+/*============================================================================
+ * Create a binary signature - this is read by dptsig
+ * Needed for our management apps
+ *============================================================================
+ */
+static dpt_sig_S DPTI_sig = {
+       {'d', 'P', 't', 'S', 'i', 'G'}, SIG_VERSION,
+#ifdef __i386__
+       PROC_INTEL, PROC_386 | PROC_486 | PROC_PENTIUM | PROC_SEXIUM,
+#elif defined __ia64__
+       PROC_INTEL, PROC_IA64,
+#elif define __sparc__
+       PROC_ULTRASPARC,
+#elif defined(__alpha__)
+       PROC_ALPHA ,
+#else
+       (-1),
+#endif
+        FT_HBADRVR, 0, OEM_DPT, OS_LINUX, CAP_OVERLAP, DEV_ALL,
+       ADF_ALL_SC5, 0, 0, DPT_VERSION, DPT_REVISION, DPT_SUBREVISION,
+       DPT_MONTH, DPT_DAY, DPT_YEAR, "Adaptec Linux I2O RAID Driver"
+};
+
+
+
+
+/*============================================================================
+ * Globals
+ *============================================================================
+ */
+
+DECLARE_MUTEX(adpt_configuration_lock);
+
+static struct i2o_sys_tbl *sys_tbl = NULL;
+static int sys_tbl_ind = 0;
+static int sys_tbl_len = 0;
+
+static adpt_hba* hbas[DPTI_MAX_HBA];
+static adpt_hba* hba_chain = NULL;
+static int hba_count = 0;
+
+// Debug flags to be put into the HBA flags field when initialized
+// Make sure to enable DEBUG_PRINT for these flags to work
+static unsigned long DebugFlags = HBA_FLAGS_DBG_SCAN_B | HBA_FLAGS_DBG_FLAGS_MASK;
+
+static struct file_operations adpt_fops = {
+       ioctl: adpt_ioctl,
+       open: adpt_open,
+       release: adpt_close
+};
+
+#ifdef REBOOT_NOTIFIER
+static struct notifier_block adpt_reboot_notifier =
+{
+        adpt_reboot_event,
+        NULL,
+        0
+};
+#endif
+
+/* Structures and definitions for synchronous message posting.
+ * See adpt_i2o_post_wait() for description
+ * */
+struct adpt_i2o_post_wait_data
+{
+       int status;
+       u32 id;
+       adpt_wait_queue_head_t *wq;
+       struct adpt_i2o_post_wait_data *next;
+};
+
+static struct adpt_i2o_post_wait_data *adpt_post_wait_queue = NULL;
+static u32 adpt_post_wait_id = 0;
+static spinlock_t adpt_post_wait_lock = SPIN_LOCK_UNLOCKED;
+
+
+/*============================================================================
+ *                             Functions
+ *============================================================================
+ */
+
+static u8 adpt_read_blink_led(adpt_hba* host)
+{
+       if(host->FwDebugBLEDflag_P != 0) {
+               if( readb(host->FwDebugBLEDflag_P) == 0xbc ){
+                       return readb(host->FwDebugBLEDvalue_P);
+               }
+       }
+       return 0;
+}
+
+/*============================================================================
+ * Scsi host template interface functions
+ *============================================================================
+ */
+
+static int adpt_detect(Scsi_Host_Template* sht)
+{
+       struct pci_dev *pDev = NULL;
+       adpt_hba* pHba;
+
+       adpt_init();
+       sht->use_new_eh_code = 1;
+
+       PINFO("Detecting Adaptec I2O RAID controllers...\n");
+
+        /* search for all Adatpec I2O RAID cards */
+       while ((pDev = pci_find_device( PCI_DPT_VENDOR_ID, PCI_ANY_ID, pDev))) {
+               if(pDev->device == PCI_DPT_DEVICE_ID ||
+                  pDev->device == PCI_DPT_RAPTOR_DEVICE_ID){
+                       if(adpt_install_hba(sht, pDev) ){
+                               PERROR("Could not Init an I2O RAID device\n");
+                               PERROR("Will not try to detect others.\n");
+                               return hba_count-1;
+                       }
+               }
+       }
+
+       /* In INIT state, Activate IOPs */
+       for (pHba = hba_chain; pHba; pHba = pHba->next) {
+               // Activate does get status , init outbound, and get hrt
+               if (adpt_i2o_activate_hba(pHba) < 0) {
+                       adpt_i2o_delete_hba(pHba);
+               }
+       }
+
+
+       /* Active IOPs in HOLD state */
+
+rebuild_sys_tab:
+       if (hba_chain == NULL) 
+               return 0;
+
+       /*
+        * If build_sys_table fails, we kill everything and bail
+        * as we can't init the IOPs w/o a system table
+        */     
+       if (adpt_i2o_build_sys_table() < 0) {
+               adpt_i2o_sys_shutdown();
+               return 0;
+       }
+
+       PDEBUG("HBA's in HOLD state\n");
+
+       /* If IOP don't get online, we need to rebuild the System table */
+       for (pHba = hba_chain; pHba; pHba = pHba->next) {
+               if (adpt_i2o_online_hba(pHba) < 0) {
+                       adpt_i2o_delete_hba(pHba);      
+                       goto rebuild_sys_tab;
+               }
+       }
+
+       /* Active IOPs now in OPERATIONAL state */
+       PDEBUG("HBA's in OPERATIONAL state\n");
+
+       printk(KERN_INFO"dpti: If you have a lot of devices this could take a few minutes.\n");
+       for (pHba = hba_chain; pHba; pHba = pHba->next) {
+               printk(KERN_INFO"%s: Reading the hardware resource table.\n", pHba->name);
+               if (adpt_i2o_lct_get(pHba) < 0){
+                       adpt_i2o_delete_hba(pHba);
+                       continue;
+               }
+
+               if (adpt_i2o_parse_lct(pHba) < 0){
+                       adpt_i2o_delete_hba(pHba);
+                       continue;
+               }
+               adpt_inquiry(pHba);
+       }
+
+       for (pHba = hba_chain; pHba; pHba = pHba->next) {
+               if( adpt_scsi_register(pHba,sht) < 0){
+                       adpt_i2o_delete_hba(pHba);
+                       continue;
+               }
+               pHba->initialized = TRUE;
+               pHba->state &= ~DPTI_STATE_RESET;
+       }
+
+       // Register our control device node
+       // nodes will need to be created in /dev to access this
+       // the nodes can not be created from within the driver
+       if (hba_count && register_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER, &adpt_fops)) {
+               adpt_i2o_sys_shutdown();
+               return 0;
+       }
+       return hba_count;
+}
+
+
+/*
+ * scsi_unregister will be called AFTER we return. 
+ */
+static int adpt_release(struct Scsi_Host *host)
+{
+       adpt_hba* pHba = (adpt_hba*) host->hostdata[0];
+//     adpt_i2o_quiesce_hba(pHba);
+       adpt_i2o_delete_hba(pHba);
+       return 0;
+}
+
+
+static void adpt_inquiry(adpt_hba* pHba)
+{
+       u32 msg[14]; 
+       u32 *mptr;
+       u32 *lenptr;
+       int direction;
+       int scsidir;
+       u32 len;
+       u32 reqlen;
+       u8* buf;
+       u8  scb[16];
+       s32 rcode;
+
+       memset(msg, 0, sizeof(msg));
+       buf = (u8*)kmalloc(80,GFP_KERNEL|ADDR32);
+       if(!buf){
+               printk(KERN_ERR"%s: Could not allocate buffer\n",pHba->name);
+               return;
+       }
+       memset((void*)buf, 0, 36);
+       
+       len = 36;
+       direction = 0x00000000; 
+       scsidir  =0x40000000;   // DATA IN  (iop<--dev)
+
+       reqlen = 14;            // SINGLE SGE
+       /* Stick the headers on */
+       msg[0] = reqlen<<16 | SGL_OFFSET_12;
+       msg[1] = (0xff<<24|HOST_TID<<12|ADAPTER_TID);
+       msg[2] = 0;
+       msg[3]  = 0;
+       // Adaptec/DPT Private stuff 
+       msg[4] = I2O_CMD_SCSI_EXEC|DPT_ORGANIZATION_ID<<16;
+       msg[5] = ADAPTER_TID | 1<<16 /* Interpret*/;
+       /* Direction, disconnect ok | sense data | simple queue , CDBLen */
+       // I2O_SCB_FLAG_ENABLE_DISCONNECT | 
+       // I2O_SCB_FLAG_SIMPLE_QUEUE_TAG | 
+       // I2O_SCB_FLAG_SENSE_DATA_IN_MESSAGE;
+       msg[6] = scsidir|0x20a00000| 6 /* cmd len*/;
+
+       mptr=msg+7;
+
+       memset(scb, 0, sizeof(scb));
+       // Write SCSI command into the message - always 16 byte block 
+       scb[0] = INQUIRY;
+       scb[1] = 0;
+       scb[2] = 0;
+       scb[3] = 0;
+       scb[4] = 36;
+       scb[5] = 0;
+       // Don't care about the rest of scb
+
+       memcpy(mptr, scb, sizeof(scb));
+       mptr+=4;
+       lenptr=mptr++;          /* Remember me - fill in when we know */
+
+       /* Now fill in the SGList and command */
+       *lenptr = len;
+       *mptr++ = 0xD0000000|direction|len;
+       *mptr++ = virt_to_bus(buf);
+
+       // Send it on it's way
+       rcode = adpt_i2o_post_wait(pHba, msg, reqlen<<2, 120);
+       if (rcode != 0) {
+               sprintf(pHba->detail, "Adaptec I2O RAID");
+               printk(KERN_INFO "%s: Inquiry Error (%d)\n",pHba->name,rcode);
+       } else {
+               memset(pHba->detail, 0, sizeof(pHba->detail));
+               memcpy(&(pHba->detail), "Vendor: Adaptec ", 16);
+               memcpy(&(pHba->detail[16]), " Model: ", 8);
+               memcpy(&(pHba->detail[24]), (u8*) &buf[16], 16);
+               memcpy(&(pHba->detail[40]), " FW: ", 4);
+               memcpy(&(pHba->detail[44]), (u8*) &buf[32], 4);
+               pHba->detail[48] = '\0';        /* precautionary */
+       }
+       kfree(buf);
+       adpt_i2o_status_get(pHba);
+       return ;
+}
+
+
+static void adpt_select_queue_depths(struct Scsi_Host *host, Scsi_Device * devicelist)
+{
+       Scsi_Device *device;    /* scsi layer per device information */
+       adpt_hba* pHba;
+
+       pHba = (adpt_hba *) host->hostdata[0];
+
+       for (device = devicelist; device != NULL; device = device->next) {
+               if (device->host != host) {
+                       continue;
+               }
+               if (host->can_queue) {
+                       device->queue_depth =  host->can_queue - 1;
+               } else {
+                       device->queue_depth = 1;
+               }
+       }
+}
+
+static int adpt_queue(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
+{
+       adpt_hba* pHba = NULL;
+       struct adpt_device* pDev = NULL;        /* dpt per device information */
+       ulong timeout = jiffies + (TMOUT_SCSI*HZ);
+
+       cmd->scsi_done = done;
+       /*
+        * SCSI REQUEST_SENSE commands will be executed automatically by the 
+        * Host Adapter for any errors, so they should not be executed 
+        * explicitly unless the Sense Data is zero indicating that no error 
+        * occurred.
+        */
+
+       if ((cmd->cmnd[0] == REQUEST_SENSE) && (cmd->sense_buffer[0] != 0)) {
+               cmd->result = (DID_OK << 16);
+               cmd->scsi_done(cmd);
+               return 0;
+       }
+
+       pHba = (adpt_hba*)cmd->host->hostdata[0];
+       if (!pHba) {
+               return FAILED;
+       }
+
+       rmb();
+       /*
+        * TODO: I need to block here if I am processing ioctl cmds
+        * but if the outstanding cmds all finish before the ioctl,
+        * the scsi-core will not know to start sending cmds to me again.
+        * I need to a way to restart the scsi-cores queues or should I block
+        * calling scsi_done on the outstanding cmds instead
+        * for now we don't set the IOCTL state
+        */
+       if(((pHba->state) & DPTI_STATE_IOCTL) || ((pHba->state) & DPTI_STATE_RESET)) {
+               pHba->host->last_reset = jiffies;
+               pHba->host->resetting = 1;
+               return 1;
+       }
+
+       if(cmd->eh_state != SCSI_STATE_QUEUED){
+               // If we are not doing error recovery
+               mod_timer(&cmd->eh_timeout, timeout);
+       }
+
+       // TODO if the cmd->device if offline then I may need to issue a bus rescan
+       // followed by a get_lct to see if the device is there anymore
+       if((pDev = (struct adpt_device*) (cmd->device->hostdata)) == NULL) {
+               /*
+                * First command request for this device.  Set up a pointer
+                * to the device structure.  This should be a TEST_UNIT_READY
+                * command from scan_scsis_single.
+                */
+               if ((pDev = adpt_find_device(pHba, (u32)cmd->channel, (u32)cmd->target, (u32)cmd-> lun)) == NULL) {
+                       // TODO: if any luns are at this bus, scsi id then fake a TEST_UNIT_READY and INQUIRY response 
+                       // with type 7F (for all luns less than the max for this bus,id) so the lun scan will continue.
+                       cmd->result = (DID_NO_CONNECT << 16);
+                       cmd->scsi_done(cmd);
+                       return 0;
+               }
+               (struct adpt_device*)(cmd->device->hostdata) = pDev;
+       }
+       pDev->pScsi_dev = cmd->device;
+
+       /*
+        * If we are being called from when the device is being reset, 
+        * delay processing of the command until later.
+        */
+       if (pDev->state & DPTI_DEV_RESET ) {
+               return FAILED;
+       }
+       return adpt_scsi_to_i2o(pHba, cmd, pDev);
+}
+
+static int adpt_bios_param(Disk* disk, kdev_t dev, int geom[])
+{
+       int heads=-1;
+       int sectors=-1;
+       int cylinders=-1;
+
+       // *** First lets set the default geometry ****
+       
+       // If the capacity is less than ox2000
+       if (disk->capacity < 0x2000 ) { // floppy
+               heads = 18;
+               sectors = 2;
+       } 
+       // else if between 0x2000 and 0x20000
+       else if (disk->capacity < 0x20000) {
+               heads = 64;
+               sectors = 32;
+       }
+       // else if between 0x20000 and 0x40000
+       else if (disk->capacity < 0x40000) {
+               heads = 65;
+               sectors = 63;
+       }
+       // else if between 0x4000 and 0x80000
+       else if (disk->capacity < 0x80000) {
+               heads = 128;
+               sectors = 63;
+       }
+       // else if greater than 0x80000
+       else {
+               heads = 255;
+               sectors = 63;
+       }
+       cylinders = disk->capacity / (heads * sectors);
+
+       // Special case if CDROM
+       if(disk->device->type == 5) {  // CDROM
+               heads = 252;
+               sectors = 63;
+               cylinders = 1111;
+       }
+
+       geom[0] = heads;
+       geom[1] = sectors;
+       geom[2] = cylinders;
+       
+       PDEBUG("adpt_bios_param: exit\n");
+       return 0;
+}
+
+
+static const char *adpt_info(struct Scsi_Host *host)
+{
+       adpt_hba* pHba;
+
+       pHba = (adpt_hba *) host->hostdata[0];
+       return (char *) (pHba->detail);
+}
+
+static int adpt_proc_info(char *buffer, char **start, off_t offset,
+                 int length, int hostno, int inout)
+{
+       struct adpt_device* d;
+       int id;
+       int chan;
+       int len = 0;
+       int begin = 0;
+       int pos = 0;
+       adpt_hba* pHba;
+       struct Scsi_Host *host;
+       int unit;
+
+       *start = buffer;
+       if (inout == TRUE) {
+               /*
+                * The user has done a write and wants us to take the
+                * data in the buffer and do something with it.
+                * proc_scsiwrite calls us with inout = 1
+                *
+                * Read data from buffer (writing to us) - NOT SUPPORTED
+                */
+               return -EINVAL;
+       }
+
+       /*
+        * inout = 0 means the user has done a read and wants information
+        * returned, so we write information about the cards into the buffer
+        * proc_scsiread() calls us with inout = 0
+        */
+
+       // Find HBA (host bus adapter) we are looking for
+       down(&adpt_configuration_lock);
+       for (pHba = hba_chain; pHba; pHba = pHba->next) {
+               if (pHba->host->host_no == hostno) {
+                       break;  /* found adapter */
+               }
+       }
+       up(&adpt_configuration_lock);
+       if (pHba == NULL) {
+               return 0;
+       }
+       host = pHba->host;
+
+       len  = sprintf(buffer    , "Adaptec I2O RAID Driver Version: %s\n\n", DPT_I2O_VERSION);
+       len += sprintf(buffer+len, "%s\n", pHba->detail);
+       len += sprintf(buffer+len, "SCSI Host=scsi%d  Control Node=/dev/%s  irq=%d\n", 
+                       pHba->host->host_no, pHba->name, host->irq);
+       len += sprintf(buffer+len, "\tpost fifo size  = %d\n\treply fifo size = %d\n\tsg table size   = %d\n\n",
+                       host->can_queue, (int) pHba->reply_fifo_size , host->sg_tablesize);
+
+       pos = begin + len;
+
+       /* CHECKPOINT */
+       if(pos > offset + length) {
+               goto stop_output;
+       }
+       if(pos <= offset) {
+               /*
+                * If we haven't even written to where we last left
+                * off (the last time we were called), reset the 
+                * beginning pointer.
+                */
+               len = 0;
+               begin = pos;
+       }
+       len +=  sprintf(buffer+len, "Devices:\n");
+       for(chan = 0; chan < MAX_CHANNEL; chan++) {
+               for(id = 0; id < MAX_ID; id++) {
+                       d = pHba->channel[chan].device[id];
+                       while(d){
+                               len += sprintf(buffer+len,"\t%-24.24s", d->pScsi_dev->vendor);
+                               len += sprintf(buffer+len," Rev: %-8.8s\n", d->pScsi_dev->rev);
+                               pos = begin + len;
+
+
+                               /* CHECKPOINT */
+                               if(pos > offset + length) {
+                                       goto stop_output;
+                               }
+                               if(pos <= offset) {
+                                       len = 0;
+                                       begin = pos;
+                               }
+
+                               unit = d->pI2o_dev->lct_data.tid;
+                               len += sprintf(buffer+len, "\tTID=%d, (Channel=%d, Target=%d, Lun=%d)  (%s)\n\n",
+                                              unit, (int)d->scsi_channel, (int)d->scsi_id, (int)d->scsi_lun,
+                                              d->pScsi_dev->online? "online":"offline"); 
+                               pos = begin + len;
+
+                               /* CHECKPOINT */
+                               if(pos > offset + length) {
+                                       goto stop_output;
+                               }
+                               if(pos <= offset) {
+                                       len = 0;
+                                       begin = pos;
+                               }
+
+                               d = d->next_lun;
+                       }
+               }
+       }
+
+       /*
+        * begin is where we last checked our position with regards to offset
+        * begin is always less than offset.  len is relative to begin.  It
+        * is the number of bytes written past begin
+        *
+        */
+stop_output:
+       /* stop the output and calculate the correct length */
+       *(buffer + len) = '\0';
+
+       *start = buffer + (offset - begin);     /* Start of wanted data */
+       len -= (offset - begin);
+       if(len > length) {
+               len = length;
+       } else if(len < 0){
+               len = 0;
+               **start = '\0';
+       }
+       return len;
+}
+
+
+/*===========================================================================
+ * Error Handling routines
+ *===========================================================================
+ */
+
+static int adpt_abort(Scsi_Cmnd * cmd)
+{
+       adpt_hba* pHba = NULL;  /* host bus adapter structure */
+       struct adpt_device* dptdevice;  /* dpt per device information */
+       u32 msg[5];
+       int rcode;
+
+       if(cmd->serial_number == 0){
+               return FAILED;
+       }
+       pHba = (adpt_hba*) cmd->host->hostdata[0];
+       printk(KERN_INFO"%s: Trying to Abort cmd=%ld\n",pHba->name, cmd->serial_number);
+       if ((dptdevice = (void*) (cmd->device->hostdata)) == NULL) {
+               printk(KERN_ERR "%s: Unable to abort: No device in cmnd\n",pHba->name);
+               return FAILED;
+       }
+
+       memset(msg, 0, sizeof(msg));
+       msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
+       msg[1] = I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|dptdevice->tid;
+       msg[2] = 0;
+       msg[3]= 0; 
+       msg[4] = (u32)cmd;
+       if( (rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER)) != 0){
+               if(rcode == -EOPNOTSUPP ){
+                       printk(KERN_INFO"%s: Abort cmd not supported\n",pHba->name);
+                       return FAILED;
+               }
+               printk(KERN_INFO"%s: Abort cmd=%ld failed.\n",pHba->name, cmd->serial_number);
+               return FAILED;
+       } 
+       printk(KERN_INFO"%s: Abort cmd=%ld complete.\n",pHba->name, cmd->serial_number);
+       return SUCCESS;
+}
+
+
+#define I2O_DEVICE_RESET 0x27
+// This is the same for BLK and SCSI devices
+// NOTE this is wrong in the i2o.h definitions
+// This is not currently supported by our adapter but we issue it anyway
+static int adpt_device_reset(Scsi_Cmnd* cmd)
+{
+       adpt_hba* pHba;
+       u32 msg[4];
+       u32 rcode;
+       int old_state;
+       struct adpt_device* d = (void*) cmd->device->hostdata;
+
+       pHba = (void*) cmd->host->hostdata[0];
+       printk(KERN_INFO"%s: Trying to reset device\n",pHba->name);
+       if (!d) {
+               printk(KERN_INFO"%s: Reset Device: Device Not found\n",pHba->name);
+               return FAILED;
+       }
+       memset(msg, 0, sizeof(msg));
+       msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
+       msg[1] = (I2O_DEVICE_RESET<<24|HOST_TID<<12|d->tid);
+       msg[2] = 0;
+       msg[3] = 0;
+
+       old_state = d->state;
+       d->state |= DPTI_DEV_RESET;
+       if( (rcode = adpt_i2o_post_wait(pHba, (void*)msg,sizeof(msg), FOREVER)) ){
+               d->state = old_state;
+               if(rcode == -EOPNOTSUPP ){
+                       printk(KERN_INFO"%s: Device reset not supported\n",pHba->name);
+                       return FAILED;
+               }
+               printk(KERN_INFO"%s: Device reset failed\n",pHba->name);
+               return FAILED;
+       } else {
+               d->state = old_state;
+               printk(KERN_INFO"%s: Device reset successful\n",pHba->name);
+               return SUCCESS;
+       }
+}
+
+
+#define I2O_HBA_BUS_RESET 0x87
+// This version of bus reset is called by the eh_error handler
+static int adpt_bus_reset(Scsi_Cmnd* cmd)
+{
+       adpt_hba* pHba;
+       u32 msg[4];
+
+       pHba = (adpt_hba*)cmd->host->hostdata[0];
+       memset(msg, 0, sizeof(msg));
+       printk(KERN_WARNING"%s: Bus reset: SCSI Bus %d: tid: %d\n",pHba->name, cmd->channel,pHba->channel[cmd->channel].tid );
+       msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
+       msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->channel].tid);
+       msg[2] = 0;
+       msg[3] = 0;
+       if(adpt_i2o_post_wait(pHba, (void*)msg,sizeof(msg), FOREVER) ){
+               printk(KERN_WARNING"%s: Bus reset failed.\n",pHba->name);
+               return FAILED;
+       } else {
+               printk(KERN_WARNING"%s: Bus reset success.\n",pHba->name);
+               return SUCCESS;
+       }
+}
+
+// This version of reset is called by the eh_error_handler
+static int adpt_reset(Scsi_Cmnd* cmd)
+{
+       adpt_hba* pHba;
+       int rcode;
+       pHba = (adpt_hba*)cmd->host->hostdata[0];
+       printk(KERN_WARNING"%s: Hba Reset: scsi id %d: tid: %d\n",pHba->name,cmd->channel,pHba->channel[cmd->channel].tid );
+       rcode =  adpt_hba_reset(pHba);
+       if(rcode == 0){
+               printk(KERN_WARNING"%s: HBA reset complete\n",pHba->name);
+               return SUCCESS;
+       } else {
+               printk(KERN_WARNING"%s: HBA reset failed (%x)\n",pHba->name, rcode);
+               return FAILED;
+       }
+}
+
+// This version of reset is called by the ioctls and indirectly from eh_error_handler via adpt_reset
+static int adpt_hba_reset(adpt_hba* pHba)
+{
+       int rcode;
+
+       pHba->state |= DPTI_STATE_RESET;
+
+       // Activate does get status , init outbound, and get hrt
+       if ((rcode=adpt_i2o_activate_hba(pHba)) < 0) {
+               printk(KERN_ERR "%s: Could not activate\n", pHba->name);
+               adpt_i2o_delete_hba(pHba);
+               return rcode;
+       }
+
+       if ((rcode=adpt_i2o_build_sys_table()) < 0) {
+               adpt_i2o_delete_hba(pHba);
+               return rcode;
+       }
+       PDEBUG("%s: in HOLD state\n",pHba->name);
+
+       if ((rcode=adpt_i2o_online_hba(pHba)) < 0) {
+               adpt_i2o_delete_hba(pHba);      
+               return rcode;
+       }
+       PDEBUG("%s: in OPERATIONAL state\n",pHba->name);
+
+       if ((rcode=adpt_i2o_lct_get(pHba)) < 0){
+               adpt_i2o_delete_hba(pHba);
+               return rcode;
+       }
+
+       if ((rcode=adpt_i2o_reparse_lct(pHba)) < 0){
+               adpt_i2o_delete_hba(pHba);
+               return rcode;
+       }
+       pHba->state &= ~DPTI_STATE_RESET;
+
+       adpt_fail_posted_scbs(pHba);
+       return 0;       /* return success */
+}
+
+/*===========================================================================
+ * 
+ *===========================================================================
+ */
+
+
+static void adpt_i2o_sys_shutdown(void)
+{
+       adpt_hba *pHba, *pNext;
+       struct adpt_i2o_post_wait_data *p1, *p2;
+
+        printk(KERN_INFO"Shutting down Adaptec I2O controllers.\n");
+        printk(KERN_INFO"   This could take a few minutes if there are many devices attached\n");
+       /* Delete all IOPs from the controller chain */
+       /* They should have already been released by the
+        * scsi-core
+        */
+       for (pHba = hba_chain; pHba; pHba = pNext) {
+               pNext = pHba->next;
+               adpt_i2o_delete_hba(pHba);
+       }
+
+       /* Remove any timedout entries from the wait queue.  */
+       p2 = NULL;
+//     spin_lock_irqsave(&adpt_post_wait_lock, flags);
+       /* Nothing should be outstanding at this point so just
+        * free them 
+        */
+       for(p1 = adpt_post_wait_queue; p1; p2 = p1, p1 = p2->next) {
+               kfree(p1);
+       }
+//     spin_unlock_irqrestore(&adpt_post_wait_lock, flags);
+       adpt_post_wait_queue = 0;
+
+        printk(KERN_INFO "Adaptec I2O controllers down.\n");
+}
+
+/*
+ * reboot/shutdown notification.
+ *
+ * - Quiesce each IOP in the system
+ *
+ */
+
+#ifdef REBOOT_NOTIFIER
+static int adpt_reboot_event(struct notifier_block *n, ulong code, void *p)
+{
+
+        if(code != SYS_RESTART && code != SYS_HALT && code != SYS_POWER_OFF)
+                 return NOTIFY_DONE;
+
+        adpt_i2o_sys_shutdown();
+
+        return NOTIFY_DONE;
+}
+#endif
+
+
+static int adpt_install_hba(Scsi_Host_Template* sht, struct pci_dev* pDev) 
+{
+
+       adpt_hba* pHba = NULL;
+       adpt_hba* p = NULL;
+       ulong base_addr0_phys = 0;
+       ulong base_addr1_phys = 0;
+       u32 hba_map0_area_size = 0;
+       u32 hba_map1_area_size = 0;
+       ulong base_addr_virt = 0;
+       ulong msg_addr_virt = 0;
+
+       int raptorFlag = FALSE;
+       int i;
+
+       if(pci_enable_device(pDev)) {
+               return -EINVAL;
+       }
+       pci_set_master(pDev);
+
+       base_addr0_phys = pci_resource_start(pDev,0);
+       hba_map0_area_size = pci_resource_len(pDev,0);
+
+       // Check if standard PCI card or single BAR Raptor
+       if(pDev->device == PCI_DPT_DEVICE_ID){
+               if(pDev->subsystem_device >=0xc032 && pDev->subsystem_device <= 0xc03b){
+                       // Raptor card with this device id needs 4M
+                       hba_map0_area_size = 0x400000;
+               } else { // Not Raptor - it is a PCI card
+                       if(hba_map0_area_size > 0x100000 ){ 
+                               hba_map0_area_size = 0x100000;
+                       }
+               }
+       } else {// Raptor split BAR config
+               // Use BAR1 in this configuration
+               base_addr1_phys = pci_resource_start(pDev,1);
+               hba_map1_area_size = pci_resource_len(pDev,1);
+               raptorFlag = TRUE;
+       }
+
+
+       base_addr_virt = (ulong)ioremap(base_addr0_phys,hba_map0_area_size);
+       if(base_addr_virt == 0) {
+               PERROR("dpti: adpt_config_hba: io remap failed\n");
+               return -EINVAL;
+       }
+
+        if(raptorFlag == TRUE) {
+               msg_addr_virt = (ulong)ioremap(base_addr1_phys, hba_map1_area_size );
+               if(msg_addr_virt == 0) {
+                       PERROR("dpti: adpt_config_hba: io remap failed on BAR1\n");
+                       iounmap((void*)base_addr_virt);
+                       return -EINVAL;
+               }
+       } else {
+               msg_addr_virt = base_addr_virt;
+       }
+       
+       // Allocate and zero the data structure
+       pHba = kmalloc(sizeof(adpt_hba), GFP_KERNEL);
+       if( pHba == NULL) {
+               if(msg_addr_virt != base_addr_virt){
+                       iounmap((void*)msg_addr_virt);
+               }
+               iounmap((void*)base_addr_virt);
+               return -ENOMEM;
+       }
+       memset(pHba, 0, sizeof(adpt_hba));
+
+       down(&adpt_configuration_lock);
+       for(i=0;i<DPTI_MAX_HBA;i++) {
+               if(hbas[i]==NULL) {
+                       hbas[i]=pHba;
+                       break;
+               }
+       }
+
+       if(hba_chain != NULL){
+               for(p = hba_chain; p->next; p = p->next);
+               p->next = pHba;
+       } else {
+               hba_chain = pHba;
+       }
+       pHba->next = NULL;
+       pHba->unit = hba_count;
+       sprintf(pHba->name, "dpti%d", i);
+       hba_count++;
+       
+       up(&adpt_configuration_lock);
+
+       pHba->pDev = pDev;
+       pHba->base_addr_phys = base_addr0_phys;
+
+       // Set up the Virtual Base Address of the I2O Device
+       pHba->base_addr_virt = base_addr_virt;
+       pHba->msg_addr_virt = msg_addr_virt;  
+       pHba->irq_mask = (ulong)(base_addr_virt+0x30);
+       pHba->post_port = (ulong)(base_addr_virt+0x40);
+       pHba->reply_port = (ulong)(base_addr_virt+0x44);
+
+       pHba->hrt = NULL;
+       pHba->lct = NULL;
+       pHba->lct_size = 0;
+       pHba->status_block = NULL;
+       pHba->post_count = 0;
+       pHba->state = DPTI_STATE_RESET;
+       pHba->pDev = pDev;
+       pHba->devices = NULL;
+
+       // Initializing the spinlocks
+       spin_lock_init(&pHba->state_lock);
+
+       if(raptorFlag == 0){
+               printk(KERN_INFO"Adaptec I2O RAID controller %d at %lx size=%x irq=%d\n", 
+                       hba_count-1, base_addr_virt, hba_map0_area_size, pDev->irq);
+       } else {
+               printk(KERN_INFO"Adaptec I2O RAID controller %d irq=%d\n",hba_count-1, pDev->irq);
+               printk(KERN_INFO"     BAR0 %lx - size= %x\n",base_addr_virt,hba_map0_area_size);
+               printk(KERN_INFO"     BAR1 %lx - size= %x\n",msg_addr_virt,hba_map1_area_size);
+       }
+
+       if (request_irq (pDev->irq, adpt_isr, SA_SHIRQ, pHba->name, pHba)) {
+               printk(KERN_ERR"%s: Couldn't register IRQ %d\n", pHba->name, pDev->irq);
+               adpt_i2o_delete_hba(pHba);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+
+static void adpt_i2o_delete_hba(adpt_hba* pHba)
+{
+       adpt_hba* p1;
+       adpt_hba* p2;
+       struct i2o_device* d;
+       struct i2o_device* next;
+       int i;
+       int j;
+       struct adpt_device* pDev;
+       struct adpt_device* pNext;
+
+
+       down(&adpt_configuration_lock);
+       // scsi_unregister calls our adpt_release which
+       // does a quiese
+       if(pHba->host){
+               free_irq(pHba->host->irq, pHba);
+       }
+       for(i=0;i<DPTI_MAX_HBA;i++) {
+               if(hbas[i]==pHba) {
+                       hbas[i] = NULL;
+               }
+       }
+       p2 = NULL;
+       for( p1 = hba_chain; p1; p2 = p1,p1=p1->next){
+               if(p1 == pHba) {
+                       if(p2) {
+                               p2->next = p1->next;
+                       } else {
+                               hba_chain = p1->next;
+                       }
+                       break;
+               }
+       }
+
+       hba_count--;
+       up(&adpt_configuration_lock);
+
+       iounmap((void*)pHba->base_addr_virt);
+       if(pHba->msg_addr_virt != pHba->base_addr_virt){
+               iounmap((void*)pHba->msg_addr_virt);
+       }
+       if(pHba->hrt) {
+               kfree(pHba->hrt);
+       }
+       if(pHba->lct){
+               kfree(pHba->lct);
+       }
+       if(pHba->status_block) {
+               kfree(pHba->status_block);
+       }
+       if(pHba->reply_pool){
+               kfree(pHba->reply_pool);
+       }
+
+       for(d = pHba->devices; d ; d = next){
+               next = d->next;
+               kfree(d);
+       }
+       for(i = 0 ; i < pHba->top_scsi_channel ; i++){
+               for(j = 0; j < MAX_ID; j++){
+                       if(pHba->channel[i].device[j] != NULL){
+                               for(pDev = pHba->channel[i].device[j]; pDev; pDev = pNext){
+                                       pNext = pDev->next_lun;
+                                       kfree(pDev);
+                               }
+                       }
+               }
+       }
+       kfree(pHba);
+
+       if(hba_count <= 0){
+               unregister_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER);   
+       }
+}
+
+
+static int adpt_init(void)
+{
+       int i;
+
+       printk(KERN_INFO"Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n");
+       for (i = 0; i < DPTI_MAX_HBA; i++) {
+               hbas[i] = NULL;
+       }
+#ifdef REBOOT_NOTIFIER
+       register_reboot_notifier(&adpt_reboot_notifier);
+#endif
+
+       return 0;
+}
+
+
+static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun)
+{
+       struct adpt_device* d;
+
+       if( pHba->channel[chan].device == NULL){
+               printk(KERN_DEBUG"Adaptec I2O RAID: Trying to find device before they are allocated\n");
+               return NULL;
+       }
+
+       d = pHba->channel[chan].device[id];
+       if(!d || d->tid == 0) {
+               return NULL;
+       }
+
+       /* If it is the only lun at that address then this should match*/
+       if(d->scsi_lun == lun){
+               return d;
+       }
+
+       /* else we need to look through all the luns */
+       for(d=d->next_lun ; d ; d = d->next_lun){
+               if(d->scsi_lun == lun){
+                       return d;
+               }
+       }
+       return NULL;
+}
+
+
+static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout)
+{
+       // I used my own version of the WAIT_QUEUE_HEAD
+       // to handle some version differences
+       // When embedded in the kernel this could go back to the vanilla one
+       ADPT_DECLARE_WAIT_QUEUE_HEAD(adpt_wq_i2o_post);
+       int status = 0;
+       ulong flags = 0;
+       struct adpt_i2o_post_wait_data *p1, *p2;
+       struct adpt_i2o_post_wait_data *wait_data =
+               kmalloc(sizeof(struct adpt_i2o_post_wait_data),GFP_KERNEL);
+       adpt_wait_queue_t wait;
+
+       if(!wait_data){
+               return -ENOMEM;
+       }
+       /*
+        * The spin locking is needed to keep anyone from playing
+        * with the queue pointers and id while we do the same
+        */
+       spin_lock_irqsave(&adpt_post_wait_lock, flags);
+       // TODO we need a MORE unique way of getting ids
+       // to support async LCT get
+       wait_data->next = adpt_post_wait_queue;
+       adpt_post_wait_queue = wait_data;
+       adpt_post_wait_id = (++adpt_post_wait_id & 0x7fff);
+       wait_data->id =  adpt_post_wait_id;
+       spin_unlock_irqrestore(&adpt_post_wait_lock, flags);
+
+       wait_data->wq = &adpt_wq_i2o_post;
+       wait_data->status = -ETIMEDOUT;
+
+       // this code is taken from kernel/sched.c:interruptible_sleep_on_timeout
+       wait.task = current;
+       init_waitqueue_entry(&wait, current);
+       wq_write_lock_irqsave(&adpt_wq_i2o_post.lock,flags);
+       __add_wait_queue(&adpt_wq_i2o_post, &wait);
+       wq_write_unlock(&adpt_wq_i2o_post.lock);
+
+       msg[2] |= 0x80000000 | ((u32)wait_data->id);
+       timeout *= HZ;
+       if((status = adpt_i2o_post_this(pHba, msg, len)) == 0){
+               if(!timeout){
+                       current->state = TASK_INTERRUPTIBLE;
+                       spin_unlock_irq(&io_request_lock);
+                       schedule();
+                       spin_lock_irq(&io_request_lock);
+               } else {
+                       current->state = TASK_INTERRUPTIBLE;
+                       spin_unlock_irq(&io_request_lock);
+                       schedule_timeout(timeout*HZ);
+                       spin_lock_irq(&io_request_lock);
+               }
+       }
+       wq_write_lock_irq(&adpt_wq_i2o_post.lock);
+       __remove_wait_queue(&adpt_wq_i2o_post, &wait);
+       wq_write_unlock_irqrestore(&adpt_wq_i2o_post.lock,flags);
+
+       if(status == -ETIMEDOUT){
+               printk(KERN_INFO"dpti%d: POST WAIT TIMEOUT\n",pHba->unit);
+               // We will have to free the wait_data memory during shutdown
+               return status;
+       }
+
+       /* Remove the entry from the queue.  */
+       p2 = NULL;
+       spin_lock_irqsave(&adpt_post_wait_lock, flags);
+       for(p1 = adpt_post_wait_queue; p1; p2 = p1, p1 = p1->next) {
+               if(p1 == wait_data) {
+                       if(p1->status == I2O_DETAIL_STATUS_UNSUPPORTED_FUNCTION ) {
+                               status = -EOPNOTSUPP;
+                       }
+                       if(p2) {
+                               p2->next = p1->next;
+                       } else {
+                               adpt_post_wait_queue = p1->next;
+                       }
+                       break;
+               }
+       }
+       spin_unlock_irqrestore(&adpt_post_wait_lock, flags);
+
+       kfree(wait_data);
+
+       return status;
+}
+
+
+static s32 adpt_i2o_post_this(adpt_hba* pHba, u32* data, int len)
+{
+
+       u32 m = EMPTY_QUEUE;
+       u32 *msg;
+       ulong timeout = jiffies + 30*HZ;
+       do {
+               rmb();
+               m = readl(pHba->post_port);
+               if (m != EMPTY_QUEUE) {
+                       break;
+               }
+               if(time_after(jiffies,timeout)){
+                       printk(KERN_WARNING"dpti%d: Timeout waiting for message frame!\n", pHba->unit);
+                       return -ETIMEDOUT;
+               }
+       } while(m == EMPTY_QUEUE);
+               
+       msg = (u32*) (pHba->msg_addr_virt + m);
+       memcpy_toio(msg, data, len);
+       wmb();
+
+       //post message
+       writel(m, pHba->post_port);
+       wmb();
+
+       return 0;
+}
+
+
+static void adpt_i2o_post_wait_complete(u32 context, int status)
+{
+       struct adpt_i2o_post_wait_data *p1 = NULL;
+       /*
+        * We need to search through the adpt_post_wait
+        * queue to see if the given message is still
+        * outstanding.  If not, it means that the IOP
+        * took longer to respond to the message than we
+        * had allowed and timer has already expired.
+        * Not much we can do about that except log
+        * it for debug purposes, increase timeout, and recompile
+        *
+        * Lock needed to keep anyone from moving queue pointers
+        * around while we're looking through them.
+        */
+
+       context &= 0x7fff;
+
+       spin_lock(&adpt_post_wait_lock);
+       for(p1 = adpt_post_wait_queue; p1; p1 = p1->next) {
+               if(p1->id == context) {
+                       p1->status = status;
+                       spin_unlock(&adpt_post_wait_lock);
+                       wake_up_interruptible(p1->wq);
+                       return;
+               }
+       }
+       spin_unlock(&adpt_post_wait_lock);
+        // If this happens we loose commands that probably really completed
+       printk(KERN_DEBUG"dpti: Could Not find task %d in wait queue\n",context);
+       printk(KERN_DEBUG"      Tasks in wait queue:\n");
+       for(p1 = adpt_post_wait_queue; p1; p1 = p1->next) {
+               printk(KERN_DEBUG"           %d\n",p1->id);
+       }
+       return;
+}
+
+static s32 adpt_i2o_reset_hba(adpt_hba* pHba)                  
+{
+       u32 msg[8];
+       u8* status;
+       u32 m = EMPTY_QUEUE ;
+       ulong timeout = jiffies + (TMOUT_IOPRESET*HZ);
+
+       if(pHba->initialized  == FALSE) {       // First time reset should be quick
+               timeout = jiffies + (25*HZ);
+       } else {
+               adpt_i2o_quiesce_hba(pHba);
+       }
+
+       do {
+               rmb();
+               m = readl(pHba->post_port);
+               if (m != EMPTY_QUEUE) {
+                       break;
+               }
+               if(time_after(jiffies,timeout)){
+                       printk(KERN_WARNING"Timeout waiting for message!\n");
+                       return -ETIMEDOUT;
+               }
+       } while (m == EMPTY_QUEUE);
+
+       status = (u8*)kmalloc(4, GFP_KERNEL|ADDR32);
+       if(status == NULL) {
+               adpt_send_nop(pHba, m);
+               printk(KERN_ERR"IOP reset failed - no free memory.\n");
+               return -ENOMEM;
+       }
+       memset(status,0,4);
+
+       msg[0]=EIGHT_WORD_MSG_SIZE|SGL_OFFSET_0;
+       msg[1]=I2O_CMD_ADAPTER_RESET<<24|HOST_TID<<12|ADAPTER_TID;
+       msg[2]=0;
+       msg[3]=0;
+       msg[4]=0;
+       msg[5]=0;
+       msg[6]=virt_to_bus(status);
+       msg[7]=0;     
+
+       memcpy_toio(pHba->msg_addr_virt+m, msg, sizeof(msg));
+       wmb();
+       writel(m, pHba->post_port);
+       wmb();
+
+       while(*status == 0){
+               if(time_after(jiffies,timeout)){
+                       printk(KERN_WARNING"%s: IOP Reset Timeout\n",pHba->name);
+                       kfree(status);
+                       return -ETIMEDOUT;
+               }
+               rmb();
+       }
+
+       if(*status == 0x01 /*I2O_EXEC_IOP_RESET_IN_PROGRESS*/) {
+               PDEBUG("%s: Reset in progress...\n", pHba->name);
+               // Here we wait for message frame to become available
+               // indicated that reset has finished
+               do {
+                       rmb();
+                       m = readl(pHba->post_port);
+                       if (m != EMPTY_QUEUE) {
+                               break;
+                       }
+                       if(time_after(jiffies,timeout)){
+                               printk(KERN_ERR "%s:Timeout waiting for IOP Reset.\n",pHba->name);
+                               return -ETIMEDOUT;
+                       }
+               } while (m == EMPTY_QUEUE);
+               // Flush the offset
+               adpt_send_nop(pHba, m);
+       }
+       adpt_i2o_status_get(pHba);
+       if(*status == 0x02 ||
+                       pHba->status_block->iop_state != ADAPTER_STATE_RESET) {
+               printk(KERN_WARNING"%s: Reset reject, trying to clear\n",
+                               pHba->name);
+       } else {
+               PDEBUG("%s: Reset completed.\n", pHba->name);
+       }
+
+       kfree(status);
+#ifdef UARTDELAY
+       // This delay is to allow someone attached to the card through the debug UART to 
+       // set up the dump levels that they want before the rest of the initialization sequence
+       adpt_delay(20000);
+#endif
+       return 0;
+}
+
+
+static int adpt_i2o_parse_lct(adpt_hba* pHba)
+{
+       int i;
+       int max;
+       int tid;
+       struct i2o_device *d;
+       i2o_lct *lct = pHba->lct;
+       u8 bus_no = 0;
+       s16 scsi_id;
+       s16 scsi_lun;
+       u32 buf[10]; // larger than 7, or 8 ...
+       struct adpt_device* pDev; 
+       
+       if (lct == NULL) {
+               printk(KERN_ERR "%s: LCT is empty???\n",pHba->name);
+               return -1;
+       }
+       
+       max = lct->table_size;  
+       max -= 3;
+       max /= 9;
+
+       for(i=0;i<max;i++) {
+               if( lct->lct_entry[i].user_tid != 0xfff){
+                       /*
+                        * If we have hidden devices, we need to inform the upper layers about
+                        * the possible maximum id reference to handle device access when
+                        * an array is disassembled. This code has no other purpose but to
+                        * allow us future access to devices that are currently hidden
+                        * behind arrays, hotspares or have not been configured (JBOD mode).
+                        */
+                       if( lct->lct_entry[i].class_id != I2O_CLASS_RANDOM_BLOCK_STORAGE &&
+                           lct->lct_entry[i].class_id != I2O_CLASS_SCSI_PERIPHERAL &&
+                           lct->lct_entry[i].class_id != I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL ){
+                               continue;
+                       }
+                       tid = lct->lct_entry[i].tid;
+                       // I2O_DPT_DEVICE_INFO_GROUP_NO;
+                       if(adpt_i2o_query_scalar(pHba, tid, 0x8000, -1, buf, 32)<0) {
+                               continue;
+                       }
+                       bus_no = buf[0]>>16;
+                       scsi_id = buf[1];
+                       scsi_lun = (buf[2]>>8 )&0xff;
+                       if(bus_no >= MAX_CHANNEL) {     // Something wrong skip it
+                               printk(KERN_WARNING"%s: Channel number %d out of range \n", pHba->name, bus_no);
+                               continue;
+                       }
+                       if(scsi_id > MAX_ID){
+                               printk(KERN_WARNING"%s: SCSI ID %d out of range \n", pHba->name, bus_no);
+                               continue;
+                       }
+                       if(bus_no > pHba->top_scsi_channel){
+                               pHba->top_scsi_channel = bus_no;
+                       }
+                       if(scsi_id > pHba->top_scsi_id){
+                               pHba->top_scsi_id = scsi_id;
+                       }
+                       if(scsi_lun > pHba->top_scsi_lun){
+                               pHba->top_scsi_lun = scsi_lun;
+                       }
+                       continue;
+               }
+               d = (struct i2o_device *)kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
+               if(d==NULL)
+               {
+                       printk(KERN_CRIT"%s: Out of memory for I2O device data.\n",pHba->name);
+                       return -ENOMEM;
+               }
+               
+               d->controller = (void*)pHba;
+               d->next = NULL;
+
+               memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
+
+               d->flags = 0;
+               tid = d->lct_data.tid;
+               adpt_i2o_report_hba_unit(pHba, d);
+               adpt_i2o_install_device(pHba, d);
+       }
+       bus_no = 0;
+       for(d = pHba->devices; d ; d = d->next) {
+               if(d->lct_data.class_id  == I2O_CLASS_BUS_ADAPTER_PORT ||
+                  d->lct_data.class_id  == I2O_CLASS_FIBRE_CHANNEL_PORT){
+                       tid = d->lct_data.tid;
+                       // TODO get the bus_no from hrt-but for now they are in order
+                       //bus_no = 
+                       if(bus_no > pHba->top_scsi_channel){
+                               pHba->top_scsi_channel = bus_no;
+                       }
+                       pHba->channel[bus_no].type = d->lct_data.class_id;
+                       pHba->channel[bus_no].tid = tid;
+                       if(adpt_i2o_query_scalar(pHba, tid, 0x0200, -1, buf, 28)>=0)
+                       {
+                               pHba->channel[bus_no].scsi_id = buf[1];
+                               PDEBUG("Bus %d - SCSI ID %d.\n", bus_no, buf[1]);
+                       }
+                       // TODO remove - this is just until we get from hrt
+                       bus_no++;
+                       if(bus_no >= MAX_CHANNEL) {     // Something wrong skip it
+                               printk(KERN_WARNING"%s: Channel number %d out of range - LCT\n", pHba->name, bus_no);
+                               break;
+                       }
+               }
+       }
+
+       // Setup adpt_device table
+       for(d = pHba->devices; d ; d = d->next) {
+               if(d->lct_data.class_id  == I2O_CLASS_RANDOM_BLOCK_STORAGE ||
+                  d->lct_data.class_id  == I2O_CLASS_SCSI_PERIPHERAL ||
+                  d->lct_data.class_id  == I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL ){
+
+                       tid = d->lct_data.tid;
+                       scsi_id = -1;
+                       // I2O_DPT_DEVICE_INFO_GROUP_NO;
+                       if(adpt_i2o_query_scalar(pHba, tid, 0x8000, -1, buf, 32)>=0) {
+                               bus_no = buf[0]>>16;
+                               scsi_id = buf[1];
+                               scsi_lun = (buf[2]>>8 )&0xff;
+                               if(bus_no >= MAX_CHANNEL) {     // Something wrong skip it
+                                       continue;
+                               }
+                               if(scsi_id > MAX_ID){
+                                       continue;
+                               }
+                               if( pHba->channel[bus_no].device[scsi_id] == NULL){
+                                       pDev =  kmalloc(sizeof(struct adpt_device),GFP_KERNEL);
+                                       if(pDev == NULL) {
+                                               return -ENOMEM;
+                                       }
+                                       pHba->channel[bus_no].device[scsi_id] = pDev;
+                                       memset(pDev,0,sizeof(struct adpt_device));
+                               } else {
+                                       for( pDev = pHba->channel[bus_no].device[scsi_id];      
+                                                       pDev->next_lun; pDev = pDev->next_lun){
+                                       }
+                                       pDev->next_lun = kmalloc(sizeof(struct adpt_device),GFP_KERNEL);
+                                       if(pDev == NULL) {
+                                               return -ENOMEM;
+                                       }
+                                       memset(pDev->next_lun,0,sizeof(struct adpt_device));
+                                       pDev = pDev->next_lun;
+                               }
+                               pDev->tid = tid;
+                               pDev->scsi_channel = bus_no;
+                               pDev->scsi_id = scsi_id;
+                               pDev->scsi_lun = scsi_lun;
+                               pDev->pI2o_dev = d;
+                               d->owner = pDev;
+                               pDev->type = (buf[0])&0xff;
+                               pDev->flags = (buf[0]>>8)&0xff;
+                               if(scsi_id > pHba->top_scsi_id){
+                                       pHba->top_scsi_id = scsi_id;
+                               }
+                               if(scsi_lun > pHba->top_scsi_lun){
+                                       pHba->top_scsi_lun = scsi_lun;
+                               }
+                       }
+                       if(scsi_id == -1){
+                               printk(KERN_WARNING"Could not find SCSI ID for %s\n",
+                                               d->lct_data.identity_tag);
+                       }
+               }
+       }
+       return 0;
+}
+
+
+/*
+ *     Each I2O controller has a chain of devices on it - these match
+ *     the useful parts of the LCT of the board.
+ */
+static int adpt_i2o_install_device(adpt_hba* pHba, struct i2o_device *d)
+{
+       down(&adpt_configuration_lock);
+       d->controller=pHba;
+       d->owner=NULL;
+       d->next=pHba->devices;
+       d->prev=NULL;
+       if (pHba->devices != NULL){
+               pHba->devices->prev=d;
+       }
+       pHba->devices=d;
+       *d->dev_name = 0;
+
+       up(&adpt_configuration_lock);
+       return 0;
+}
+
+static int adpt_open(struct inode *inode, struct file *file)
+{
+       int minor;
+       adpt_hba* pHba;
+
+       //TODO check for root access
+       //
+       minor = MINOR(inode->i_rdev);
+       if (minor >= hba_count) {
+               return -ENXIO;
+       }
+       down(&adpt_configuration_lock);
+       for (pHba = hba_chain; pHba; pHba = pHba->next) {
+               if (pHba->unit == minor) {
+                       break;  /* found adapter */
+               }
+       }
+       if (pHba == NULL) {
+               up(&adpt_configuration_lock);
+               return -ENXIO;
+       }
+
+//     if(pHba->in_use){
+       //      up(&adpt_configuration_lock);
+//             return -EBUSY;
+//     }
+
+       pHba->in_use = 1;
+       up(&adpt_configuration_lock);
+
+       return 0;
+}
+
+static int adpt_close(struct inode *inode, struct file *file)
+{
+       int minor;
+       adpt_hba* pHba;
+
+       minor = MINOR(inode->i_rdev);
+       if (minor >= hba_count) {
+               return -ENXIO;
+       }
+       down(&adpt_configuration_lock);
+       for (pHba = hba_chain; pHba; pHba = pHba->next) {
+               if (pHba->unit == minor) {
+                       break;  /* found adapter */
+               }
+       }
+       up(&adpt_configuration_lock);
+       if (pHba == NULL) {
+               return -ENXIO;
+       }
+
+       pHba->in_use = 0;
+
+       return 0;
+}
+
+
+static int adpt_i2o_passthru(adpt_hba* pHba, u32* arg)
+{
+       u32 msg[MAX_MESSAGE_SIZE];
+       u32* reply = NULL;
+       u32 size = 0;
+       u32 reply_size = 0;
+       u32* user_msg = (u32*)arg;
+       u32* user_reply = NULL;
+       ulong sg_list[pHba->sg_tablesize];
+       u32 sg_offset = 0;
+       u32 sg_count = 0;
+       int sg_index = 0;
+       u32 i = 0;
+       u32 rcode = 0;
+       ulong p = 0;
+       ulong flags = 0;
+
+       memset(&msg, 0, MAX_MESSAGE_SIZE*4);
+       // get user msg size in u32s 
+       if(get_user(size, &user_msg[0])){
+               return -EFAULT;
+       }
+       size = size>>16;
+
+       user_reply = &user_msg[size];
+       if(size > MAX_MESSAGE_SIZE){
+               return -EFAULT;
+       }
+       size *= 4; // Convert to bytes
+
+       /* Copy in the user's I2O command */
+       if(copy_from_user((void*)msg, (void*)user_msg, size)) {
+               return -EFAULT;
+       }
+       get_user(reply_size, &user_reply[0]);
+       reply_size = reply_size>>16;
+       if(reply_size > REPLY_FRAME_SIZE){
+               reply_size = REPLY_FRAME_SIZE;
+       }
+       reply_size *= 4;
+       reply = kmalloc(REPLY_FRAME_SIZE*4, GFP_KERNEL);
+       if(reply == NULL) {
+               printk(KERN_WARNING"%s: Could not allocate reply buffer\n",pHba->name);
+               return -ENOMEM;
+       }
+       memset(reply,0,REPLY_FRAME_SIZE*4);
+       sg_offset = (msg[0]>>4)&0xf;
+       msg[2] = 0x40000000; // IOCTL context
+       msg[3] = (u32)reply;
+       memset(sg_list,0, sizeof(sg_list[0])*pHba->sg_tablesize);
+       if(sg_offset) {
+               // TODO 64bit fix
+               struct sg_simple_element *sg =  (struct sg_simple_element*) (msg+sg_offset);
+               sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element);
+               if (sg_count > pHba->sg_tablesize){
+                       printk(KERN_DEBUG"%s:IOCTL SG List too large (%u)\n", pHba->name,sg_count);
+                       kfree (reply);
+                       return -EINVAL;
+               }
+
+               for(i = 0; i < sg_count; i++) {
+                       int sg_size;
+
+                       if (!(sg[i].flag_count & 0x10000000 /*I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT*/)) {
+                               printk(KERN_DEBUG"%s:Bad SG element %d - not simple (%x)\n",pHba->name,i,  sg[i].flag_count);
+                               rcode = -EINVAL;
+                               goto cleanup;
+                       }
+                       sg_size = sg[i].flag_count & 0xffffff;      
+                       /* Allocate memory for the transfer */
+                       p = (ulong)kmalloc(sg_size, GFP_KERNEL|ADDR32);
+                       if(p == 0) {
+                               printk(KERN_DEBUG"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
+                                               pHba->name,sg_size,i,sg_count);
+                               rcode = -ENOMEM;
+                               goto cleanup;
+                       }
+                       sg_list[sg_index++] = p; // sglist indexed with input frame, not our internal frame.
+                       /* Copy in the user's SG buffer if necessary */
+                       if(sg[i].flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR*/) {
+                               // TODO 64bit fix
+                               if (copy_from_user((void*)p,(void*)sg[i].addr_bus, sg_size)) {
+                                       printk(KERN_DEBUG"%s: Could not copy SG buf %d FROM user\n",pHba->name,i);
+                                       rcode = -EFAULT;
+                                       goto cleanup;
+                               }
+                       }
+                       //TODO 64bit fix
+                       sg[i].addr_bus = (u32)virt_to_bus((void*)p);
+               }
+       }
+
+       do {
+               spin_lock_irqsave(&io_request_lock, flags);
+               // This state stops any new commands from enterring the
+               // controller while processing the ioctl
+//             pHba->state |= DPTI_STATE_IOCTL;
+//             We can't set this now - The scsi subsystem sets host_blocked and
+//             the queue empties and stops.  We need a way to restart the queue
+               rcode = adpt_i2o_post_wait(pHba, msg, size, FOREVER);
+//             pHba->state &= ~DPTI_STATE_IOCTL;
+               spin_unlock_irqrestore(&io_request_lock, flags);
+       } while(rcode == -ETIMEDOUT);  
+
+       if(rcode){
+               goto cleanup;
+       }
+
+       if(sg_offset) {
+       /* Copy back the Scatter Gather buffers back to user space */
+               u32 j;
+               // TODO 64bit fix
+               struct sg_simple_element* sg;
+               int sg_size;
+
+               // re-acquire the original message to handle correctly the sg copy operation
+               memset(&msg, 0, MAX_MESSAGE_SIZE*4); 
+               // get user msg size in u32s 
+               if(get_user(size, &user_msg[0])){
+                       rcode = -EFAULT; 
+                       goto cleanup; 
+               }
+               size = size>>16;
+               size *= 4;
+               /* Copy in the user's I2O command */
+               if (copy_from_user ((void*)msg, (void*)user_msg, size)) {
+                       rcode = -EFAULT;
+                       goto cleanup;
+               }
+               sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element);
+
+               // TODO 64bit fix
+               sg       = (struct sg_simple_element*)(msg + sg_offset);
+               for (j = 0; j < sg_count; j++) {
+                       /* Copy out the SG list to user's buffer if necessary */
+                       if(! (sg[j].flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR*/)) {
+                               sg_size = sg[j].flag_count & 0xffffff; 
+                               // TODO 64bit fix
+                               if (copy_to_user((void*)sg[j].addr_bus,(void*)sg_list[j], sg_size)) {
+                                       printk(KERN_WARNING"%s: Could not copy %lx TO user %x\n",pHba->name, sg_list[j], sg[j].addr_bus);
+                                       rcode = -EFAULT;
+                                       goto cleanup;
+                               }
+                       }
+               }
+       } 
+
+       /* Copy back the reply to user space */
+       if (reply_size) {
+               // we wrote our own values for context - now restore the user supplied ones
+               if(copy_from_user(reply+2, user_msg+2, sizeof(u32)*2)) {
+                       printk(KERN_WARNING"%s: Could not copy message context FROM user\n",pHba->name);
+                       rcode = -EFAULT;
+               }
+               if(copy_to_user(user_reply, reply, reply_size)) {
+                       printk(KERN_WARNING"%s: Could not copy reply TO user\n",pHba->name);
+                       rcode = -EFAULT;
+               }
+       }
+
+
+cleanup:
+       kfree (reply);
+       while(sg_index) {
+               if(sg_list[--sg_index]) {
+                       kfree((void*)(sg_list[sg_index]));
+               }
+       }
+       return rcode;
+}
+
+
+/*
+ * This routine returns information about the system.  This does not effect
+ * any logic and if the info is wrong - it doesn't matter.
+ */
+
+/* Get all the info we can not get from kernel services */
+static int adpt_system_info(void *buffer)
+{
+       sysInfo_S si;
+
+       memset(&si, 0, sizeof(si));
+
+       si.osType = OS_LINUX;
+       si.osMajorVersion = (u8) (LINUX_VERSION_CODE >> 16);
+       si.osMinorVersion = (u8) (LINUX_VERSION_CODE >> 8 & 0x0ff);
+       si.osRevision =     (u8) (LINUX_VERSION_CODE & 0x0ff);
+       si.busType = SI_PCI_BUS;
+       si.processorFamily = DPTI_sig.dsProcessorFamily;
+
+#if defined __i386__ 
+       adpt_i386_info(&si);
+#elif defined __ia64__
+       adpt_ia64_info(&si);
+#elif define __sparc__
+       adpt_sparc_info(&si);
+#elif defined __alpha__ 
+       adpt_alpha_info(&si);
+#else
+       si.processorType = 0xff ;
+#endif
+       if(copy_to_user(buffer, &si, sizeof(si))){
+               printk(KERN_WARNING"dpti: Could not copy buffer TO user\n");
+               return -EFAULT;
+       }
+
+       return 0;
+}
+
+#if defined __ia64__ 
+static void adpt_ia64_info(sysInfo_S* si)
+{
+       // This is all the info we need for now
+       // We will add more info as our new
+       // managmenent utility requires it
+       si->processorType = PROC_IA64;
+}
+#endif
+
+
+#if defined __sparc__ 
+static void adpt_sparc_info(sysInfo_S* si)
+{
+       // This is all the info we need for now
+       // We will add more info as our new
+       // managmenent utility requires it
+       si->processorType = PROC_ULTRASPARC;
+}
+#endif
+
+#if defined __alpha__ 
+static void adpt_sparc_info(sysInfo_S* si)
+{
+       // This is all the info we need for now
+       // We will add more info as our new
+       // managmenent utility requires it
+       si->processorType = PROC_ALPHA;
+}
+#endif
+
+#if defined __i386__
+
+static void adpt_i386_info(sysInfo_S* si)
+{
+       // This is all the info we need for now
+       // We will add more info as our new
+       // managmenent utility requires it
+       switch (boot_cpu_data.x86) {
+       case CPU_386:
+               si->processorType = PROC_386;
+               break;
+       case CPU_486:
+               si->processorType = PROC_486;
+               break;
+       case CPU_586:
+               si->processorType = PROC_PENTIUM;
+               break;
+       default:  // Just in case 
+               si->processorType = PROC_PENTIUM;
+               break;
+       }
+}
+
+#endif
+
+
+static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd,
+             ulong arg)
+{
+       int minor;
+       int error = 0;
+       adpt_hba* pHba;
+       ulong flags;
+
+       minor = MINOR(inode->i_rdev);
+       if (minor >= DPTI_MAX_HBA){
+               return -ENXIO;
+       }
+       down(&adpt_configuration_lock);
+       for (pHba = hba_chain; pHba; pHba = pHba->next) {
+               if (pHba->unit == minor) {
+                       break;  /* found adapter */
+               }
+       }
+       up(&adpt_configuration_lock);
+       if(pHba == NULL){
+               return -ENXIO;
+       }
+
+       while((volatile u32) pHba->state & DPTI_STATE_RESET ) {
+               set_task_state(current,TASK_UNINTERRUPTIBLE);
+               schedule_timeout(2);
+
+       }
+
+       switch (cmd) {
+       // TODO: handle 3 cases
+       case DPT_SIGNATURE:
+               if (copy_to_user((char*)arg, &DPTI_sig, sizeof(DPTI_sig))) {
+                       return -EFAULT;
+               }
+               break;
+       case I2OUSRCMD:
+               return  adpt_i2o_passthru(pHba,(u32*)arg);
+               break;
+
+       case DPT_CTRLINFO:{
+               drvrHBAinfo_S HbaInfo;
+
+#define FLG_OSD_PCI_VALID 0x0001
+#define FLG_OSD_DMA      0x0002
+#define FLG_OSD_I2O      0x0004
+               memset(&HbaInfo, 0, sizeof(HbaInfo));
+               HbaInfo.drvrHBAnum = pHba->unit;
+               HbaInfo.baseAddr = (ulong) pHba->base_addr_phys;
+               HbaInfo.blinkState = adpt_read_blink_led(pHba);
+               HbaInfo.pciBusNum =  pHba->pDev->bus->number;
+               HbaInfo.pciDeviceNum=PCI_SLOT(pHba->pDev->devfn); 
+               HbaInfo.Interrupt = pHba->pDev->irq; 
+               HbaInfo.hbaFlags = FLG_OSD_PCI_VALID | FLG_OSD_DMA | FLG_OSD_I2O;
+               if(copy_to_user((void *) arg, &HbaInfo, sizeof(HbaInfo))){
+                       printk(KERN_WARNING"%s: Could not copy HbaInfo TO user\n",pHba->name);
+                       return -EFAULT;
+               }
+               break;
+               }
+       case DPT_SYSINFO:
+               return adpt_system_info((void*)arg);
+               break;
+       case DPT_BLINKLED:{
+               u32 value;
+               value = (u32)adpt_read_blink_led(pHba);
+               if (copy_to_user((char*)arg, &value, sizeof(value))) {
+                       return -EFAULT;
+               }
+               break;
+               }
+       case I2ORESETCMD:
+               spin_lock_irqsave(&io_request_lock, flags);
+               adpt_hba_reset(pHba);
+               spin_unlock_irqrestore(&io_request_lock, flags);
+               break;
+       case I2ORESCANCMD:
+               adpt_rescan(pHba);
+               break;
+       case DPT_TARGET_BUSY & 0xFFFF:
+       case DPT_TARGET_BUSY:
+       {
+               TARGET_BUSY_T busy;
+               struct adpt_device* d;
+
+               if (copy_from_user((void*)&busy, (void*)arg, sizeof(TARGET_BUSY_T))) {
+                       return -EFAULT;
+               }
+
+               d = adpt_find_device(pHba, busy.channel, busy.id, busy.lun);
+               if(d == NULL){
+                       return -ENODEV;
+               }
+               busy.isBusy = ((d->pScsi_dev) && (0 != d->pScsi_dev->access_count)) ? 1 : 0;
+               if (copy_to_user ((char*)arg, &busy, sizeof(busy))) {
+                       return -EFAULT;
+               }
+               break;
+       }
+       default:
+               return -EINVAL;
+       }
+
+       return error;
+}
+
+
+static void adpt_isr(int irq, void *dev_id, struct pt_regs *regs)
+{
+       Scsi_Cmnd* cmd;
+       adpt_hba* pHba=NULL;
+       u32 m;
+       ulong reply;
+       u32 status=0;
+       u32 context;
+       ulong flags = 0;
+
+       pHba = dev_id;
+       if (pHba == NULL ){
+               printk(KERN_WARNING"adpt_isr: NULL dev_id\n");
+               return;
+       }
+       spin_lock_irqsave(&io_request_lock, flags);
+       while( readl(pHba->irq_mask) & I2O_INTERRUPT_PENDING_B) {
+               m = readl(pHba->reply_port);
+               if(m == EMPTY_QUEUE){
+                       // Try twice then give up
+                       rmb();
+                       m = readl(pHba->reply_port);
+                       if(m == EMPTY_QUEUE){ 
+                               // This really should not happen
+                               printk(KERN_ERR"dpti: Could not get reply frame\n");
+                               spin_unlock_irqrestore(&io_request_lock,flags);
+                               return;
+                       }
+               }
+               reply = (ulong)bus_to_virt(m);
+
+               if (readl(reply) & MSG_FAIL) {
+                       u32 old_m = readl(reply+28); 
+                       ulong msg;
+                       u32 old_context;
+                       PDEBUG("%s: Failed message\n",pHba->name);
+                       if(old_m >= 0x100000){
+                               printk(KERN_ERR"%s: Bad preserved MFA (%x)- dropping frame\n",pHba->name,old_m);
+                               writel(m,pHba->reply_port);
+                               continue;
+                       }
+                       // Transaction context is 0 in failed reply frame
+                       msg = (ulong)(pHba->msg_addr_virt + old_m);
+                       old_context = readl(msg+12);
+                       writel(old_context, reply+12);
+                       adpt_send_nop(pHba, old_m);
+               } 
+               context = readl(reply+8);
+               if(context & 0x40000000){ // IOCTL
+                       ulong p = (ulong)(readl(reply+12));
+                       if( p != 0) {
+                               memcpy((void*)p, (void*)reply, REPLY_FRAME_SIZE * 4);
+                       }
+                       // All IOCTLs will also be post wait
+               }
+               if(context & 0x80000000){ // Post wait message
+                       status = readl(reply+16);
+                       if(status  >> 24){
+                               status &=  0xffff; /* Get detail status */
+                       } else {
+                               status = I2O_POST_WAIT_OK;
+                       }
+                       if(!(context & 0x40000000)) {
+                               cmd = (Scsi_Cmnd*) readl(reply+12); 
+                               if(cmd != NULL) {
+                                       printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context);
+                               }
+                       }
+                       adpt_i2o_post_wait_complete(context, status);
+               } else { // SCSI message
+                       cmd = (Scsi_Cmnd*) readl(reply+12); 
+                       if(cmd != NULL){
+                               if(cmd->serial_number != 0) { // If not timedout
+                                       adpt_i2o_to_scsi(reply, cmd);
+                               }
+                       }
+               }
+               writel(m, pHba->reply_port);
+               wmb();
+               rmb();
+       }
+       spin_unlock_irqrestore(&io_request_lock, flags);
+       return;
+
+}
+
+static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device* d)
+{
+       int i;
+       u32 msg[MAX_MESSAGE_SIZE];
+       u32* mptr;
+       u32 *lenptr;
+       int direction;
+       int scsidir;
+       u32 len;
+       u32 reqlen;
+       s32 rcode;
+
+       memset(msg, 0 , sizeof(msg));
+       len = cmd->request_bufflen;
+       direction = 0x00000000; 
+       
+       scsidir = 0x00000000;                   // DATA NO XFER
+       if(len) {
+               /*
+                * Set SCBFlags to indicate if data is being transferred
+                * in or out, or no data transfer
+                * Note:  Do not have to verify index is less than 0 since
+                * cmd->cmnd[0] is an unsigned char
+                */
+               switch(cmd->sc_data_direction){
+               case SCSI_DATA_READ:
+                       scsidir  =0x40000000;   // DATA IN  (iop<--dev)
+                       break;
+               case SCSI_DATA_WRITE:
+                       direction=0x04000000;   // SGL OUT
+                       scsidir  =0x80000000;   // DATA OUT (iop-->dev)
+                       break;
+               case SCSI_DATA_NONE:
+                       break;
+               case SCSI_DATA_UNKNOWN:
+                       scsidir  =0x40000000;   // DATA IN  (iop<--dev)
+                       // Assume In - and continue;
+                       break;
+               default:
+                       printk(KERN_WARNING"%s: scsi opcode 0x%x not supported.\n",
+                            pHba->name, cmd->cmnd[0]);
+                       cmd->result = (DID_OK <<16) | (INITIATOR_ERROR << 8);
+                       cmd->scsi_done(cmd);
+                       return  0;
+               }
+       }
+       // msg[0] is set later
+       // I2O_CMD_SCSI_EXEC
+       msg[1] = ((0xff<<24)|(HOST_TID<<12)|d->tid);
+       msg[2] = 0;
+       msg[3] = (u32)cmd;      /* We want the SCSI control block back */
+       // Our cards use the transaction context as the tag for queueing
+       // Adaptec/DPT Private stuff 
+       msg[4] = I2O_CMD_SCSI_EXEC|(DPT_ORGANIZATION_ID<<16);
+       msg[5] = d->tid;
+       /* Direction, disconnect ok | sense data | simple queue , CDBLen */
+       // I2O_SCB_FLAG_ENABLE_DISCONNECT | 
+       // I2O_SCB_FLAG_SIMPLE_QUEUE_TAG | 
+       // I2O_SCB_FLAG_SENSE_DATA_IN_MESSAGE;
+       msg[6] = scsidir|0x20a00000|cmd->cmd_len;
+
+       mptr=msg+7;
+
+       // Write SCSI command into the message - always 16 byte block 
+       memset(mptr, 0,  16);
+       memcpy(mptr, cmd->cmnd, cmd->cmd_len);
+       mptr+=4;
+       lenptr=mptr++;          /* Remember me - fill in when we know */
+       reqlen = 14;            // SINGLE SGE
+       /* Now fill in the SGList and command */
+       if(cmd->use_sg) {
+               struct scatterlist *sg = (struct scatterlist *)cmd->request_buffer;
+               len = 0;
+               for(i = 0 ; i < cmd->use_sg; i++) {
+                       *mptr++ = direction|0x10000000|sg->length;
+                       len+=sg->length;
+                       *mptr++ = virt_to_bus(sg->address);
+                       sg++;
+               }
+               /* Make this an end of list */
+               mptr[-2] = direction|0xD0000000|(sg-1)->length;
+               reqlen = mptr - msg;
+               *lenptr = len;
+               
+               if(cmd->underflow && len != cmd->underflow){
+                       printk(KERN_WARNING"Cmd len %08X Cmd underflow %08X\n",
+                               len, cmd->underflow);
+               }
+       } else {
+               *lenptr = len = cmd->request_bufflen;
+               if(len == 0) {
+                       reqlen = 12;
+               } else {
+                       *mptr++ = 0xD0000000|direction|cmd->request_bufflen;
+                       *mptr++ = virt_to_bus(cmd->request_buffer);
+               }
+       }
+       
+       /* Stick the headers on */
+       msg[0] = reqlen<<16 | ((reqlen > 12) ? SGL_OFFSET_12 : SGL_OFFSET_0);
+       
+       // Send it on it's way
+       rcode = adpt_i2o_post_this(pHba, msg, reqlen<<2);
+       if (rcode == 0) {
+               return 0;
+       }
+       return rcode;
+}
+
+
+static s32 adpt_scsi_register(adpt_hba* pHba,Scsi_Host_Template * sht)
+{
+       struct Scsi_Host *host = NULL;
+
+       host = scsi_register(sht, sizeof(adpt_hba*));
+       if (host == NULL) {
+               printk ("%s: scsi_register returned NULL\n",pHba->name);
+               return -1;
+       }
+       (adpt_hba*)(host->hostdata[0]) = pHba;
+       pHba->host = host;
+
+       host->irq = pHba->pDev->irq;;
+       /* no IO ports, so don't have to set host->io_port and 
+        * host->n_io_port
+        */
+       host->io_port = 0;
+       host->n_io_port = 0;
+                               /* see comments in hosts.h */
+       host->max_id = 16;
+       host->max_lun = 256;
+       host->max_channel = pHba->top_scsi_channel + 1;
+       host->cmd_per_lun = 256;
+       host->unique_id = (uint) pHba;
+       host->sg_tablesize = pHba->sg_tablesize;
+       host->can_queue = pHba->post_fifo_size;
+       host->select_queue_depths = adpt_select_queue_depths;
+
+       return 0;
+}
+
+
+static s32 adpt_i2o_to_scsi(ulong reply, Scsi_Cmnd* cmd)
+{
+       adpt_hba* pHba;
+       u32 hba_status;
+       u32 dev_status;
+       u32 reply_flags = readl(reply) & 0xff00; // Leave it shifted up 8 bits 
+       // I know this would look cleaner if I just read bytes
+       // but the model I have been using for all the rest of the
+       // io is in 4 byte words - so I keep that model
+       u16 detailed_status = readl(reply+16) &0xffff;
+       dev_status = (detailed_status & 0xff);
+       hba_status = detailed_status >> 8;
+
+       // calculate resid for sg 
+       cmd->resid = cmd->request_bufflen - readl(reply+5);
+
+       pHba = (adpt_hba*) cmd->host->hostdata[0];
+
+       cmd->sense_buffer[0] = '\0';  // initialize sense valid flag to false
+
+       if(!(reply_flags & MSG_FAIL)) {
+               switch(detailed_status & I2O_SCSI_DSC_MASK) {
+               case I2O_SCSI_DSC_SUCCESS:
+                       cmd->result = (DID_OK << 16);
+                       // handle underflow
+                       if(readl(reply+5) < cmd->underflow ) {
+                               cmd->result = (DID_ERROR <<16);
+                               printk(KERN_WARNING"%s: SCSI CMD underflow\n",pHba->name);
+                       }
+                       break;
+               case I2O_SCSI_DSC_REQUEST_ABORTED:
+                       cmd->result = (DID_ABORT << 16);
+                       break;
+               case I2O_SCSI_DSC_PATH_INVALID:
+               case I2O_SCSI_DSC_DEVICE_NOT_PRESENT:
+               case I2O_SCSI_DSC_SELECTION_TIMEOUT:
+               case I2O_SCSI_DSC_COMMAND_TIMEOUT:
+               case I2O_SCSI_DSC_NO_ADAPTER:
+               case I2O_SCSI_DSC_RESOURCE_UNAVAILABLE:
+                       printk(KERN_WARNING"%s: SCSI Timeout-Device (%d,%d,%d) hba status=0x%x, dev status=0x%x, cmd=0x%x\n",
+                               pHba->name, (u32)cmd->channel, (u32)cmd->target, (u32)cmd->lun, hba_status, dev_status, cmd->cmnd[0]);
+                       cmd->result = (DID_TIME_OUT << 16);
+                       break;
+               case I2O_SCSI_DSC_ADAPTER_BUSY:
+               case I2O_SCSI_DSC_BUS_BUSY:
+                       cmd->result = (DID_BUS_BUSY << 16);
+                       break;
+               case I2O_SCSI_DSC_SCSI_BUS_RESET:
+               case I2O_SCSI_DSC_BDR_MESSAGE_SENT:
+                       cmd->result = (DID_RESET << 16);
+                       break;
+               case I2O_SCSI_DSC_PARITY_ERROR_FAILURE:
+                       printk(KERN_WARNING"%s: SCSI CMD parity error\n",pHba->name);
+                       cmd->result = (DID_PARITY << 16);
+                       break;
+               case I2O_SCSI_DSC_UNABLE_TO_ABORT:
+               case I2O_SCSI_DSC_COMPLETE_WITH_ERROR:
+               case I2O_SCSI_DSC_UNABLE_TO_TERMINATE:
+               case I2O_SCSI_DSC_MR_MESSAGE_RECEIVED:
+               case I2O_SCSI_DSC_AUTOSENSE_FAILED:
+               case I2O_SCSI_DSC_DATA_OVERRUN:
+               case I2O_SCSI_DSC_UNEXPECTED_BUS_FREE:
+               case I2O_SCSI_DSC_SEQUENCE_FAILURE:
+               case I2O_SCSI_DSC_REQUEST_LENGTH_ERROR:
+               case I2O_SCSI_DSC_PROVIDE_FAILURE:
+               case I2O_SCSI_DSC_REQUEST_TERMINATED:
+               case I2O_SCSI_DSC_IDE_MESSAGE_SENT:
+               case I2O_SCSI_DSC_UNACKNOWLEDGED_EVENT:
+               case I2O_SCSI_DSC_MESSAGE_RECEIVED:
+               case I2O_SCSI_DSC_INVALID_CDB:
+               case I2O_SCSI_DSC_LUN_INVALID:
+               case I2O_SCSI_DSC_SCSI_TID_INVALID:
+               case I2O_SCSI_DSC_FUNCTION_UNAVAILABLE:
+               case I2O_SCSI_DSC_NO_NEXUS:
+               case I2O_SCSI_DSC_CDB_RECEIVED:
+               case I2O_SCSI_DSC_LUN_ALREADY_ENABLED:
+               case I2O_SCSI_DSC_QUEUE_FROZEN:
+               case I2O_SCSI_DSC_REQUEST_INVALID:
+               default:
+                       printk(KERN_WARNING"%s: SCSI error %0x-Device(%d,%d,%d) hba_status=0x%x, dev_status=0x%x, cmd=0x%x\n",
+                               pHba->name, detailed_status & I2O_SCSI_DSC_MASK, (u32)cmd->channel, (u32)cmd->target, (u32)cmd-> lun,
+                              hba_status, dev_status, cmd->cmnd[0]);
+                       cmd->result = (DID_ERROR << 16);
+                       break;
+               }
+
+               // copy over the request sense data if it was a check
+               // condition status
+               if(dev_status == 0x02 /*CHECK_CONDITION*/) {
+                       u32 len = sizeof(cmd->sense_buffer);
+                       len = (len > 40) ?  40 : len;
+                       // Copy over the sense data
+                       memcpy(cmd->sense_buffer, (void*)(reply+28) , len);
+                       if(cmd->sense_buffer[0] == 0x70 /* class 7 */ && 
+                          cmd->sense_buffer[2] == DATA_PROTECT ){
+                               /* This is to handle an array failed */
+                               cmd->result = (DID_TIME_OUT << 16);
+                               printk(KERN_WARNING"%s: SCSI Data Protect-Device (%d,%d,%d) hba_status=0x%x, dev_status=0x%x, cmd=0x%x\n",
+                                       pHba->name, (u32)cmd->channel, (u32)cmd->target, (u32)cmd->lun, 
+                                       hba_status, dev_status, cmd->cmnd[0]);
+
+                       }
+               }
+       } else {
+               /* In this condtion we could not talk to the tid
+                * the card rejected it.  We should signal a retry
+                * for a limitted number of retries.
+                */
+               cmd->result = (DID_TIME_OUT << 16);
+               printk(KERN_WARNING"%s: I2O MSG_FAIL - Device (%d,%d,%d) tid=%d, cmd=0x%x\n",
+                       pHba->name, (u32)cmd->channel, (u32)cmd->target, (u32)cmd-> lun,
+                       ((struct adpt_device*)(cmd->device->hostdata))->tid, cmd->cmnd[0]);
+       }
+
+       cmd->result |= (dev_status);
+
+       if(cmd->scsi_done != NULL){
+               cmd->scsi_done(cmd);
+       } 
+       return cmd->result;
+}
+
+
+static s32 adpt_rescan(adpt_hba* pHba)
+{
+       s32 rcode;
+       ulong flags;
+
+       spin_lock_irqsave(&io_request_lock, flags);
+       if ((rcode=adpt_i2o_lct_get(pHba)) < 0){
+               spin_unlock_irqrestore(&io_request_lock, flags);
+               return rcode;
+       }
+
+       if ((rcode=adpt_i2o_reparse_lct(pHba)) < 0){
+               spin_unlock_irqrestore(&io_request_lock, flags);
+               return rcode;
+       }
+       spin_unlock_irqrestore(&io_request_lock, flags);
+       return 0;
+}
+
+
+static s32 adpt_i2o_reparse_lct(adpt_hba* pHba)
+{
+       int i;
+       int max;
+       int tid;
+       struct i2o_device *d;
+       i2o_lct *lct = pHba->lct;
+       u8 bus_no = 0;
+       s16 scsi_id;
+       s16 scsi_lun;
+       u32 buf[10]; // at least 8 u32's
+       struct adpt_device* pDev = NULL;
+       struct i2o_device* pI2o_dev = NULL;
+       
+       if (lct == NULL) {
+               printk(KERN_ERR "%s: LCT is empty???\n",pHba->name);
+               return -1;
+       }
+       
+       max = lct->table_size;  
+       max -= 3;
+       max /= 9;
+
+       // Mark each drive as unscanned
+       for (d = pHba->devices; d; d = d->next) {
+               pDev =(struct adpt_device*) d->owner;
+               if(!pDev){
+                       continue;
+               }
+               pDev->state |= DPTI_DEV_UNSCANNED;
+       }
+
+       printk(KERN_INFO "%s: LCT has %d entries.\n", pHba->name,max);
+       
+       for(i=0;i<max;i++) {
+               if( lct->lct_entry[i].user_tid != 0xfff){
+                       continue;
+               }
+
+               if( lct->lct_entry[i].class_id == I2O_CLASS_RANDOM_BLOCK_STORAGE ||
+                   lct->lct_entry[i].class_id == I2O_CLASS_SCSI_PERIPHERAL ||
+                   lct->lct_entry[i].class_id == I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL ){
+                       tid = lct->lct_entry[i].tid;
+                       if(adpt_i2o_query_scalar(pHba, tid, 0x8000, -1, buf, 32)<0) {
+                               printk(KERN_ERR"%s: Could not query device\n",pHba->name);
+                               continue;
+                       }
+                       bus_no = buf[0]>>16;
+                       scsi_id = buf[1];
+                       scsi_lun = (buf[2]>>8 )&0xff;
+                       pDev = pHba->channel[bus_no].device[scsi_id];
+                       /* da lun */
+                       while(pDev) {
+                               if(pDev->scsi_lun == scsi_lun) {
+                                       break;
+                               }
+                               pDev = pDev->next_lun;
+                       }
+                       if(!pDev ) { // Something new add it
+                               d = (struct i2o_device *)kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
+                               if(d==NULL)
+                               {
+                                       printk(KERN_CRIT "Out of memory for I2O device data.\n");
+                                       return -ENOMEM;
+                               }
+                               
+                               d->controller = (void*)pHba;
+                               d->next = NULL;
+
+                               memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
+
+                               d->flags = 0;
+                               adpt_i2o_report_hba_unit(pHba, d);
+                               adpt_i2o_install_device(pHba, d);
+       
+                               if(bus_no >= MAX_CHANNEL) {     // Something wrong skip it
+                                       printk(KERN_WARNING"%s: Channel number %d out of range \n", pHba->name, bus_no);
+                                       continue;
+                               }
+                               pDev = pHba->channel[bus_no].device[scsi_id];   
+                               if( pDev == NULL){
+                                       pDev =  kmalloc(sizeof(struct adpt_device),GFP_KERNEL);
+                                       if(pDev == NULL) {
+                                               return -ENOMEM;
+                                       }
+                                       pHba->channel[bus_no].device[scsi_id] = pDev;
+                               } else {
+                                       while (pDev->next_lun) {
+                                               pDev = pDev->next_lun;
+                                       }
+                                       pDev = pDev->next_lun = kmalloc(sizeof(struct adpt_device),GFP_KERNEL);
+                                       if(pDev == NULL) {
+                                               return -ENOMEM;
+                                       }
+                               }
+                               memset(pDev,0,sizeof(struct adpt_device));
+                               pDev->tid = d->lct_data.tid;
+                               pDev->scsi_channel = bus_no;
+                               pDev->scsi_id = scsi_id;
+                               pDev->scsi_lun = scsi_lun;
+                               pDev->pI2o_dev = d;
+                               d->owner = pDev;
+                               pDev->type = (buf[0])&0xff;
+                               pDev->flags = (buf[0]>>8)&0xff;
+                               // Too late, SCSI system has made up it's mind, but what the hey ...
+                               if(scsi_id > pHba->top_scsi_id){
+                                       pHba->top_scsi_id = scsi_id;
+                               }
+                               if(scsi_lun > pHba->top_scsi_lun){
+                                       pHba->top_scsi_lun = scsi_lun;
+                               }
+                               continue;
+                       } // end of new i2o device
+
+                       // We found an old device - check it
+                       while(pDev) {
+                               if(pDev->scsi_lun == scsi_lun) {
+                                       if(pDev->pScsi_dev->online == FALSE) {
+                                               printk(KERN_WARNING"%s: Setting device (%d,%d,%d) back online\n",
+                                                               pHba->name,bus_no,scsi_id,scsi_lun);
+                                               if (pDev->pScsi_dev) {
+                                                       pDev->pScsi_dev->online = TRUE;
+                                               }
+                                       }
+                                       d = pDev->pI2o_dev;
+                                       if(d->lct_data.tid != tid) { // something changed
+                                               pDev->tid = tid;
+                                               memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
+                                               if (pDev->pScsi_dev) {
+                                                       pDev->pScsi_dev->changed = TRUE;
+                                                       pDev->pScsi_dev->removable = TRUE;
+                                               }
+                                       }
+                                       // Found it - mark it scanned
+                                       pDev->state = DPTI_DEV_ONLINE;
+                                       break;
+                               }
+                               pDev = pDev->next_lun;
+                       }
+               }
+       }
+       for (pI2o_dev = pHba->devices; pI2o_dev; pI2o_dev = pI2o_dev->next) {
+               pDev =(struct adpt_device*) pI2o_dev->owner;
+               if(!pDev){
+                       continue;
+               }
+               // Drive offline drives that previously existed but could not be found
+               // in the LCT table
+               if (pDev->state & DPTI_DEV_UNSCANNED){
+                       pDev->state = DPTI_DEV_OFFLINE;
+                       printk(KERN_WARNING"%s: Device (%d,%d,%d) offline\n",pHba->name,pDev->scsi_channel,pDev->scsi_id,pDev->scsi_lun);
+                       if (pDev->pScsi_dev) {
+                               pDev->pScsi_dev->online = FALSE;
+                               if (pDev->pScsi_dev->access_count) {
+                                       // A drive that was mounted is no longer there... bad!
+                                       SCSI_LOG_ERROR_RECOVERY(1, printk ("%s:Rescan: Previously "
+                                                                "mounted drive not found!\n",pHba->name));
+                                       printk(KERN_WARNING"%s:Mounted drive taken offline\n",pHba->name);
+                               }
+                       }
+               }
+       }
+       return 0;
+}
+
+static void adpt_fail_posted_scbs(adpt_hba* pHba)
+{
+       Scsi_Cmnd*      cmd = NULL;
+       Scsi_Device*    d = NULL;
+
+       if( pHba->host->host_queue != NULL ) {
+               d = pHba->host->host_queue;
+               if(!d){
+                       return;
+               }
+               while( d->next != NULL ){
+                       for(cmd = d->device_queue; cmd ; cmd = cmd->next){
+                               if(cmd->serial_number == 0){
+                                       continue;
+                               }
+                               cmd->result = (DID_OK << 16) | (QUEUE_FULL <<1);
+                               cmd->scsi_done(cmd);
+                       }
+                       d = d->next;
+               }
+       }
+}
+
+
+/*============================================================================
+ *  Routines from i2o subsystem
+ *============================================================================
+ */
+
+
+
+/*
+ *     Bring an I2O controller into HOLD state. See the spec.
+ */
+static int adpt_i2o_activate_hba(adpt_hba* pHba)
+{
+       int rcode;
+
+       if(pHba->initialized ) {
+               if (adpt_i2o_status_get(pHba) < 0) {
+                       if((rcode = adpt_i2o_reset_hba(pHba) != 0)){
+                               printk(KERN_WARNING"%s: Could NOT reset.\n", pHba->name);
+                               return rcode;
+                       }
+                       if (adpt_i2o_status_get(pHba) < 0) {
+                               printk(KERN_INFO "HBA not responding.\n");
+                               return -1;
+                       }
+               }
+
+               if(pHba->status_block->iop_state == ADAPTER_STATE_FAULTED) {
+                       printk(KERN_CRIT "%s: hardware fault\n", pHba->name);
+                       return -1;
+               }
+
+               if (pHba->status_block->iop_state == ADAPTER_STATE_READY ||
+                   pHba->status_block->iop_state == ADAPTER_STATE_OPERATIONAL ||
+                   pHba->status_block->iop_state == ADAPTER_STATE_HOLD ||
+                   pHba->status_block->iop_state == ADAPTER_STATE_FAILED) {
+                       adpt_i2o_reset_hba(pHba);                       
+                       if (adpt_i2o_status_get(pHba) < 0 || pHba->status_block->iop_state != ADAPTER_STATE_RESET) {
+                               printk(KERN_ERR "%s: Failed to initialize.\n", pHba->name);
+                               return -1;
+                       }
+               }
+       } else {
+               if((rcode = adpt_i2o_reset_hba(pHba) != 0)){
+                       printk(KERN_WARNING"%s: Could NOT reset.\n", pHba->name);
+                       return rcode;
+               }
+
+       }
+
+       if (adpt_i2o_init_outbound_q(pHba) < 0) {
+               return -1;
+       }
+
+       /* In HOLD state */
+       
+       if (adpt_i2o_hrt_get(pHba) < 0) {
+               return -1;
+       }
+
+       return 0;
+}
+
+/*
+ *     Bring a controller online into OPERATIONAL state. 
+ */
+static int adpt_i2o_online_hba(adpt_hba* pHba)
+{
+       if (adpt_i2o_systab_send(pHba) < 0) {
+               adpt_i2o_delete_hba(pHba);
+               return -1;
+       }
+       /* In READY state */
+
+       if (adpt_i2o_enable_hba(pHba) < 0) {
+               adpt_i2o_delete_hba(pHba);
+               return -1;
+       }
+
+       /* In OPERATIONAL state  */
+       return 0;
+}
+
+static s32 adpt_send_nop(adpt_hba*pHba,u32 m)
+{
+       u32 *msg;
+       ulong timeout = jiffies + 5*HZ;
+
+       while(m == EMPTY_QUEUE){
+               rmb();
+               m = readl(pHba->post_port);
+               if(m != EMPTY_QUEUE){
+                       break;
+               }
+               if(time_after(jiffies,timeout)){
+                       printk(KERN_ERR "%s: Timeout waiting for message frame!\n",pHba->name);
+                       return 2;
+               }
+       }
+       msg = (u32*)(pHba->msg_addr_virt + m);
+       writel( THREE_WORD_MSG_SIZE | SGL_OFFSET_0,&msg[0]);
+       writel( I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | 0,&msg[1]);
+       writel( 0,&msg[2]);
+       wmb();
+
+       writel(m, pHba->post_port);
+       wmb();
+       return 0;
+}
+
+static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
+{
+       u8 *status;
+       u32 *msg = NULL;
+       int i;
+       ulong timeout = jiffies + TMOUT_INITOUTBOUND*HZ;
+       u32* ptr;
+       u32 outbound_frame;  // This had to be a 32 bit address
+       u32 m;
+
+       do {
+               rmb();
+               m = readl(pHba->post_port);
+               if (m != EMPTY_QUEUE) {
+                       break;
+               }
+
+               if(time_after(jiffies,timeout)){
+                       printk(KERN_WARNING"%s: Timeout waiting for message frame\n",pHba->name);
+                       return -ETIMEDOUT;
+               }
+       } while(m == EMPTY_QUEUE);
+
+       msg=(u32 *)(pHba->msg_addr_virt+m);
+
+       status = kmalloc(4,GFP_KERNEL|ADDR32);
+       if (status==NULL) {
+               adpt_send_nop(pHba, m);
+               printk(KERN_WARNING"%s: IOP reset failed - no free memory.\n",
+                       pHba->name);
+               return -ENOMEM;
+       }
+       memset(status, 0, 4);
+
+       writel(EIGHT_WORD_MSG_SIZE| SGL_OFFSET_6, &msg[0]);
+       writel(I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID, &msg[1]);
+       writel(0, &msg[2]);
+       writel(0x0106, &msg[3]);        /* Transaction context */
+       writel(4096, &msg[4]);          /* Host page frame size */
+       writel((REPLY_FRAME_SIZE)<<16|0x80, &msg[5]);   /* Outbound msg frame size and Initcode */
+       writel(0xD0000004, &msg[6]);            /* Simple SG LE, EOB */
+       writel(virt_to_bus(status), &msg[7]);
+
+       writel(m, pHba->post_port);
+       wmb();
+
+       // Wait for the reply status to come back
+       do {
+               if (*status) {
+                       if (*status != 0x01 /*I2O_EXEC_OUTBOUND_INIT_IN_PROGRESS*/) {
+                               break;
+                       }
+               }
+               rmb();
+               if(time_after(jiffies,timeout)){
+                       printk(KERN_WARNING"%s: Timeout Initializing\n",pHba->name);
+                       kfree((void*)status);
+                       return -ETIMEDOUT;
+               }
+       } while (1);
+
+       // If the command was successful, fill the fifo with our reply
+       // message packets
+       if(*status != 0x04 /*I2O_EXEC_OUTBOUND_INIT_COMPLETE*/) {
+               kfree((void*)status);
+               return -2;
+       }
+       kfree((void*)status);
+
+       if(pHba->reply_pool != NULL){
+               kfree(pHba->reply_pool);
+       }
+
+       pHba->reply_pool = (u32*)kmalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32);
+       if(!pHba->reply_pool){
+               printk(KERN_ERR"%s: Could not allocate reply pool\n",pHba->name);
+               return -1;
+       }
+       memset(pHba->reply_pool, 0 , pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4);
+
+       ptr = pHba->reply_pool;
+       for(i = 0; i < pHba->reply_fifo_size; i++) {
+               outbound_frame = (u32)virt_to_bus(ptr);
+               writel(outbound_frame, pHba->reply_port);
+               wmb();
+               ptr +=  REPLY_FRAME_SIZE;
+       }
+       adpt_i2o_status_get(pHba);
+       return 0;
+}
+
+
+/*
+ * I2O System Table.  Contains information about
+ * all the IOPs in the system.  Used to inform IOPs
+ * about each other's existence.
+ *
+ * sys_tbl_ver is the CurrentChangeIndicator that is
+ * used by IOPs to track changes.
+ */
+
+
+
+static s32 adpt_i2o_status_get(adpt_hba* pHba)
+{
+       ulong timeout;
+       u32 m;
+       u32 *msg;
+       u8 *status_block=NULL;
+       ulong status_block_bus;
+
+       if(pHba->status_block == NULL) {
+               pHba->status_block = (i2o_status_block*)
+                       kmalloc(sizeof(i2o_status_block),GFP_KERNEL|ADDR32);
+               if(pHba->status_block == NULL) {
+                       printk(KERN_ERR
+                       "dpti%d: Get Status Block failed; Out of memory. \n", 
+                       pHba->unit);
+                       return -ENOMEM;
+               }
+       }
+       memset(pHba->status_block, 0, sizeof(i2o_status_block));
+       status_block = (u8*)(pHba->status_block);
+       status_block_bus = virt_to_bus(pHba->status_block);
+       timeout = jiffies+TMOUT_GETSTATUS*HZ;
+       do {
+               rmb();
+               m = readl(pHba->post_port);
+               if (m != EMPTY_QUEUE) {
+                       break;
+               }
+               if(time_after(jiffies,timeout)){
+                       printk(KERN_ERR "%s: Timeout waiting for message !\n",
+                                       pHba->name);
+                       return -ETIMEDOUT;
+               }
+       } while(m==EMPTY_QUEUE);
+
+       
+       msg=(u32*)(pHba->msg_addr_virt+m);
+
+       writel(NINE_WORD_MSG_SIZE|SGL_OFFSET_0, &msg[0]);
+       writel(I2O_CMD_STATUS_GET<<24|HOST_TID<<12|ADAPTER_TID, &msg[1]);
+       writel(1, &msg[2]);
+       writel(0, &msg[3]);
+       writel(0, &msg[4]);
+       writel(0, &msg[5]);
+       writel(((u32)status_block_bus)&0xffffffff, &msg[6]);
+       writel(0, &msg[7]);
+       writel(sizeof(i2o_status_block), &msg[8]); // 88 bytes
+
+       //post message
+       writel(m, pHba->post_port);
+       wmb();
+
+       while(status_block[87]!=0xff){
+               if(time_after(jiffies,timeout)){
+                       printk(KERN_ERR"dpti%d: Get status timeout.\n",
+                               pHba->unit);
+                       return -ETIMEDOUT;
+               }
+               rmb();
+       }
+
+       // Set up our number of outbound and inbound messages
+       pHba->post_fifo_size = pHba->status_block->max_inbound_frames;
+       if (pHba->post_fifo_size > MAX_TO_IOP_MESSAGES) {
+               pHba->post_fifo_size = MAX_TO_IOP_MESSAGES;
+       }
+
+       pHba->reply_fifo_size = pHba->status_block->max_outbound_frames;
+       if (pHba->reply_fifo_size > MAX_FROM_IOP_MESSAGES) {
+               pHba->reply_fifo_size = MAX_FROM_IOP_MESSAGES;
+       }
+
+       // Calculate the Scatter Gather list size
+       pHba->sg_tablesize = (pHba->status_block->inbound_frame_size * 4 -40)/ sizeof(struct sg_simple_element);
+       if (pHba->sg_tablesize > SG_LIST_ELEMENTS) {
+               pHba->sg_tablesize = SG_LIST_ELEMENTS;
+       }
+
+
+#ifdef DEBUG
+       printk("dpti%d: State = ",pHba->unit);
+       switch(pHba->status_block->iop_state) {
+               case 0x01:
+                       printk("INIT\n");
+                       break;
+               case 0x02:
+                       printk("RESET\n");
+                       break;
+               case 0x04:
+                       printk("HOLD\n");
+                       break;
+               case 0x05:
+                       printk("READY\n");
+                       break;
+               case 0x08:
+                       printk("OPERATIONAL\n");
+                       break;
+               case 0x10:
+                       printk("FAILED\n");
+                       break;
+               case 0x11:
+                       printk("FAULTED\n");
+                       break;
+               default:
+                       printk("%x (unknown!!)\n",pHba->status_block->iop_state);
+       }
+#endif
+       return 0;
+}
+
+/*
+ * Get the IOP's Logical Configuration Table
+ */
+static int adpt_i2o_lct_get(adpt_hba* pHba)
+{
+       u32 msg[8];
+       int ret;
+       u32 buf[16];
+
+       if ((pHba->lct_size == 0) || (pHba->lct == NULL)){
+               pHba->lct_size = pHba->status_block->expected_lct_size;
+       }
+       do {
+               if (pHba->lct == NULL) {
+                       pHba->lct = kmalloc(pHba->lct_size, GFP_KERNEL|ADDR32);
+                       if(pHba->lct == NULL) {
+                               printk(KERN_CRIT "%s: Lct Get failed. Out of memory.\n",
+                                       pHba->name);
+                               return -ENOMEM;
+                       }
+               }
+               memset(pHba->lct, 0, pHba->lct_size);
+
+               msg[0] = EIGHT_WORD_MSG_SIZE|SGL_OFFSET_6;
+               msg[1] = I2O_CMD_LCT_NOTIFY<<24 | HOST_TID<<12 | ADAPTER_TID;
+               msg[2] = 0;
+               msg[3] = 0;
+               msg[4] = 0xFFFFFFFF;    /* All devices */
+               msg[5] = 0x00000000;    /* Report now */
+               msg[6] = 0xD0000000|pHba->lct_size;
+               msg[7] = virt_to_bus(pHba->lct);
+
+               if ((ret=adpt_i2o_post_wait(pHba, msg, sizeof(msg), 360))) {
+                       printk(KERN_ERR "%s: LCT Get failed (status=%#10x.\n", 
+                               pHba->name, ret);       
+                       printk(KERN_ERR"Adaptec: Error Reading Hardware.\n");
+                       return ret;
+               }
+
+               if ((pHba->lct->table_size << 2) > pHba->lct_size) {
+                       pHba->lct_size = pHba->lct->table_size << 2;
+                       kfree(pHba->lct);
+                       pHba->lct = NULL;
+               }
+       } while (pHba->lct == NULL);
+
+       PDEBUG("%s: Hardware resource table read.\n", pHba->name);
+
+
+       // I2O_DPT_EXEC_IOP_BUFFERS_GROUP_NO;
+       if(adpt_i2o_query_scalar(pHba, 0 , 0x8000, -1, buf, sizeof(buf))>=0) {
+               pHba->FwDebugBufferSize = buf[1];
+               pHba->FwDebugBuffer_P    = pHba->base_addr_virt + buf[0];
+               pHba->FwDebugFlags_P     = pHba->FwDebugBuffer_P + FW_DEBUG_FLAGS_OFFSET;
+               pHba->FwDebugBLEDvalue_P = pHba->FwDebugBuffer_P + FW_DEBUG_BLED_OFFSET;
+               pHba->FwDebugBLEDflag_P  = pHba->FwDebugBLEDvalue_P + 1;
+               pHba->FwDebugStrLength_P = pHba->FwDebugBuffer_P + FW_DEBUG_STR_LENGTH_OFFSET;
+               pHba->FwDebugBuffer_P += buf[2]; 
+               pHba->FwDebugFlags = 0;
+       }
+
+       return 0;
+}
+
+static int adpt_i2o_build_sys_table(void)
+{
+       adpt_hba* pHba = NULL;
+       int count = 0;
+
+       sys_tbl_len = sizeof(struct i2o_sys_tbl) +      // Header + IOPs
+                               (hba_count) * sizeof(struct i2o_sys_tbl_entry);
+
+       if(sys_tbl)
+               kfree(sys_tbl);
+
+       sys_tbl = kmalloc(sys_tbl_len, GFP_KERNEL|ADDR32);
+       if(!sys_tbl) {
+               printk(KERN_WARNING "SysTab Set failed. Out of memory.\n");     
+               return -ENOMEM;
+       }
+       memset(sys_tbl, 0, sys_tbl_len);
+
+       sys_tbl->num_entries = hba_count;
+       sys_tbl->version = I2OVERSION;
+       sys_tbl->change_ind = sys_tbl_ind++;
+
+       for(pHba = hba_chain; pHba; pHba = pHba->next) {
+               // Get updated Status Block so we have the latest information
+               if (adpt_i2o_status_get(pHba)) {
+                       sys_tbl->num_entries--;
+                       continue; // try next one       
+               }
+
+               sys_tbl->iops[count].org_id = pHba->status_block->org_id;
+               sys_tbl->iops[count].iop_id = pHba->unit + 2;
+               sys_tbl->iops[count].seg_num = 0;
+               sys_tbl->iops[count].i2o_version = pHba->status_block->i2o_version;
+               sys_tbl->iops[count].iop_state = pHba->status_block->iop_state;
+               sys_tbl->iops[count].msg_type = pHba->status_block->msg_type;
+               sys_tbl->iops[count].frame_size = pHba->status_block->inbound_frame_size;
+               sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ??
+               sys_tbl->iops[count].iop_capabilities = pHba->status_block->iop_capabilities;
+               sys_tbl->iops[count].inbound_low = (u32)virt_to_bus((void*)pHba->post_port);
+               sys_tbl->iops[count].inbound_high = (u32)((u64)virt_to_bus((void*)pHba->post_port)>>32);
+
+               count++;
+       }
+
+#ifdef DEBUG
+{
+       u32 *table = (u32*)sys_tbl;
+       printk(KERN_DEBUG"sys_tbl_len=%d in 32bit words\n",(sys_tbl_len >>2));
+       for(count = 0; count < (sys_tbl_len >>2); count++) {
+               printk(KERN_INFO "sys_tbl[%d] = %0#10x\n", 
+                       count, table[count]);
+       }
+}
+#endif
+
+       return 0;
+}
+
+
+/*
+ *      Dump the information block associated with a given unit (TID)
+ */
+static void adpt_i2o_report_hba_unit(adpt_hba* pHba, struct i2o_device *d)
+{
+       char buf[64];
+       int unit = d->lct_data.tid;
+
+       printk(KERN_INFO "TID %3.3d ", unit);
+
+       if(adpt_i2o_query_scalar(pHba, unit, 0xF100, 3, buf, 16)>=0)
+       {
+               buf[16]=0;
+               printk(" Vendor: %-12.12s", buf);
+       }
+       if(adpt_i2o_query_scalar(pHba, unit, 0xF100, 4, buf, 16)>=0)
+       {
+               buf[16]=0;
+               printk(" Device: %-12.12s", buf);
+       }
+       if(adpt_i2o_query_scalar(pHba, unit, 0xF100, 6, buf, 8)>=0)
+       {
+               buf[8]=0;
+               printk(" Rev: %-12.12s\n", buf);
+       }
+#ifdef DEBUG
+        printk(KERN_INFO "\tClass: %.21s\n", adpt_i2o_get_class_name(d->lct_data.class_id));
+        printk(KERN_INFO "\tSubclass: 0x%04X\n", d->lct_data.sub_class);
+        printk(KERN_INFO "\tFlags: ");
+
+        if(d->lct_data.device_flags&(1<<0))
+                 printk("C");       // ConfigDialog requested
+        if(d->lct_data.device_flags&(1<<1))
+                 printk("U");       // Multi-user capable
+        if(!(d->lct_data.device_flags&(1<<4)))
+                 printk("P");       // Peer service enabled!
+        if(!(d->lct_data.device_flags&(1<<5)))
+                 printk("M");       // Mgmt service enabled!
+        printk("\n");
+#endif
+}
+
+#ifdef DEBUG
+/*
+ *     Do i2o class name lookup
+ */
+static const char *adpt_i2o_get_class_name(int class)
+{
+       int idx = 16;
+       static char *i2o_class_name[] = {
+               "Executive",
+               "Device Driver Module",
+               "Block Device",
+               "Tape Device",
+               "LAN Interface",
+               "WAN Interface",
+               "Fibre Channel Port",
+               "Fibre Channel Device",
+               "SCSI Device",
+               "ATE Port",
+               "ATE Device",
+               "Floppy Controller",
+               "Floppy Device",
+               "Secondary Bus Port",
+               "Peer Transport Agent",
+               "Peer Transport",
+               "Unknown"
+       };
+       
+       switch(class&0xFFF) {
+       case I2O_CLASS_EXECUTIVE:
+               idx = 0; break;
+       case I2O_CLASS_DDM:
+               idx = 1; break;
+       case I2O_CLASS_RANDOM_BLOCK_STORAGE:
+               idx = 2; break;
+       case I2O_CLASS_SEQUENTIAL_STORAGE:
+               idx = 3; break;
+       case I2O_CLASS_LAN:
+               idx = 4; break;
+       case I2O_CLASS_WAN:
+               idx = 5; break;
+       case I2O_CLASS_FIBRE_CHANNEL_PORT:
+               idx = 6; break;
+       case I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL:
+               idx = 7; break;
+       case I2O_CLASS_SCSI_PERIPHERAL:
+               idx = 8; break;
+       case I2O_CLASS_ATE_PORT:
+               idx = 9; break;
+       case I2O_CLASS_ATE_PERIPHERAL:
+               idx = 10; break;
+       case I2O_CLASS_FLOPPY_CONTROLLER:
+               idx = 11; break;
+       case I2O_CLASS_FLOPPY_DEVICE:
+               idx = 12; break;
+       case I2O_CLASS_BUS_ADAPTER_PORT:
+               idx = 13; break;
+       case I2O_CLASS_PEER_TRANSPORT_AGENT:
+               idx = 14; break;
+       case I2O_CLASS_PEER_TRANSPORT:
+               idx = 15; break;
+       }
+       return i2o_class_name[idx];
+}
+#endif
+
+
+static s32 adpt_i2o_hrt_get(adpt_hba* pHba)
+{
+       u32 msg[6];
+       int ret, size = sizeof(i2o_hrt);
+
+       do {
+               if (pHba->hrt == NULL) {
+                       pHba->hrt=kmalloc(size, GFP_KERNEL|ADDR32);
+                       if (pHba->hrt == NULL) {
+                               printk(KERN_CRIT "%s: Hrt Get failed; Out of memory.\n", pHba->name);
+                               return -ENOMEM;
+                       }
+               }
+
+               msg[0]= SIX_WORD_MSG_SIZE| SGL_OFFSET_4;
+               msg[1]= I2O_CMD_HRT_GET<<24 | HOST_TID<<12 | ADAPTER_TID;
+               msg[2]= 0;
+               msg[3]= 0;
+               msg[4]= (0xD0000000 | size);    /* Simple transaction */
+               msg[5]= virt_to_bus(pHba->hrt);   /* Dump it here */
+
+               if ((ret = adpt_i2o_post_wait(pHba, msg, sizeof(msg),20))) {
+                       printk(KERN_ERR "%s: Unable to get HRT (status=%#10x)\n", pHba->name, ret);
+                       return ret;
+               }
+
+               if (pHba->hrt->num_entries * pHba->hrt->entry_len << 2 > size) {
+                       size = pHba->hrt->num_entries * pHba->hrt->entry_len << 2;
+                       kfree(pHba->hrt);
+                       pHba->hrt = NULL;
+               }
+       } while(pHba->hrt == NULL);
+       return 0;
+}                                                                                                                                       
+
+/*
+ *      Query one scalar group value or a whole scalar group.
+ */                    
+static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid, 
+                       int group, int field, void *buf, int buflen)
+{
+       u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field };
+       u8  resblk[8+buflen]; /* 8 bytes for header */
+       int size;
+
+       if (field == -1)                /* whole group */
+                       opblk[4] = -1;
+
+       size = adpt_i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET, pHba, tid, 
+               opblk, sizeof(opblk), resblk, sizeof(resblk));
+                       
+       memcpy(buf, resblk+8, buflen);  /* cut off header */
+
+       if (size < 0)
+               return size;    
+
+       return buflen;
+}
+
+
+/*     Issue UTIL_PARAMS_GET or UTIL_PARAMS_SET
+ *
+ *     This function can be used for all UtilParamsGet/Set operations.
+ *     The OperationBlock is given in opblk-buffer, 
+ *     and results are returned in resblk-buffer.
+ *     Note that the minimum sized resblk is 8 bytes and contains
+ *     ResultCount, ErrorInfoSize, BlockStatus and BlockSize.
+ */
+static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid, 
+                 void *opblk, int oplen, void *resblk, int reslen)
+{
+       u32 msg[9]; 
+       u32 *res = (u32 *)resblk;
+       int wait_status;
+
+       msg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_5;
+       msg[1] = cmd << 24 | HOST_TID << 12 | tid; 
+       msg[2] = 0;
+       msg[3] = 0;
+       msg[4] = 0;
+       msg[5] = 0x54000000 | oplen;    /* OperationBlock */
+       msg[6] = virt_to_bus(opblk);
+       msg[7] = 0xD0000000 | reslen;   /* ResultBlock */
+       msg[8] = virt_to_bus(resblk);
+
+       if ((wait_status = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 20))) {
+               return wait_status;     /* -DetailedStatus */
+       }
+
+       if (res[1]&0x00FF0000) {        /* BlockStatus != SUCCESS */
+               printk(KERN_WARNING "%s: %s - Error:\n  ErrorInfoSize = 0x%02x, "
+                       "BlockStatus = 0x%02x, BlockSize = 0x%04x\n",
+                       pHba->name,
+                       (cmd == I2O_CMD_UTIL_PARAMS_SET) ? "PARAMS_SET"
+                                                        : "PARAMS_GET",   
+                       res[1]>>24, (res[1]>>16)&0xFF, res[1]&0xFFFF);
+               return -((res[1] >> 16) & 0xFF); /* -BlockStatus */
+       }
+
+        return 4 + ((res[1] & 0x0000FFFF) << 2); /* bytes used in resblk */ 
+}
+
+
+static s32 adpt_i2o_quiesce_hba(adpt_hba* pHba)
+{
+       u32 msg[4];
+       int ret;
+
+       adpt_i2o_status_get(pHba);
+
+       /* SysQuiesce discarded if IOP not in READY or OPERATIONAL state */
+
+       if((pHba->status_block->iop_state != ADAPTER_STATE_READY) &&
+          (pHba->status_block->iop_state != ADAPTER_STATE_OPERATIONAL)){
+               return 0;
+       }
+
+       msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
+       msg[1] = I2O_CMD_SYS_QUIESCE<<24|HOST_TID<<12|ADAPTER_TID;
+       msg[2] = 0;
+       msg[3] = 0;
+
+       if((ret = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 240))) {
+               printk(KERN_INFO"dpti%d: Unable to quiesce (status=%#x).\n",
+                               pHba->unit, -ret);
+       } else {
+               printk(KERN_INFO"dpti%d: Quiesced.\n",pHba->unit);
+       }
+
+       adpt_i2o_status_get(pHba);
+       return ret;
+}
+
+
+/* 
+ * Enable IOP. Allows the IOP to resume external operations.
+ */
+static int adpt_i2o_enable_hba(adpt_hba* pHba)
+{
+       u32 msg[4];
+       int ret;
+       
+       adpt_i2o_status_get(pHba);
+       if(!pHba->status_block){
+               return -ENOMEM;
+       }
+       /* Enable only allowed on READY state */
+       if(pHba->status_block->iop_state == ADAPTER_STATE_OPERATIONAL)
+               return 0;
+
+       if(pHba->status_block->iop_state != ADAPTER_STATE_READY)
+               return -EINVAL;
+
+       msg[0]=FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
+       msg[1]=I2O_CMD_SYS_ENABLE<<24|HOST_TID<<12|ADAPTER_TID;
+       msg[2]= 0;
+       msg[3]= 0;
+
+       if ((ret = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 240))) {
+               printk(KERN_WARNING"%s: Could not enable (status=%#10x).\n", 
+                       pHba->name, ret);
+       } else {
+               PDEBUG("%s: Enabled.\n", pHba->name);
+       }
+
+       adpt_i2o_status_get(pHba);
+       return ret;
+}
+
+
+static int adpt_i2o_systab_send(adpt_hba* pHba)
+{
+        u32 msg[12];
+        int ret;
+
+       msg[0] = I2O_MESSAGE_SIZE(12) | SGL_OFFSET_6;
+       msg[1] = I2O_CMD_SYS_TAB_SET<<24 | HOST_TID<<12 | ADAPTER_TID;
+       msg[2] = 0;
+       msg[3] = 0;
+       msg[4] = (0<<16) | ((pHba->unit+2) << 12); /* Host 0 IOP ID (unit + 2) */
+       msg[5] = 0;                                /* Segment 0 */
+
+       /* 
+        * Provide three SGL-elements:
+        * System table (SysTab), Private memory space declaration and 
+        * Private i/o space declaration  
+        */
+       msg[6] = 0x54000000 | sys_tbl_len;
+       msg[7] = virt_to_phys(sys_tbl);
+       msg[8] = 0x54000000 | 0;
+       msg[9] = 0;
+       msg[10] = 0xD4000000 | 0;
+       msg[11] = 0;
+
+       if ((ret=adpt_i2o_post_wait(pHba, msg, sizeof(msg), 120))) {
+               printk(KERN_INFO "%s: Unable to set SysTab (status=%#10x).\n", 
+                       pHba->name, ret);
+       }
+#ifdef DEBUG
+       else {
+               PINFO("%s: SysTab set.\n", pHba->name);
+       }
+#endif
+
+       return ret;     
+ }
+
+
+/*============================================================================
+ *
+ *============================================================================
+ */
+
+
+#ifdef UARTDELAY 
+
+static static void adpt_delay(int millisec)
+{
+       int i;
+       for (i = 0; i < millisec; i++) {
+               udelay(1000);   /* delay for one millisecond */
+       }
+}
+
+#endif
+
+static Scsi_Host_Template driver_template = DPT_I2O;
+#include "scsi_module.c"
+EXPORT_NO_SYMBOLS;
diff --git a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h
new file mode 100644 (file)
index 0000000..bf3e89b
--- /dev/null
@@ -0,0 +1,403 @@
+/***************************************************************************
+                          dpti.h  -  description
+                             -------------------
+    begin                : Thu Sep 7 2000
+    copyright            : (C) 2001 by Adaptec
+    email                : deanna_bonds@adaptec.com
+
+    See README.dpti for history, notes, license info, and credits
+ ***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef _DPT_H
+#define _DPT_H
+
+#ifndef LINUX_VERSION_CODE
+#include <linux/version.h>
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,00)
+#define MAX_TO_IOP_MESSAGES   (210)
+#else
+#define MAX_TO_IOP_MESSAGES   (255)
+#endif
+#define MAX_FROM_IOP_MESSAGES (255)
+
+
+/*
+ * SCSI interface function Prototypes
+ */
+
+static int adpt_proc_info(char *buffer, char **start, off_t offset,
+                 int length, int inode, int inout);
+static int adpt_detect(Scsi_Host_Template * sht);
+static int adpt_queue(Scsi_Cmnd * cmd, void (*cmdcomplete) (Scsi_Cmnd *));
+static int adpt_abort(Scsi_Cmnd * cmd);
+static int adpt_reset(Scsi_Cmnd* cmd);
+static int adpt_release(struct Scsi_Host *host);
+
+static const char *adpt_info(struct Scsi_Host *pSHost);
+static int adpt_bios_param(Disk * disk, kdev_t dev, int geom[]);
+
+static int adpt_bus_reset(Scsi_Cmnd* cmd);
+static int adpt_device_reset(Scsi_Cmnd* cmd);
+
+
+/*
+ * Scsi_Host_Template (see hosts.h) 
+ */
+
+#define DPT_DRIVER_NAME        "Adaptec I2O RAID"
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,00)
+#define DPT_I2O { \
+       proc_info: adpt_proc_info,                                      \
+       detect: adpt_detect,                                            \
+       release: adpt_release,                                          \
+       info: adpt_info,                                                \
+       queuecommand: adpt_queue,                                       \
+       eh_abort_handler: adpt_abort,                                   \
+       eh_device_reset_handler: adpt_device_reset,                     \
+       eh_bus_reset_handler: adpt_bus_reset,                           \
+       eh_host_reset_handler: adpt_reset,                              \
+       bios_param: adpt_bios_param,                                    \
+       can_queue: MAX_TO_IOP_MESSAGES ,/* max simultaneous cmds      */\
+       this_id: 7,                     /* scsi id of host adapter    */\
+       sg_tablesize: 0,                /* max scatter-gather cmds    */\
+       cmd_per_lun: 256,               /* cmds per lun (linked cmds) */\
+       use_clustering: ENABLE_CLUSTERING,                              \
+       use_new_eh_code: 1                                              \
+}
+
+#else                          /* KERNEL_VERSION > 2.2.16 */
+
+#define DPT_I2O { \
+       proc_info: adpt_proc_info,                                      \
+       detect: adpt_detect,                                            \
+       release: adpt_release,                                          \
+       info: adpt_info,                                                \
+       queuecommand: adpt_queue,                                       \
+       eh_abort_handler: adpt_abort,                                   \
+       eh_device_reset_handler: adpt_device_reset,                     \
+       eh_bus_reset_handler: adpt_bus_reset,                           \
+       eh_host_reset_handler: adpt_reset,                              \
+       bios_param: adpt_bios_param,                                    \
+       can_queue: MAX_TO_IOP_MESSAGES, /* max simultaneous cmds      */\
+       this_id: 7,                     /* scsi id of host adapter    */\
+       sg_tablesize: 0,                /* max scatter-gather cmds    */\
+       cmd_per_lun: 256,               /* cmds per lun (linked cmds) */\
+       use_clustering: ENABLE_CLUSTERING,                              \
+       use_new_eh_code: 1,                                             \
+       proc_name: "dpt_i2o"    /* this is the name of our proc node*/  \
+}
+#endif
+
+#ifndef HOSTS_C
+
+#include "dpt/sys_info.h"
+#include <linux/wait.h>
+#include "dpt/dpti_i2o.h"
+#include "dpt/dpti_ioctl.h"
+
+#define DPT_I2O_VERSION "2.4 Build 5"
+#define DPT_VERSION     2
+#define DPT_REVISION    '4'
+#define DPT_SUBREVISION '5'
+#define DPT_BETA       ""
+#define DPT_MONTH      8 
+#define DPT_DAY        7
+#define DPT_YEAR        (2001-1980)
+
+#define DPT_DRIVER     "dpt_i2o"
+#define DPTI_I2O_MAJOR (151)
+#define DPT_ORGANIZATION_ID (0x1B)        /* For Private Messages */
+#define DPTI_MAX_HBA   (16)
+#define MAX_CHANNEL     (5)    // Maximum Channel # Supported
+#define MAX_ID         (128)   // Maximum Target ID Supported
+
+/* Sizes in 4 byte words */
+#define REPLY_FRAME_SIZE  (17)
+#define MAX_MESSAGE_SIZE  (128)
+#define SG_LIST_ELEMENTS  (56)
+
+#define EMPTY_QUEUE           0xffffffff
+#define I2O_INTERRUPT_PENDING_B   (0x08)
+
+#define PCI_DPT_VENDOR_ID         (0x1044)     // DPT PCI Vendor ID
+#define PCI_DPT_DEVICE_ID         (0xA501)     // DPT PCI I2O Device ID
+#define PCI_DPT_RAPTOR_DEVICE_ID  (0xA511)     
+
+//#define REBOOT_NOTIFIER 1
+/* Debugging macro from Linux Device Drivers - Rubini */
+#undef PDEBUG
+#ifdef DEBUG
+//TODO add debug level switch
+#  define PDEBUG(fmt, args...)  printk(KERN_DEBUG "dpti: " fmt, ##args)
+#  define PDEBUGV(fmt, args...) printk(KERN_DEBUG "dpti: " fmt, ##args)
+#else
+# define PDEBUG(fmt, args...) /* not debugging: nothing */
+# define PDEBUGV(fmt, args...) /* not debugging: nothing */
+#endif
+
+#define PERROR(fmt, args...) printk(KERN_ERR fmt, ##args)
+#define PWARN(fmt, args...) printk(KERN_WARNING fmt, ##args)
+#define PINFO(fmt, args...) printk(KERN_INFO fmt, ##args)
+#define PCRIT(fmt, args...) printk(KERN_CRIT fmt, ##args)
+
+#define SHUTDOWN_SIGS  (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM))
+
+// Command timeouts
+#define FOREVER                        (0)
+#define TMOUT_INQUIRY          (20)
+#define TMOUT_FLUSH            (360/45)
+#define TMOUT_ABORT            (30)
+#define TMOUT_SCSI             (300)
+#define TMOUT_IOPRESET         (360)
+#define TMOUT_GETSTATUS                (15)
+#define TMOUT_INITOUTBOUND     (15)
+#define TMOUT_LCT              (360)
+
+
+#define I2O_SCSI_DEVICE_DSC_MASK                0x00FF
+
+#define I2O_DETAIL_STATUS_UNSUPPORTED_FUNCTION  0x000A
+
+#define I2O_SCSI_DSC_MASK                   0xFF00
+#define I2O_SCSI_DSC_SUCCESS                0x0000
+#define I2O_SCSI_DSC_REQUEST_ABORTED        0x0200
+#define I2O_SCSI_DSC_UNABLE_TO_ABORT        0x0300
+#define I2O_SCSI_DSC_COMPLETE_WITH_ERROR    0x0400
+#define I2O_SCSI_DSC_ADAPTER_BUSY           0x0500
+#define I2O_SCSI_DSC_REQUEST_INVALID        0x0600
+#define I2O_SCSI_DSC_PATH_INVALID           0x0700
+#define I2O_SCSI_DSC_DEVICE_NOT_PRESENT     0x0800
+#define I2O_SCSI_DSC_UNABLE_TO_TERMINATE    0x0900
+#define I2O_SCSI_DSC_SELECTION_TIMEOUT      0x0A00
+#define I2O_SCSI_DSC_COMMAND_TIMEOUT        0x0B00
+#define I2O_SCSI_DSC_MR_MESSAGE_RECEIVED    0x0D00
+#define I2O_SCSI_DSC_SCSI_BUS_RESET         0x0E00
+#define I2O_SCSI_DSC_PARITY_ERROR_FAILURE   0x0F00
+#define I2O_SCSI_DSC_AUTOSENSE_FAILED       0x1000
+#define I2O_SCSI_DSC_NO_ADAPTER             0x1100
+#define I2O_SCSI_DSC_DATA_OVERRUN           0x1200
+#define I2O_SCSI_DSC_UNEXPECTED_BUS_FREE    0x1300
+#define I2O_SCSI_DSC_SEQUENCE_FAILURE       0x1400
+#define I2O_SCSI_DSC_REQUEST_LENGTH_ERROR   0x1500
+#define I2O_SCSI_DSC_PROVIDE_FAILURE        0x1600
+#define I2O_SCSI_DSC_BDR_MESSAGE_SENT       0x1700
+#define I2O_SCSI_DSC_REQUEST_TERMINATED     0x1800
+#define I2O_SCSI_DSC_IDE_MESSAGE_SENT       0x3300
+#define I2O_SCSI_DSC_RESOURCE_UNAVAILABLE   0x3400
+#define I2O_SCSI_DSC_UNACKNOWLEDGED_EVENT   0x3500
+#define I2O_SCSI_DSC_MESSAGE_RECEIVED       0x3600
+#define I2O_SCSI_DSC_INVALID_CDB            0x3700
+#define I2O_SCSI_DSC_LUN_INVALID            0x3800
+#define I2O_SCSI_DSC_SCSI_TID_INVALID       0x3900
+#define I2O_SCSI_DSC_FUNCTION_UNAVAILABLE   0x3A00
+#define I2O_SCSI_DSC_NO_NEXUS               0x3B00
+#define I2O_SCSI_DSC_SCSI_IID_INVALID       0x3C00
+#define I2O_SCSI_DSC_CDB_RECEIVED           0x3D00
+#define I2O_SCSI_DSC_LUN_ALREADY_ENABLED    0x3E00
+#define I2O_SCSI_DSC_BUS_BUSY               0x3F00
+#define I2O_SCSI_DSC_QUEUE_FROZEN           0x4000
+
+
+#ifndef TRUE
+#define TRUE                  1
+#define FALSE                 0
+#endif
+
+#define HBA_FLAGS_INSTALLED_B       0x00000001 // Adapter Was Installed
+#define HBA_FLAGS_BLINKLED_B        0x00000002 // Adapter In Blink LED State
+#define HBA_FLAGS_IN_RESET     0x00000040      /* in reset */
+#define HBA_HOSTRESET_FAILED   0x00000080      /* adpt_resethost failed */
+
+
+// Device state flags
+#define DPTI_DEV_ONLINE    0x00
+#define DPTI_DEV_UNSCANNED 0x01
+#define DPTI_DEV_RESET    0x02
+#define DPTI_DEV_OFFLINE   0x04
+
+
+struct adpt_device {
+       struct adpt_device* next_lun;
+       u32     flags;
+       u32     type;
+       u32     capacity;
+       u32     block_size;
+       u8      scsi_channel;
+       u8      scsi_id;
+       u8      scsi_lun;
+       u8      state;
+       u16     tid;
+       struct i2o_device* pI2o_dev;
+       Scsi_Device *pScsi_dev;
+};
+
+struct adpt_channel {
+       struct adpt_device* device[MAX_ID];     /* used as an array of 128 scsi ids */
+       u8      scsi_id;
+       u8      type;
+       u16     tid;
+       u32     state;
+       struct i2o_device* pI2o_dev;
+};
+
+// HBA state flags
+#define DPTI_STATE_RESET       (0x01)
+#define DPTI_STATE_IOCTL       (0x02)
+
+typedef struct _adpt_hba {
+       struct _adpt_hba *next;
+       struct pci_dev *pDev;
+       struct Scsi_Host *host;
+       u32 state;
+       spinlock_t state_lock;
+       int unit;
+       int host_no;            /* SCSI host number */
+       u8 initialized;
+       u8 in_use;              /* is the management node open*/
+
+       char name[32];
+       char detail[55];
+
+       ulong base_addr_virt;
+       ulong msg_addr_virt;
+       ulong base_addr_phys;
+       ulong  post_port;
+       ulong  reply_port;
+       ulong  irq_mask;
+       u16  post_count;
+       u32  post_fifo_size;
+       u32  reply_fifo_size;
+       u32* reply_pool;
+       u32  sg_tablesize;      // Scatter/Gather List Size.       
+       u8  top_scsi_channel;
+       u8  top_scsi_id;
+       u8  top_scsi_lun;
+
+       i2o_status_block* status_block;
+       i2o_hrt* hrt;
+       i2o_lct* lct;
+       uint lct_size;
+       struct i2o_device* devices;
+       struct adpt_channel channel[MAX_CHANNEL];
+       struct proc_dir_entry* proc_entry;      /* /proc dir */
+
+       ulong FwDebugBuffer_P;  // Virtual Address Of FW Debug Buffer
+       u32   FwDebugBufferSize;        // FW Debug Buffer Size In Bytes
+       ulong FwDebugStrLength_P;       // Virtual Addr Of FW Debug String Len
+       ulong FwDebugFlags_P;   // Virtual Address Of FW Debug Flags 
+       ulong FwDebugBLEDflag_P;        // Virtual Addr Of FW Debug BLED
+       ulong FwDebugBLEDvalue_P;       // Virtual Addr Of FW Debug BLED
+       u32 FwDebugFlags;
+} adpt_hba;
+
+struct sg_simple_element {
+   u32  flag_count;
+   u32 addr_bus;
+}; 
+
+/*
+ * Function Prototypes
+ */
+
+static void adpt_i2o_sys_shutdown(void);
+static int adpt_init(void);
+static int adpt_i2o_build_sys_table(void);
+static void adpt_isr(int irq, void *dev_id, struct pt_regs *regs);
+#ifdef REBOOT_NOTIFIER
+static int adpt_reboot_event(struct notifier_block *n, ulong code, void *p);
+#endif
+
+static void adpt_i2o_report_hba_unit(adpt_hba* pHba, struct i2o_device *d);
+static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid, 
+                       int group, int field, void *buf, int buflen);
+#ifdef DEBUG
+static const char *adpt_i2o_get_class_name(int class);
+#endif
+static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid, 
+                 void *opblk, int oplen, void *resblk, int reslen);
+static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout);
+static int adpt_i2o_lct_get(adpt_hba* pHba);
+static int adpt_i2o_parse_lct(adpt_hba* pHba);
+static int adpt_i2o_activate_hba(adpt_hba* pHba);
+static int adpt_i2o_enable_hba(adpt_hba* pHba);
+static int adpt_i2o_install_device(adpt_hba* pHba, struct i2o_device *d);
+static s32 adpt_i2o_post_this(adpt_hba* pHba, u32* data, int len);
+static s32 adpt_i2o_quiesce_hba(adpt_hba* pHba);
+static s32 adpt_i2o_status_get(adpt_hba* pHba);
+static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba);
+static s32 adpt_i2o_hrt_get(adpt_hba* pHba);
+static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device* dptdevice);
+static s32 adpt_i2o_to_scsi(ulong reply, Scsi_Cmnd* cmd);
+static s32 adpt_scsi_register(adpt_hba* pHba,Scsi_Host_Template * sht);
+static s32 adpt_hba_reset(adpt_hba* pHba);
+static s32 adpt_i2o_reset_hba(adpt_hba* pHba);
+static s32 adpt_rescan(adpt_hba* pHba);
+static s32 adpt_i2o_reparse_lct(adpt_hba* pHba);
+static s32 adpt_send_nop(adpt_hba*pHba,u32 m);
+static void adpt_i2o_delete_hba(adpt_hba* pHba);
+static void adpt_select_queue_depths(struct Scsi_Host *host, Scsi_Device * devicelist);
+static void adpt_inquiry(adpt_hba* pHba);
+static void adpt_fail_posted_scbs(adpt_hba* pHba);
+static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun);
+static int adpt_install_hba(Scsi_Host_Template* sht, struct pci_dev* pDev) ;
+static int adpt_i2o_online_hba(adpt_hba* pHba);
+static void adpt_i2o_post_wait_complete(u32, int);
+static int adpt_i2o_systab_send(adpt_hba* pHba);
+
+static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg);
+static int adpt_open(struct inode *inode, struct file *file);
+static int adpt_close(struct inode *inode, struct file *file);
+
+
+#ifdef UARTDELAY
+static void adpt_delay(int millisec);
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
+static struct pci_dev* adpt_pci_find_device(uint vendor, struct pci_dev* from);
+#endif
+
+#if defined __ia64__ 
+static void adpt_ia64_info(sysInfo_S* si);
+#endif
+#if defined __sparc__ 
+static void adpt_sparc_info(sysInfo_S* si);
+#endif
+#if defined __alpha__ 
+static void adpt_sparc_info(sysInfo_S* si);
+#endif
+#if defined __i386__
+static void adpt_i386_info(sysInfo_S* si);
+#endif
+
+#define PRINT_BUFFER_SIZE     512
+
+#define HBA_FLAGS_DBG_FLAGS_MASK         0xffff0000    // Mask for debug flags
+#define HBA_FLAGS_DBG_KERNEL_PRINT_B     0x00010000    // Kernel Debugger Print
+#define HBA_FLAGS_DBG_FW_PRINT_B         0x00020000    // Firmware Debugger Print
+#define HBA_FLAGS_DBG_FUNCTION_ENTRY_B   0x00040000    // Function Entry Point
+#define HBA_FLAGS_DBG_FUNCTION_EXIT_B    0x00080000    // Function Exit
+#define HBA_FLAGS_DBG_ERROR_B            0x00100000    // Error Conditions
+#define HBA_FLAGS_DBG_INIT_B             0x00200000    // Init Prints
+#define HBA_FLAGS_DBG_OS_COMMANDS_B      0x00400000    // OS Command Info
+#define HBA_FLAGS_DBG_SCAN_B             0x00800000    // Device Scan
+
+#define FW_DEBUG_STR_LENGTH_OFFSET 0
+#define FW_DEBUG_FLAGS_OFFSET      4
+#define FW_DEBUG_BLED_OFFSET       8
+
+#define FW_DEBUG_FLAGS_NO_HEADERS_B    0x01
+#endif                         /* !HOSTS_C */
+#endif                         /* _DPT_H */
index c751c081917cec715ce4df429741a3df973a4222..1a283cad4280584b758ac843ce85aea58082f136 100644 (file)
@@ -1,8 +1,10 @@
 /************************************************************************
- * GDT ISA/EISA/PCI Disk Array Controller driver for Linux              *
+ * Linux driver for                                                     *  
+ * ICP vortex GmbH:    GDT ISA/EISA/PCI Disk Array Controllers          *
+ * Intel Corporation:  Storage RAID Controllers                         *
  *                                                                      *
  * gdth.c                                                               *
- * Copyright (C) 1995-01 ICP vortex Computersysteme GmbH, Achim Leubner *
+ * Copyright (C) 1995-01 ICP vortex, an Intel company,  Achim Leubner   *
  *                                                                      *
  * <achim@vortex.de>                                                    *
  *                                                                      *
  * along with this kernel; if not, write to the Free Software           *
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.            *
  *                                                                      *
- * Tested with Linux 1.2.13, ..., 2.2.18, ..., 2.4.2                    *
+ * Tested with Linux 1.2.13, ..., 2.2.19, ..., 2.4.7                    *
  *                                                                      *
  * $Log: gdth.c,v $
+ * Revision 1.57  2001/08/21 11:16:35  achim
+ * Bugfix free_irq()
+ *
+ * Revision 1.56  2001/08/09 11:19:39  achim
+ * Scsi_Host_Template changes
+ *
+ * Revision 1.55  2001/08/09 10:11:28  achim
+ * Command HOST_UNFREEZE_IO before cache service init.
+ *
+ * Revision 1.54  2001/07/20 13:48:12  achim
+ * Expand: gdth_analyse_hdrive() removed
+ *
+ * Revision 1.53  2001/07/17 09:52:49  achim
+ * Small OEM related change
+ *
+ * Revision 1.52  2001/06/19 15:06:20  achim
+ * New host command GDT_UNFREEZE_IO added
+ *
+ * Revision 1.51  2001/05/22 06:42:37  achim
+ * PCI: Subdevice ID added
+ *
+ * Revision 1.50  2001/05/17 13:42:16  achim
+ * Support for Intel Storage RAID Controllers added
+ *
+ * Revision 1.50  2001/05/17 12:12:34  achim
+ * Support for Intel Storage RAID Controllers added
+ *
  * Revision 1.49  2001/03/15 15:07:17  achim
  * New __setup interface for boot command line options added
  *
  * Initial revision
  *
  ************************************************************************/
-#ident "$Id: gdth.c,v 1.49 2001/03/15 15:07:17 achim Exp $" 
+#ident "$Id: gdth.c,v 1.57 2001/08/21 11:16:35 achim Exp $" 
 
 /* All GDT Disk Array Controllers are fully supported by this driver.
  * This includes the PCI/EISA/ISA SCSI Disk Array Controllers and the
 #else
 #include <linux/bios32.h>
 #endif
-#if LINUX_VERSION_CODE >= 0x020126
-#include <linux/init.h>
-#endif
 
 #include <asm/dma.h>
 #include <asm/system.h>
@@ -344,6 +370,8 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive);
 static int gdth_search_eisa(ushort eisa_adr);
 static int gdth_search_isa(ulong32 bios_adr);
 static int gdth_search_pci(gdth_pci_str *pcistr);
+static void gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, 
+                            ushort vendor, ushort dev);
 static void gdth_sort_pci(gdth_pci_str *pcistr, int cnt);
 static int gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha);
 static int gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha);
@@ -588,8 +616,10 @@ static unchar gdth_direction_tab[0x100] = {
 /* __initfunc, __initdata macros */
 #if LINUX_VERSION_CODE >= 0x020322
 #define GDTH_INITFUNC(type, func)       type __init func 
+#include <linux/init.h>
 #elif LINUX_VERSION_CODE >= 0x020126
 #define GDTH_INITFUNC(type, func)       __initfunc(type func)
+#include <linux/init.h>
 #else
 #define GDTH_INITFUNC(type, func)       type func
 #define __initdata
@@ -752,9 +782,29 @@ GDTH_INITFUNC(static int, gdth_search_isa(ulong32 bios_adr))
 
 
 GDTH_INITFUNC(static int, gdth_search_pci(gdth_pci_str *pcistr))
+{
+    ushort device, cnt;
+    
+    TRACE(("gdth_search_pci()\n"));
+
+    cnt = 0;
+    for (device = 0; device <= PCI_DEVICE_ID_VORTEX_GDT6555; ++device)
+        gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, device);
+    for (device = PCI_DEVICE_ID_VORTEX_GDT6x17RP; 
+         device <= PCI_DEVICE_ID_VORTEX_GDTMAXRP; ++device)
+        gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, device);
+    gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, 
+                    PCI_DEVICE_ID_VORTEX_GDTNEWRX);
+    gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_INTEL,
+                    PCI_DEVICE_ID_INTEL_SRC);
+    return cnt;
+}
+
+
+GDTH_INITFUNC(static void, gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt,
+                                           ushort vendor, ushort device))
 {
     ulong base0, base1, base2;
-    ushort device_id, cnt;
 #if LINUX_VERSION_CODE >= 0x2015C
     struct pci_dev *pdev;
 #else
@@ -762,147 +812,150 @@ GDTH_INITFUNC(static int, gdth_search_pci(gdth_pci_str *pcistr))
     ushort idx;
 #endif
     
-    TRACE(("gdth_search_pci()\n"));
+    TRACE(("gdth_search_dev() cnt %d vendor %x device %x\n",
+          *cnt, vendor, device));
 
-    cnt = 0;
-    for (device_id = 0; device_id <= PCI_DEVICE_ID_VORTEX_GDTMAXRP; 
-         ++device_id) {
-        if (device_id > PCI_DEVICE_ID_VORTEX_GDT6555 &&
-            device_id < PCI_DEVICE_ID_VORTEX_GDT6x17RP)
-            continue;
 #if LINUX_VERSION_CODE >= 0x20363
-        pdev = NULL;
-        while ((pdev = pci_find_device(PCI_VENDOR_ID_VORTEX,device_id,pdev)) 
-               != NULL) {
-            if (pci_enable_device(pdev))
+    pdev = NULL;
+    while ((pdev = pci_find_device(vendor, device, pdev)) 
+           != NULL) {
+        if (pci_enable_device(pdev))
+            continue;
+        if (*cnt >= MAXHA)
+            return;
+        /* GDT PCI controller found, resources are already in pdev */
+        pcistr[*cnt].pdev = pdev;
+        pcistr[*cnt].vendor_id = vendor;
+        pcistr[*cnt].device_id = device;
+        pcistr[*cnt].subdevice_id = pdev->subsystem_device;
+        pcistr[*cnt].bus = pdev->bus->number;
+        pcistr[*cnt].device_fn = pdev->devfn;
+        pcistr[*cnt].irq = pdev->irq;
+        base0 = pci_resource_flags(pdev, 0);
+        base1 = pci_resource_flags(pdev, 1);
+        base2 = pci_resource_flags(pdev, 2);
+        if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B ||   /* GDT6000/B */
+            device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) {  /* MPR */
+            if (!(base0 & IORESOURCE_MEM)) 
                 continue;
-            if (cnt >= MAXHA)
-                return cnt;
-            /* GDT PCI controller found, resources are already in pdev */
-            pcistr[cnt].pdev = pdev;
-            pcistr[cnt].device_id = device_id;
-            pcistr[cnt].bus = pdev->bus->number;
-            pcistr[cnt].device_fn = pdev->devfn;
-            pcistr[cnt].irq = pdev->irq;
-            base0 = pci_resource_flags(pdev, 0);
-            base1 = pci_resource_flags(pdev, 1);
-            base2 = pci_resource_flags(pdev, 2);
-            if (device_id <= PCI_DEVICE_ID_VORTEX_GDT6000B ||   /* GDT6000/B */
-                device_id >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) {  /* MPR */
-                if (!(base0 & IORESOURCE_MEM)) 
-                    continue;
-                pcistr[cnt].dpmem = pci_resource_start(pdev, 0);
-            } else {                                  /* GDT6110, GDT6120, .. */
-                if (!(base0 & IORESOURCE_MEM) ||
-                    !(base2 & IORESOURCE_MEM) ||
-                    !(base1 & IORESOURCE_IO)) 
-                    continue;
-                pcistr[cnt].dpmem = pci_resource_start(pdev, 2);
-                pcistr[cnt].io_mm = pci_resource_start(pdev, 0);
-                pcistr[cnt].io    = pci_resource_start(pdev, 1);
-            }
-            TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
-                    pcistr[cnt].bus, PCI_SLOT(pcistr[cnt].device_fn), 
-                    pcistr[cnt].irq, pcistr[cnt].dpmem));
-            cnt++;
-        }       
+            pcistr[*cnt].dpmem = pci_resource_start(pdev, 0);
+        } else {                                  /* GDT6110, GDT6120, .. */
+            if (!(base0 & IORESOURCE_MEM) ||
+                !(base2 & IORESOURCE_MEM) ||
+                !(base1 & IORESOURCE_IO)) 
+                continue;
+            pcistr[*cnt].dpmem = pci_resource_start(pdev, 2);
+            pcistr[*cnt].io_mm = pci_resource_start(pdev, 0);
+            pcistr[*cnt].io    = pci_resource_start(pdev, 1);
+        }
+        TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
+                pcistr[*cnt].bus, PCI_SLOT(pcistr[*cnt].device_fn), 
+                pcistr[*cnt].irq, pcistr[*cnt].dpmem));
+        (*cnt)++;
+    }       
 #elif LINUX_VERSION_CODE >= 0x2015C
-        pdev = NULL;
-        while ((pdev = pci_find_device(PCI_VENDOR_ID_VORTEX,device_id,pdev)) 
-               != NULL) {
-            if (cnt >= MAXHA)
-                return cnt;
-            /* GDT PCI controller found, resources are already in pdev */
-            pcistr[cnt].pdev = pdev;
-            pcistr[cnt].device_id = device_id;
-            pcistr[cnt].bus = pdev->bus->number;
-            pcistr[cnt].device_fn = pdev->devfn;
-            pcistr[cnt].irq = pdev->irq;
-            base0 = pdev->base_address[0];
-            base1 = pdev->base_address[1];
-            base2 = pdev->base_address[2];
-            if (device_id <= PCI_DEVICE_ID_VORTEX_GDT6000B ||   /* GDT6000/B */
-                device_id >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) {  /* MPR */
-                if ((base0 & PCI_BASE_ADDRESS_SPACE) != 
-                    PCI_BASE_ADDRESS_SPACE_MEMORY)
-                    continue;
-                pcistr[cnt].dpmem = base0 & PCI_BASE_ADDRESS_MEM_MASK;
-            } else {                                  /* GDT6110, GDT6120, .. */
-                if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
-                    PCI_BASE_ADDRESS_SPACE_MEMORY ||
-                    (base2 & PCI_BASE_ADDRESS_SPACE) !=
-                    PCI_BASE_ADDRESS_SPACE_MEMORY ||
-                    (base1 & PCI_BASE_ADDRESS_SPACE) !=
-                    PCI_BASE_ADDRESS_SPACE_IO)
-                    continue;
-                pcistr[cnt].dpmem = base2 & PCI_BASE_ADDRESS_MEM_MASK;
-                pcistr[cnt].io_mm = base0 & PCI_BASE_ADDRESS_MEM_MASK;
-                pcistr[cnt].io    = base1 & PCI_BASE_ADDRESS_IO_MASK;
-            }
-            TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
-                    pcistr[cnt].bus, PCI_SLOT(pcistr[cnt].device_fn), 
-                    pcistr[cnt].irq, pcistr[cnt].dpmem));
-            cnt++;
-        }       
+    pdev = NULL;
+    while ((pdev = pci_find_device(vendor, device, pdev)) 
+           != NULL) {
+        if (*cnt >= MAXHA)
+            return;
+        /* GDT PCI controller found, resources are already in pdev */
+        pcistr[*cnt].pdev = pdev;
+        pcistr[*cnt].vendor_id = vendor;
+        pcistr[*cnt].device_id = device;
+        pcistr[*cnt].bus = pdev->bus->number;
+        pcistr[*cnt].device_fn = pdev->devfn;
+        pcibios_read_config_word(pcistr[*cnt].bus, pcistr[*cnt].device_fn,
+                                 PCI_SUBSYSTEM_ID, &pcistr[*cnt].subdevice_id);
+        pcistr[*cnt].irq = pdev->irq;
+        base0 = pdev->base_address[0];
+        base1 = pdev->base_address[1];
+        base2 = pdev->base_address[2];
+        if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B ||   /* GDT6000/B */
+            device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) {  /* MPR */
+            if ((base0 & PCI_BASE_ADDRESS_SPACE) != 
+                PCI_BASE_ADDRESS_SPACE_MEMORY)
+                continue;
+            pcistr[*cnt].dpmem = base0 & PCI_BASE_ADDRESS_MEM_MASK;
+        } else {                                  /* GDT6110, GDT6120, .. */
+            if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
+                PCI_BASE_ADDRESS_SPACE_MEMORY ||
+                (base2 & PCI_BASE_ADDRESS_SPACE) !=
+                PCI_BASE_ADDRESS_SPACE_MEMORY ||
+                (base1 & PCI_BASE_ADDRESS_SPACE) !=
+                PCI_BASE_ADDRESS_SPACE_IO)
+                continue;
+            pcistr[*cnt].dpmem = base2 & PCI_BASE_ADDRESS_MEM_MASK;
+            pcistr[*cnt].io_mm = base0 & PCI_BASE_ADDRESS_MEM_MASK;
+            pcistr[*cnt].io    = base1 & PCI_BASE_ADDRESS_IO_MASK;
+        }
+        TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
+                pcistr[*cnt].bus, PCI_SLOT(pcistr[*cnt].device_fn), 
+                pcistr[*cnt].irq, pcistr[*cnt].dpmem));
+        (*cnt)++;
+    }       
 #else   
-        idx = 0;
-        while (!pcibios_find_device(PCI_VENDOR_ID_VORTEX,device_id,idx++,
-                                    &pcistr[cnt].bus,&pcistr[cnt].device_fn)) {
-            if (cnt >= MAXHA)
-                return cnt;
-            /* GDT PCI ctr. found, now read resources from config space */
+    idx = 0;
+    while (!pcibios_find_device(vendor, device, idx++,
+                                &pcistr[*cnt].bus,&pcistr[*cnt].device_fn)) {
+        if (*cnt >= MAXHA)
+            return;
+        /* GDT PCI ctr. found, now read resources from config space */
 #if LINUX_VERSION_CODE >= 0x010300
 #define GDTH_BASEP      (int *)
 #else
 #define GDTH_BASEP
 #endif
-            if ((error = pcibios_read_config_dword(pcistr[cnt].bus,
-                                                   pcistr[cnt].device_fn,
-                                                   PCI_BASE_ADDRESS_0,
-                                                   GDTH_BASEP&base0)) ||
-                (error = pcibios_read_config_dword(pcistr[cnt].bus,
-                                                   pcistr[cnt].device_fn,
-                                                   PCI_BASE_ADDRESS_1,
-                                                   GDTH_BASEP&base1)) ||
-                (error = pcibios_read_config_dword(pcistr[cnt].bus,
-                                                   pcistr[cnt].device_fn,
-                                                   PCI_BASE_ADDRESS_2,
-                                                   GDTH_BASEP&base2)) ||
-                (error = pcibios_read_config_byte(pcistr[cnt].bus,
-                                                  pcistr[cnt].device_fn,
-                                                  PCI_INTERRUPT_LINE,
-                                                  &pcistr[cnt].irq))) {
-                printk("GDT-PCI: error %d reading configuration space", error);
+        if ((error = pcibios_read_config_dword(pcistr[*cnt].bus,
+                                               pcistr[*cnt].device_fn,
+                                               PCI_BASE_ADDRESS_0,
+                                               GDTH_BASEP&base0)) ||
+            (error = pcibios_read_config_dword(pcistr[*cnt].bus,
+                                               pcistr[*cnt].device_fn,
+                                               PCI_BASE_ADDRESS_1,
+                                               GDTH_BASEP&base1)) ||
+            (error = pcibios_read_config_dword(pcistr[*cnt].bus,
+                                               pcistr[*cnt].device_fn,
+                                               PCI_BASE_ADDRESS_2,
+                                               GDTH_BASEP&base2)) ||
+            (error = pcibios_read_config_word(pcistr[*cnt].bus,
+                                              pcistr[*cnt].device_fn,
+                                              PCI_SUBSYSTEM_ID,
+                                              &pcistr[*cnt].subdevice_id)) ||
+            (error = pcibios_read_config_byte(pcistr[*cnt].bus,
+                                              pcistr[*cnt].device_fn,
+                                              PCI_INTERRUPT_LINE,
+                                              &pcistr[*cnt].irq))) {
+            printk("GDT-PCI: error %d reading configuration space", error);
+            continue;
+        }
+        pcistr[*cnt].vendor_id = vendor;
+        pcistr[*cnt].device_id = device;
+        if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B ||   /* GDT6000/B */
+            device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) {  /* MPR */
+            if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
+                PCI_BASE_ADDRESS_SPACE_MEMORY)
                 continue;
-            }
-            pcistr[cnt].device_id = device_id;
-            if (device_id <= PCI_DEVICE_ID_VORTEX_GDT6000B ||   /* GDT6000/B */
-                device_id >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) {  /* MPR */
-                if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
-                    PCI_BASE_ADDRESS_SPACE_MEMORY)
-                    continue;
-                pcistr[cnt].dpmem = base0 & PCI_BASE_ADDRESS_MEM_MASK;
-            } else {                                    /* GDT6110, GDT6120, .. */
-                if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
-                    PCI_BASE_ADDRESS_SPACE_MEMORY ||
-                    (base2 & PCI_BASE_ADDRESS_SPACE) !=
-                    PCI_BASE_ADDRESS_SPACE_MEMORY ||
-                    (base1 & PCI_BASE_ADDRESS_SPACE) !=
-                    PCI_BASE_ADDRESS_SPACE_IO)
-                    continue;
-                pcistr[cnt].dpmem = base2 & PCI_BASE_ADDRESS_MEM_MASK;
-                pcistr[cnt].io_mm = base0 & PCI_BASE_ADDRESS_MEM_MASK;
-                pcistr[cnt].io    = base1 & PCI_BASE_ADDRESS_IO_MASK;
-            }
-            TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
-                    pcistr[cnt].bus, PCI_SLOT(pcistr[cnt].device_fn), 
-                    pcistr[cnt].irq, pcistr[cnt].dpmem));
-            cnt++;
+            pcistr[*cnt].dpmem = base0 & PCI_BASE_ADDRESS_MEM_MASK;
+        } else {                                    /* GDT6110, GDT6120, .. */
+            if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
+                PCI_BASE_ADDRESS_SPACE_MEMORY ||
+                (base2 & PCI_BASE_ADDRESS_SPACE) !=
+                PCI_BASE_ADDRESS_SPACE_MEMORY ||
+                (base1 & PCI_BASE_ADDRESS_SPACE) !=
+                PCI_BASE_ADDRESS_SPACE_IO)
+                continue;
+            pcistr[*cnt].dpmem = base2 & PCI_BASE_ADDRESS_MEM_MASK;
+            pcistr[*cnt].io_mm = base0 & PCI_BASE_ADDRESS_MEM_MASK;
+            pcistr[*cnt].io    = base1 & PCI_BASE_ADDRESS_IO_MASK;
         }
+        TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
+                pcistr[*cnt].bus, PCI_SLOT(pcistr[*cnt].device_fn), 
+                pcistr[*cnt].irq, pcistr[*cnt].dpmem));
+        (*cnt)++;
+    }
 #endif
-    }   
-    return cnt;
-}
+}   
 
 
 GDTH_INITFUNC(static void, gdth_sort_pci(gdth_pci_str *pcistr, int cnt))
@@ -982,6 +1035,7 @@ GDTH_INITFUNC(static int, gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha))
 
     /* detect IRQ */ 
     if ((id = inl(eisa_adr+ID0REG)) == GDT3_ID) {
+        ha->oem_id = OEM_ID_ICP;
         ha->type = GDT_EISA;
         ha->stype = id;
         outl(1,eisa_adr+MAILBOXREG+8);
@@ -1025,6 +1079,7 @@ GDTH_INITFUNC(static int, gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha))
         if (eisacf > 4)                         /* level triggered */
             eisacf -= 4;
         ha->irq = gdth_irq_tab[eisacf];
+        ha->oem_id = OEM_ID_ICP;
         ha->type = GDT_EISA;
         ha->stype = id;
     }
@@ -1101,6 +1156,7 @@ GDTH_INITFUNC(static int, gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha))
         return 0;
     }
 
+    ha->oem_id = OEM_ID_ICP;
     ha->type = GDT_ISA;
     ha->ic_all_size = sizeof(dp2_ptr->u);
     ha->stype= GDT2_ID;
@@ -1144,9 +1200,14 @@ GDTH_INITFUNC(static int, gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha))
 
     TRACE(("gdth_init_pci()\n"));
 
+    if (pcistr->vendor_id == PCI_VENDOR_ID_INTEL)
+        ha->oem_id = OEM_ID_INTEL;
+    else
+        ha->oem_id = OEM_ID_ICP;
     ha->brd_phys = (pcistr->bus << 8) | (pcistr->device_fn & 0xf8);
-    ha->stype    = (ulong32)pcistr->device_id;
-    ha->irq      = pcistr->irq;
+    ha->stype = (ulong32)pcistr->device_id;
+    ha->subdevice_id = pcistr->subdevice_id;
+    ha->irq = pcistr->irq;
     
     if (ha->stype <= PCI_DEVICE_ID_VORTEX_GDT6000B) {  /* GDT6000/B */
         TRACE2(("init_pci() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq));
@@ -1914,7 +1975,10 @@ GDTH_INITFUNC(static int, gdth_search_drives(int hanum))
     /* 3. send to controller firmware */
     gdth_internal_cmd(hanum,SCREENSERVICE,GDT_REALTIME, *(ulong32 *)&rtc[0],
                       *(ulong32 *)&rtc[4], *(ulong32 *)&rtc[8]);
-#endif   
+#endif  
+    /* unfreeze all IOs */
+    gdth_internal_cmd(hanum,CACHESERVICE,GDT_UNFREEZE_IO,0,0,0);
  
     /* initialize cache service */
     if (!gdth_internal_cmd(hanum,CACHESERVICE,GDT_INIT,LINUX_OS,0,0)) {
@@ -2599,7 +2663,10 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp)
         inq.version   = 2;
         inq.resp_aenc = 2;
         inq.add_length= 32;
-        strcpy(inq.vendor,"ICP    ");
+        if (ha->oem_id == OEM_ID_INTEL)
+            strcpy(inq.vendor,"Intel  ");
+        else 
+            strcpy(inq.vendor,"ICP    ");
         sprintf(inq.product,"Host Drive  #%02d",t);
         strcpy(inq.revision,"   ");
         gdth_copy_internal_data(scp,(char*)&inq,sizeof(gdth_inq_data));
@@ -3690,7 +3757,7 @@ static int gdth_async_event(int hanum)
         if (ha->service == CACHESERVICE && ha->status == 56) {
             TRACE2(("gdth_async_event(): new host drive %d created\n",
                     (ushort)ha->info));
-            gdth_analyse_hdrive(hanum, (ushort)ha->info);
+            /* gdth_analyse_hdrive(hanum, (ushort)ha->info); */
         }   
     }
     return 1;
@@ -3938,7 +4005,7 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
             if (request_dma(ha->drq,"gdth")) {
                 printk("GDT-ISA: Unable to allocate DMA channel\n");
 #if LINUX_VERSION_CODE >= 0x010346 
-                free_irq(ha->irq,NULL);
+                free_irq(ha->irq,ha);
 #else
                 free_irq(ha->irq);
 #endif
@@ -3984,7 +4051,7 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
                     scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
 #endif
 #if LINUX_VERSION_CODE >= 0x010346 
-                free_irq(ha->irq,NULL);
+                free_irq(ha->irq,ha);
 #else
                 free_irq(ha->irq);
 #endif
@@ -4085,7 +4152,7 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
                     scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
 #endif
 #if LINUX_VERSION_CODE >= 0x010346 
-                free_irq(ha->irq,NULL);
+                free_irq(ha->irq,ha);
 #else
                 free_irq(ha->irq);
 #endif
@@ -4194,7 +4261,7 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
                     scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
 #endif
 #if LINUX_VERSION_CODE >= 0x010346 
-                free_irq(ha->irq,NULL);
+                free_irq(ha->irq,ha);
 #else
                 free_irq(ha->irq);
 #endif
@@ -4264,7 +4331,7 @@ int gdth_release(struct Scsi_Host *shp)
 
         if (shp->irq) {
 #if LINUX_VERSION_CODE >= 0x010346
-            free_irq(shp->irq,NULL);
+            free_irq(shp->irq,ha);
 #else
             free_irq(shp->irq);
 #endif
index c4dcb9164b26dc9ce53588928a5955bdb89e50d6..d97d88382c7bda75b797e81f60be31480d07e50d 100644 (file)
@@ -10,7 +10,7 @@
  *
  * <achim@vortex.de>
  *
- * $Id: gdth.h,v 1.38 2001/03/15 15:06:23 achim Exp $
+ * $Id: gdth.h,v 1.44 2001/08/21 11:19:05 achim Exp $
  */
 
 #include <linux/version.h>
 /* defines, macros */
 
 /* driver version */
-#define GDTH_VERSION_STR        "1.28"
-#define GDTH_VERSION            1
-#define GDTH_SUBVERSION         28
+#define GDTH_VERSION_STR        "2.03"
+#define GDTH_VERSION            2
+#define GDTH_SUBVERSION         3
 
 /* protocol version */
 #define PROTOCOL_VERSION        1
 
+/* OEM IDs */
+#define OEM_ID_ICP     0x941c
+#define OEM_ID_INTEL   0x8000
+
 /* controller classes */
 #define GDT_ISA         0x01                    /* ISA controller */
 #define GDT_EISA        0x02                    /* EISA controller */
@@ -54,6 +58,9 @@
 #ifndef PCI_VENDOR_ID_VORTEX
 #define PCI_VENDOR_ID_VORTEX            0x1119  /* PCI controller vendor ID */
 #endif
+#ifndef PCI_VENDOR_ID_INTEL
+#define PCI_VENDOR_ID_INTEL             0x8086  
+#endif
 
 #ifndef PCI_DEVICE_ID_VORTEX_GDT60x0
 /* GDT_PCI */
 #define PCI_DEVICE_ID_VORTEX_GDTMAXRP   0x2ff   
 #endif
 
+#ifndef PCI_DEVICE_ID_VORTEX_GDTNEWRX
+/* new GDT Rx Controller */
+#define PCI_DEVICE_ID_VORTEX_GDTNEWRX  0x300
+#endif
+       
+#ifndef PCI_DEVICE_ID_INTEL_SRC
+/* Intel Storage RAID Controller */
+#define PCI_DEVICE_ID_INTEL_SRC                0x600
+#endif
+
 /* limits */
 #define GDTH_SCRATCH    PAGE_SIZE               /* 4KB scratch buffer */
 #define GDTH_SCRATCH_ORD 0                      /* order 0 means 1 page */
 #define GDT_CLUST_INFO  22                      /* cluster info */
 #define GDT_RW_ATTRIBS  23                      /* R/W attribs (write thru,..)*/
 #define GDT_CLUST_RESET 24                      /* releases the cluster drives*/
+#define GDT_FREEZE_IO   25                      /* freezes all IOs */
+#define GDT_UNFREEZE_IO 26                      /* unfreezes all IOs */
 
 /* raw service commands */
 #define GDT_RESERVE     14                      /* reserve dev. to raw serv. */
@@ -843,7 +862,9 @@ typedef struct {
 #if LINUX_VERSION_CODE >= 0x02015C
     struct pci_dev      *pdev;
 #endif
+    ushort              vendor_id;              /* vendor (ICP, Intel, ..) */
     ushort              device_id;              /* device ID (0,..,9) */
+    ushort              subdevice_id;           /* sub device ID */
     unchar              bus;                    /* PCI bus */
     unchar              device_fn;              /* PCI device/function no. */
     ulong               dpmem;                  /* DPRAM address */
@@ -855,9 +876,11 @@ typedef struct {
 
 /* controller information structure */
 typedef struct {
+    ushort              oem_id;                 /* OEM */
     ushort              type;                   /* controller class */
     ushort              raw_feat;               /* feat. raw service (s/g,..) */
-    ulong32             stype;                  /* controller subtype */
+    ulong32             stype;                  /* subtype (PCI: device ID) */
+    ushort              subdevice_id;           /* sub device ID (PCI) */
     ushort              fw_vers;                /* firmware version */
     ushort              cache_feat;             /* feat. cache serv. (s/g,..) */
     ushort              bmic;                   /* BMIC address (EISA) */
index 66f3d85c257b50a3b0bda0a72bf6a3084247ae40..ee6eb78a59b518a2256e30b0ceebf0a15978603d 100644 (file)
@@ -2,7 +2,7 @@
 #define _GDTH_IOCTL_H
 
 /* gdth_ioctl.h
- * $Id: gdth_ioctl.h,v 1.9 2001/01/10 14:39:37 achim Exp $
+ * $Id: gdth_ioctl.h,v 1.10 2001/05/22 06:28:59 achim Exp $
  */
 
 /* IOCTLs */
@@ -83,6 +83,8 @@ typedef struct {
             ushort          bios_ver;           /* not used */
             ushort          access;             /* not used */
             ushort          ext_type;           /* extended type */
+            ushort          device_id;          /* device ID */
+            ushort          sub_device_id;      /* sub device ID */
         } ctrtype;
         struct {
             unchar          version;            /* OS version */
index cb61a628d2f69b5aa925f912a3065131b6d3708b..371e44dbf050e9065d6eb96168fed3b970e45db8 100644 (file)
@@ -1,9 +1,11 @@
 /* gdth_proc.c 
- * $Id: gdth_proc.c,v 1.27 2001/03/14 10:47:00 achim Exp $
+ * $Id: gdth_proc.c,v 1.33 2001/08/10 07:54:39 achim Exp $
  */
 
 #include "gdth_ioctl.h"
+#if LINUX_VERSION_CODE >= 0x020407
 #include <linux/completion.h>
+#endif
 
 int gdth_proc_info(char *buffer,char **start,off_t offset,int length,   
                    int hostno,int inout)
@@ -48,7 +50,7 @@ static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum)
     sdev = scsi_get_host_dev(gdth_ctr_vtab[vh]);
     scp  = scsi_allocate_device(sdev, 1, FALSE);
     if (!scp)
-           return -ENOMEM;
+        return -ENOMEM;
     scp->cmd_len = 12;
     scp->use_sg = 0;
 #else
@@ -176,7 +178,7 @@ static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
     }
 
     if (wb_mode) {
-        if (!gdth_ioctl_alloc(hanum, sizeof(gdth_cpar_str)))
+        if (!gdth_ioctl_alloc(hanum, sizeof(gdth_cpar_str), TRUE))
             return(-EBUSY);
         pcpar = (gdth_cpar_str *)ha->pscratch;
         memcpy( pcpar, &ha->cpar, sizeof(gdth_cpar_str) );
@@ -192,7 +194,7 @@ static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
 #else
         gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
 #endif
-        gdth_ioctl_free(hanum);
+        gdth_ioctl_free(hanum, ha->pscratch);
         printk("Done.\n");
         return(orig_length);
     }
@@ -270,7 +272,8 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
         } else {
             return(-EINVAL);
         }
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str)+add_size+add_size2 ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str)+add_size+add_size2,
+                               TRUE ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
 
@@ -294,7 +297,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
         break;
 
       case GDTIOCTL_DRVERS:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
@@ -303,25 +306,33 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
         break;
 
       case GDTIOCTL_CTRTYPE:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
         piord->status = S_OK;
         if (ha->type == GDT_ISA || ha->type == GDT_EISA) {
             piord->iu.ctrtype.type = (unchar)((ha->stype>>20) - 0x10);
-        } else if (ha->type != GDT_PCIMPR) {
-            piord->iu.ctrtype.type = (unchar)((ha->stype<<8) + 6);
         } else {
-            piord->iu.ctrtype.type = 0xfe;
-            piord->iu.ctrtype.ext_type = 0x6000 | ha->stype;
+            if (ha->type != GDT_PCIMPR) {
+                piord->iu.ctrtype.type = (unchar)((ha->stype<<4) + 6);
+            } else {
+                piord->iu.ctrtype.type = 
+                    (ha->oem_id == OEM_ID_INTEL ? 0xfd : 0xfe);
+                if (ha->stype >= 0x300)
+                    piord->iu.ctrtype.ext_type = 0x6000 | ha->subdevice_id;
+                else 
+                    piord->iu.ctrtype.ext_type = 0x6000 | ha->stype;
+            }
+            piord->iu.ctrtype.device_id = ha->stype;
+            piord->iu.ctrtype.sub_device_id = ha->subdevice_id;
         }
         piord->iu.ctrtype.info = ha->brd_phys;
-        piord->iu.ctrtype.oem_id = (ushort)GDT3_ID;
+        piord->iu.ctrtype.oem_id = ha->oem_id;
         break;
 
       case GDTIOCTL_CTRCNT:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
@@ -330,7 +341,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
         break;
 
       case GDTIOCTL_OSVERS:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
@@ -341,7 +352,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
         break;
 
       case GDTIOCTL_LOCKDRV:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         for (i = 0; i < piowr->iu.lockdrv.drive_cnt; ++i) {
@@ -367,7 +378,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
         break;
 
       case GDTIOCTL_LOCKCHN:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
             return(-EBUSY);
         i = piowr->iu.lockchn.channel;
         if (i < ha->bus_cnt) {
@@ -395,7 +406,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
         break;
 
       case GDTIOCTL_EVENT:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         if (piowr->iu.event.erase == 0xff) {
@@ -430,7 +441,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
         break;
 
       case GDTIOCTL_SCSI:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
@@ -451,7 +462,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
         break;
 
       case GDTIOCTL_RESET_BUS:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
@@ -475,7 +486,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
         break;
 
       case GDTIOCTL_HDRLIST:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
@@ -509,7 +520,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
         break;
 
       case GDTIOCTL_RESCAN:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
@@ -635,7 +646,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
         break;
 
       case GDTIOCTL_RESET_DRV:
-        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+        if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
             return(-EBUSY);
         piord = (gdth_iord_str *)ha->pscratch;
         piord->size = sizeof(gdth_iord_str);
@@ -684,6 +695,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
     char hrec[161];
     struct timeval tv;
 
+    char *buf;
     gdth_dskstat_str *pds;
     gdth_diskinfo_str *pdi;
     gdth_arrayinf_str *pai;
@@ -701,6 +713,8 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
 #if LINUX_VERSION_CODE >= 0x020322
     sdev = scsi_get_host_dev(gdth_ctr_vtab[vh]);
     scp  = scsi_allocate_device(sdev, 1, FALSE);
+    if (!scp)
+        return -ENOMEM;
     scp->cmd_len = 12;
     scp->use_sg = 0;
 #else
@@ -784,12 +798,13 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
             len += size;  pos = begin + len;
             flag = FALSE;
             
-            if (!gdth_ioctl_alloc(hanum, GDTH_SCRATCH))
+            buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE);
+            if (!buf) 
                 goto stop_output;
             for (i = 0; i < ha->bus_cnt; ++i) {
                 /* 2.a statistics (and retries/reassigns) */
                 TRACE2(("pdr_statistics() chn %d\n",i));                
-                pds = (gdth_dskstat_str *)(ha->pscratch + GDTH_SCRATCH/4);
+                pds = (gdth_dskstat_str *)(buf + GDTH_SCRATCH/4);
                 gdtcmd.Service = CACHESERVICE;
                 gdtcmd.OpCode = GDT_IOCTL;
                 gdtcmd.u.ioctl.p_param = virt_to_bus(pds);
@@ -819,7 +834,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
                     /* 2.b drive info */
                     TRACE2(("scsi_drv_info() chn %d dev %d\n",
                         i, ha->raw[i].id_list[j]));             
-                    pdi = (gdth_diskinfo_str *)ha->pscratch;
+                    pdi = (gdth_diskinfo_str *)buf;
                     gdtcmd.Service = CACHESERVICE;
                     gdtcmd.OpCode = GDT_IOCTL;
                     gdtcmd.u.ioctl.p_param = virt_to_bus(pdi);
@@ -874,7 +889,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
                         /* 2.c grown defects */
                         TRACE2(("scsi_drv_defcnt() chn %d dev %d\n",
                                 i, ha->raw[i].id_list[j]));             
-                        pdef = (gdth_defcnt_str *)ha->pscratch;
+                        pdef = (gdth_defcnt_str *)buf;
                         gdtcmd.Service = CACHESERVICE;
                         gdtcmd.OpCode = GDT_IOCTL;
                         gdtcmd.u.ioctl.p_param = virt_to_bus(pdef);
@@ -905,7 +920,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
                         goto stop_output;
                 }
             }
-            gdth_ioctl_free(hanum);
+            gdth_ioctl_free(hanum, buf);
 
             if (!flag) {
                 size = sprintf(buffer+len, "\n --\n");
@@ -917,7 +932,8 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
             len += size;  pos = begin + len;
             flag = FALSE;
 
-            if (!gdth_ioctl_alloc(hanum, GDTH_SCRATCH))
+            buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE);
+            if (!buf) 
                 goto stop_output;
             for (i = 0; i < MAX_LDRIVES; ++i) {
                 if (!ha->hdr[i].is_logdrv)
@@ -928,7 +944,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
                 do {
                     /* 3.a log. drive info */
                     TRACE2(("cache_drv_info() drive no %d\n",drv_no));
-                    pcdi = (gdth_cdrinfo_str *)ha->pscratch;
+                    pcdi = (gdth_cdrinfo_str *)buf;
                     gdtcmd.Service = CACHESERVICE;
                     gdtcmd.OpCode = GDT_IOCTL;
                     gdtcmd.u.ioctl.p_param = virt_to_bus(pcdi);
@@ -1018,7 +1034,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
                 if (pos > offset + length)
                     goto stop_output;
             }       
-            gdth_ioctl_free(hanum);
+            gdth_ioctl_free(hanum, buf);
         
             if (!flag) {
                 size = sprintf(buffer+len, "\n --\n");
@@ -1030,14 +1046,15 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
             len += size;  pos = begin + len;
             flag = FALSE;
 
-            if (!gdth_ioctl_alloc(hanum, GDTH_SCRATCH))
+            buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE);
+            if (!buf) 
                 goto stop_output;
             for (i = 0; i < MAX_LDRIVES; ++i) {
                 if (!(ha->hdr[i].is_arraydrv && ha->hdr[i].is_master))
                     continue;
                 /* 4.a array drive info */
                 TRACE2(("array_info() drive no %d\n",i));
-                pai = (gdth_arrayinf_str *)ha->pscratch;
+                pai = (gdth_arrayinf_str *)buf;
                 gdtcmd.Service = CACHESERVICE;
                 gdtcmd.OpCode = GDT_IOCTL;
                 gdtcmd.u.ioctl.p_param = virt_to_bus(pai);
@@ -1095,7 +1112,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
                         goto stop_output;
                 }
             }
-            gdth_ioctl_free(hanum);
+            gdth_ioctl_free(hanum, buf);
         
             if (!flag) {
                 size = sprintf(buffer+len, "\n --\n");
@@ -1107,7 +1124,8 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
             len += size;  pos = begin + len;
             flag = FALSE;
 
-            if (!gdth_ioctl_alloc(hanum, GDTH_SCRATCH))
+            buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE);
+            if (!buf) 
                 goto stop_output;
             for (i = 0; i < MAX_LDRIVES; ++i) {
                 if (!ha->hdr[i].is_logdrv || 
@@ -1115,7 +1133,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
                     continue;
                 /* 5.a get host drive list */
                 TRACE2(("host_get() drv_no %d\n",i));           
-                phg = (gdth_hget_str *)ha->pscratch;
+                phg = (gdth_hget_str *)buf;
                 gdtcmd.Service = CACHESERVICE;
                 gdtcmd.OpCode = GDT_IOCTL;
                 gdtcmd.u.ioctl.p_param = virt_to_bus(phg);
@@ -1146,7 +1164,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
                     }
                 }
             }
-            gdth_ioctl_free(hanum);
+            gdth_ioctl_free(hanum, buf);
 
             for (i = 0; i < MAX_HDRIVES; ++i) {
                 if (!(ha->hdr[i].present))
@@ -1210,7 +1228,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
             goto stop_output;
         length = piord->size;
         memcpy(buffer+len, (char *)piord, length);
-        gdth_ioctl_free(hanum);
+        gdth_ioctl_free(hanum, ha->pscratch);
         len = length; 
     }
 
@@ -1232,7 +1250,13 @@ static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *gdtcmd,
                         char *cmnd, int timeout)
 {
     unsigned bufflen;
+#if LINUX_VERSION_CODE >= 0x020407
     DECLARE_COMPLETION(wait);
+#elif LINUX_VERSION_CODE >= 0x020322
+    DECLARE_MUTEX_LOCKED(sem);
+#else
+    struct semaphore sem = MUTEX_LOCKED;
+#endif
 
     TRACE2(("gdth_do_cmd()\n"));
     if (gdtcmd != NULL) { 
@@ -1243,7 +1267,12 @@ static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *gdtcmd,
         bufflen = 0;
     }
     scp->request.rq_status = RQ_SCSI_BUSY;
+#if LINUX_VERSION_CODE >= 0x020407
     scp->request.waiting = &wait;
+    scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
+    wait_for_completion(&wait);
+#else
+    scp->request.sem = &sem;
 #if LINUX_VERSION_CODE >= 0x020322
     scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
 #else
@@ -1251,7 +1280,8 @@ static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *gdtcmd,
     scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
     GDTH_UNLOCK_SCSI_DOCMD();
 #endif
-    wait_for_completion(&wait);
+    down(&sem);
+#endif
 }
 
 void gdth_scsi_done(Scsi_Cmnd *scp)
@@ -1260,15 +1290,20 @@ void gdth_scsi_done(Scsi_Cmnd *scp)
 
     scp->request.rq_status = RQ_SCSI_DONE;
 
+#if LINUX_VERSION_CODE >= 0x020407
     if (scp->request.waiting != NULL)
         complete(scp->request.waiting);
+#else
+    if (scp->request.sem != NULL)
+        up(scp->request.sem);
+#endif
 }
 
-static int gdth_ioctl_alloc(int hanum, ushort size)
+static char *gdth_ioctl_alloc(int hanum, ushort size, int scratch)
 {
     gdth_ha_str *ha;
     ulong flags;
-    int ret_val;
+    char *ret_val;
 
     if (size == 0 || size > GDTH_SCRATCH)
         return FALSE;
@@ -1276,17 +1311,26 @@ static int gdth_ioctl_alloc(int hanum, ushort size)
     ha = HADATA(gdth_ctr_tab[hanum]);
     GDTH_LOCK_HA(ha, flags);
 
-    if (!ha->scratch_busy) {
-        ha->scratch_busy = TRUE;
-        ret_val = TRUE;
-    } else
-        ret_val = FALSE;
+    if (scratch) { 
+        if (!ha->scratch_busy) {
+            ha->scratch_busy = TRUE;
+            ret_val = ha->pscratch;
+        } else
+            ret_val = NULL;
+    } else {
+#if LINUX_VERSION_CODE >= 0x020322
+        ret_val = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA, 
+                                            GDTH_SCRATCH_ORD);
+#else
+        ret_val = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
+#endif
+    }
 
     GDTH_UNLOCK_HA(ha, flags);
     return ret_val;
 }
 
-static void gdth_ioctl_free(int hanum)
+static void gdth_ioctl_free(int hanum, char *buf)
 {
     gdth_ha_str *ha;
     ulong flags;
@@ -1294,7 +1338,15 @@ static void gdth_ioctl_free(int hanum)
     ha = HADATA(gdth_ctr_tab[hanum]);
     GDTH_LOCK_HA(ha, flags);
 
-    ha->scratch_busy = FALSE;
+    if (buf == ha->pscratch) {
+        ha->scratch_busy = FALSE;
+    } else {
+#if LINUX_VERSION_CODE >= 0x020322
+        free_pages((unsigned long)buf, GDTH_SCRATCH_ORD);
+#else
+        scsi_init_free((void *)buf, GDTH_SCRATCH);
+#endif
+    }
 
     GDTH_UNLOCK_HA(ha, flags);
 }
index 0ce4d032a4cdd6deee640d157012aaf6143afb76..328eac201365cffbf41957c452ede51e79a72af6 100644 (file)
@@ -2,7 +2,7 @@
 #define _GDTH_PROC_H
 
 /* gdth_proc.h 
- * $Id: gdth_proc.h,v 1.10 2000/07/24 09:30:01 achim Exp $
+ * $Id: gdth_proc.h,v 1.11 2001/07/25 15:37:40 achim Exp $
  */
 
 static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum);
@@ -19,8 +19,8 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp);
 static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *cmd, 
                         char *cmnd, int timeout);
 
-static int gdth_ioctl_alloc(int hanum, ushort size);
-static void gdth_ioctl_free(int hanum);
+static char *gdth_ioctl_alloc(int hanum, ushort size, int scratch);
+static void gdth_ioctl_free(int hanum, char *buf);
 static int gdth_ioctl_check_bin(int hanum, ushort size);
 static void gdth_wait_completion(int hanum, int busnum, int id);
 static void gdth_stop_timeout(int hanum, int busnum, int id);
index 0815d1954be39542dd70c725b733978568830a72..b0902e3f9a7e79c8d828851cd911d0bc74653880 100644 (file)
@@ -9,7 +9,7 @@
     Ver.0.1   Initial version
 
     This software may be used and distributed according to the terms of
-    the GNU Public License.
+    the GNU General Public License.
 
 ======================================================================*/
 
index 4c72343c04d739361d54bc0e3f6d4cc4f7cad7b7..8d45bb3fca3c83a3cf2b4c9b0193c60cf9c1cfd7 100644 (file)
@@ -3,7 +3,7 @@
       By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
 
     This software may be used and distributed according to the terms of
-    the GNU Public License.
+    the GNU General Public License.
 =========================================================================*/
 
 /* $Id: nsp_debug.c,v 1.6 2001/07/04 14:43:53 elca Exp $ */
index 6385bfbc8fa09d287b1614c8ea2800cd852b7a4a..8c765953d6cf4ef451c9fb0014869cc3d9ba65fc 100644 (file)
@@ -3,7 +3,7 @@
       By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
 
    This software may be used and distributed according to the terms of
-   the GNU Public License.
+   the GNU General Public License.
  */
 
 /* $Id: nsp_message.c,v 1.6 2001/07/05 10:56:37 elca Exp $ */
index 7e4405a78c1d68c399e5411a9840363ab721eddc..ab87e2c064448aaf32b7d90a13653fe62e3862bb 100644 (file)
@@ -98,8 +98,6 @@ typedef dma_addr_t dma64_addr_t;
    isp2200's firmware. 
 */
 
-#define RELOAD_FIRMWARE                0
-
 #define USE_NVRAM_DEFAULTS      1
 
 #define ISP2x00_PORTDB          1
@@ -440,7 +438,16 @@ struct Status_Entry {
 #define MBOX_SEND_CHANGE_REQUEST        0x0070
 #define MBOX_PORT_LOGOUT                0x0071
 
-//#include "qlogicfc_asm.c"
+/*
+ *     Firmware if needed (note this is a hack, it belongs in a seperate
+ *     module.
+ */
+#ifdef CONFIG_SCSI_QLOGIC_FC_FIRMWARE
+#include "qlogicfc_asm.c"
+#else
+static unsigned short risc_code_addr01 = 0x1000 ;
+#endif
 
 /* 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
@@ -1853,7 +1860,6 @@ static int isp2x00_reset_hardware(struct Scsi_Host *host)
        struct isp2x00_hostdata *hostdata;
        int loop_count;
        dma64_addr_t busaddr;
-       unsigned short risc_code_addr01 = 0x1000 ;
 
        ENTER("isp2x00_reset_hardware");
 
@@ -1892,7 +1898,7 @@ static int isp2x00_reset_hardware(struct Scsi_Host *host)
 
        DEBUG(printk("qlogicfc%d : verifying checksum\n", hostdata->host_id));
 
-#if RELOAD_FIRMWARE
+#if defined(CONFIG_SCSI_QLOGIC_FC_FIRMWARE)
        {
                int i;
                unsigned short * risc_code = NULL;
diff --git a/drivers/scsi/qlogicfc_asm.c b/drivers/scsi/qlogicfc_asm.c
new file mode 100644 (file)
index 0000000..55c6c4b
--- /dev/null
@@ -0,0 +1,9751 @@
+/************************************************************************
+ *                                                                     *
+ *      --- ISP2100 Fabric Initiator/Target Firmware ---               *
+ *                   with expanded LUN addressing                       *
+ *                   and FcTape (FCP-2) support                         *
+ *                                                                     *
+ *                                                                     *
+ ************************************************************************
+  Copyright (C) 2000 and 2001 Qlogic Corporation 
+  (www.qlogic.com)
+
+  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.
+************************************************************************/
+
+/*
+ *     Firmware Version 1.19.16 (10:36 Nov 02, 2000)
+ */
+
+unsigned short risc_code_addr01 = 0x1000 ;
+
+unsigned short risc_code_length2100 = 0x9260;
+unsigned short risc_code2100[] = {
+       0x0078, 0x102d, 0x0000, 0x9260, 0x0000, 0x0001, 0x0013, 0x0010,
+       0x0017, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2031, 0x3939,
+       0x3920, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241,
+       0x5449, 0x4f4e, 0x2049, 0x5350, 0x3231, 0x3030, 0x2046, 0x6972,
+       0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030,
+       0x312e, 0x3139, 0x2020, 0x2020, 0x2400, 0x2091, 0x2000, 0x20c1,
+       0x0021, 0x2039, 0xffff, 0x2019, 0xaaaa, 0x2760, 0x2069, 0x7fff,
+       0x20c1, 0x0020, 0x2c2c, 0x2d34, 0x2762, 0x236a, 0x2c24, 0x2d04,
+       0x266a, 0x2562, 0xa406, 0x00c0, 0x1052, 0x20c1, 0x0021, 0x2c2c,
+       0x2362, 0x2c04, 0x2562, 0xa306, 0x0040, 0x1052, 0x20c1, 0x0020,
+       0x2039, 0x8fff, 0x20a1, 0xaa00, 0x2708, 0x810d, 0x810d, 0x810d,
+       0x810d, 0xa18c, 0x000f, 0x2001, 0x000a, 0xa112, 0xa00e, 0x21a8,
+       0x41a4, 0x3400, 0x8211, 0x00c0, 0x105f, 0x2708, 0x3400, 0xa102,
+       0x0040, 0x106f, 0x0048, 0x106f, 0x20a8, 0xa00e, 0x41a4, 0x20a1,
+       0xa260, 0x2009, 0x0000, 0x20a9, 0x07a0, 0x41a4, 0x3400, 0x20c9,
+       0xa7ff, 0x2059, 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x255d,
+       0x2051, 0xa300, 0x2a70, 0x775e, 0xa786, 0x8fff, 0x0040, 0x1092,
+       0x705b, 0xca00, 0x7057, 0xc9f1, 0x7063, 0x0200, 0x7067, 0x0200,
+       0x0078, 0x109a, 0x7057, 0xba01, 0x7063, 0x0100, 0x7067, 0x0100,
+       0x705b, 0xba00, 0x1078, 0x12df, 0x1078, 0x13c0, 0x1078, 0x1569,
+       0x1078, 0x1ca4, 0x1078, 0x4229, 0x1078, 0x74cf, 0x1078, 0x134b,
+       0x1078, 0x2a3f, 0x1078, 0x4da2, 0x1078, 0x48b2, 0x1078, 0x57df,
+       0x1078, 0x21f7, 0x1078, 0x5abf, 0x1078, 0x5369, 0x1078, 0x210d,
+       0x1078, 0x21d4, 0x2091, 0x3009, 0x7823, 0x0000, 0x0090, 0x10cf,
+       0x7820, 0xa086, 0x0002, 0x00c0, 0x10cf, 0x7823, 0x4000, 0x0068,
+       0x10c7, 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2a70,
+       0x7003, 0x0000, 0x2001, 0x017f, 0x2003, 0x0000, 0x2a70, 0x7000,
+       0xa08e, 0x0003, 0x00c0, 0x10ef, 0x1078, 0x35bc, 0x1078, 0x2a67,
+       0x1078, 0x4df2, 0x1078, 0x4a75, 0x2009, 0x0100, 0x2104, 0xa082,
+       0x0002, 0x0048, 0x10f3, 0x1078, 0x57fb, 0x0078, 0x10d6, 0x1079,
+       0x10f7, 0x0078, 0x10dc, 0x1078, 0x6fa9, 0x0078, 0x10eb, 0x1101,
+       0x1102, 0x11be, 0x10ff, 0x1246, 0x12dc, 0x12dd, 0x12de, 0x1078,
+       0x1328, 0x007c, 0x127e, 0x0f7e, 0x2091, 0x8000, 0x7000, 0xa086,
+       0x0001, 0x00c0, 0x1198, 0x1078, 0x3a43, 0x2079, 0x0100, 0x7844,
+       0xa005, 0x00c0, 0x1198, 0x2011, 0x4129, 0x1078, 0x58d4, 0x1078,
+       0x1ab1, 0x780f, 0x00ff, 0x7840, 0xa084, 0xfffb, 0x7842, 0x2011,
+       0x8010, 0x73c0, 0x1078, 0x3579, 0x2001, 0xffff, 0x1078, 0x5975,
+       0x7238, 0xc284, 0x723a, 0x2001, 0xa30c, 0x2014, 0xc2ac, 0x2202,
+       0x1078, 0x6db5, 0x2011, 0x0004, 0x1078, 0x8a59, 0x1078, 0x47ce,
+       0x1078, 0x4211, 0x0040, 0x1144, 0x7083, 0x0001, 0x70bb, 0x0000,
+       0x1078, 0x3bf5, 0x0078, 0x1198, 0x1078, 0x4897, 0x0040, 0x114d,
+       0x7a0c, 0xc2b4, 0x7a0e, 0x0078, 0x1159, 0x1078, 0x8ddf, 0x70c8,
+       0xd09c, 0x00c0, 0x1159, 0x7094, 0xa005, 0x0040, 0x1159, 0x1078,
+       0x41f5, 0x70d3, 0x0000, 0x70cf, 0x0000, 0x72c8, 0x2079, 0xa351,
+       0x7804, 0xd0ac, 0x0040, 0x1165, 0xc295, 0x72ca, 0xa296, 0x0004,
+       0x0040, 0x1186, 0x2011, 0x0001, 0x1078, 0x8a59, 0x708f, 0x0000,
+       0x7093, 0xffff, 0x7003, 0x0002, 0x0f7f, 0x1078, 0x260d, 0x2011,
+       0x0005, 0x1078, 0x6ef2, 0x1078, 0x6109, 0x0c7e, 0x2061, 0x0100,
+       0x60e3, 0x0008, 0x0c7f, 0x127f, 0x0078, 0x119a, 0x708f, 0x0000,
+       0x7093, 0xffff, 0x7003, 0x0002, 0x2011, 0x0005, 0x1078, 0x6ef2,
+       0x1078, 0x6109, 0x0c7e, 0x2061, 0x0100, 0x60e3, 0x0008, 0x0c7f,
+       0x0f7f, 0x127f, 0x007c, 0x0c7e, 0x20a9, 0x0082, 0x2009, 0x007e,
+       0x017e, 0x027e, 0x037e, 0x2110, 0x027e, 0x2019, 0x0029, 0x1078,
+       0x71e0, 0x027f, 0x1078, 0xa190, 0x037f, 0x027f, 0x017f, 0x1078,
+       0x2921, 0x8108, 0x00f0, 0x11a0, 0x0c7f, 0x706b, 0x0000, 0x706c,
+       0xa084, 0x00ff, 0x706e, 0x7097, 0x0000, 0x007c, 0x127e, 0x2091,
+       0x8000, 0x7000, 0xa086, 0x0002, 0x00c0, 0x1244, 0x7090, 0xa086,
+       0xffff, 0x0040, 0x11d1, 0x1078, 0x260d, 0x1078, 0x6109, 0x0078,
+       0x1244, 0x70c8, 0xd09c, 0x0040, 0x11fd, 0xd084, 0x0040, 0x11fd,
+       0x0f7e, 0x2079, 0x0100, 0x790c, 0xc1b5, 0x790e, 0x0f7f, 0xd08c,
+       0x0040, 0x11fd, 0x70cc, 0xa086, 0xffff, 0x0040, 0x11f9, 0x1078,
+       0x278a, 0x1078, 0x6109, 0x70c8, 0xd094, 0x00c0, 0x1244, 0x2011,
+       0x0001, 0x2019, 0x0000, 0x1078, 0x27c2, 0x1078, 0x6109, 0x0078,
+       0x1244, 0x70d0, 0xa005, 0x00c0, 0x1244, 0x708c, 0xa005, 0x00c0,
+       0x1244, 0x1078, 0x4897, 0x00c0, 0x1244, 0x2001, 0xa352, 0x2004,
+       0xd0ac, 0x0040, 0x1227, 0x157e, 0x0c7e, 0x20a9, 0x007f, 0x2009,
+       0x0000, 0x017e, 0x1078, 0x4501, 0x00c0, 0x121a, 0x6000, 0xd0ec,
+       0x00c0, 0x1222, 0x017f, 0x8108, 0x00f0, 0x1211, 0x0c7f, 0x157f,
+       0x0078, 0x1227, 0x017f, 0x0c7f, 0x157f, 0x0078, 0x1244, 0x7003,
+       0x0003, 0x7093, 0xffff, 0x2001, 0x0000, 0x1078, 0x2480, 0x1078,
+       0x35f7, 0x2001, 0xa5ac, 0x2004, 0xa086, 0x0005, 0x00c0, 0x123c,
+       0x2011, 0x0000, 0x1078, 0x6ef2, 0x2011, 0x0000, 0x1078, 0x6efc,
+       0x1078, 0x6109, 0x1078, 0x61d3, 0x127f, 0x007c, 0x017e, 0x0f7e,
+       0x127e, 0x2091, 0x8000, 0x2079, 0x0100, 0x2009, 0x00f7, 0x1078,
+       0x41de, 0x7940, 0xa18c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0040,
+       0x125b, 0x7827, 0x0040, 0xd19c, 0x0040, 0x1260, 0x7827, 0x0008,
+       0x007e, 0x037e, 0x157e, 0xa006, 0x1078, 0x5975, 0x7900, 0xa18a,
+       0x0003, 0x0050, 0x1289, 0x7954, 0xd1ac, 0x00c0, 0x1289, 0x2009,
+       0x00f8, 0x1078, 0x41de, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9,
+       0x09c4, 0x7820, 0xd09c, 0x00c0, 0x1281, 0x7824, 0xd0ac, 0x00c0,
+       0x12ca, 0x00f0, 0x1279, 0x2001, 0x0001, 0x1078, 0x2480, 0x0078,
+       0x12d5, 0x7853, 0x0000, 0x782f, 0x0020, 0x20a9, 0x0050, 0x00e0,
+       0x128f, 0x2091, 0x6000, 0x00f0, 0x128f, 0x7853, 0x0400, 0x782f,
+       0x0000, 0x2009, 0x00f8, 0x1078, 0x41de, 0x20a9, 0x000e, 0x0005,
+       0x00f0, 0x129f, 0x7853, 0x1400, 0x7843, 0x0090, 0x7843, 0x0010,
+       0x2019, 0x61a8, 0x7854, 0x0005, 0x0005, 0xd08c, 0x0040, 0x12b4,
+       0x7824, 0xd0ac, 0x00c0, 0x12ca, 0x8319, 0x00c0, 0x12aa, 0x2009,
+       0xa331, 0x2104, 0x8000, 0x200a, 0xa084, 0xfff0, 0x0040, 0x12c4,
+       0x200b, 0x0000, 0x1078, 0x251e, 0x2001, 0x0001, 0x1078, 0x2480,
+       0x0078, 0x12d3, 0x2001, 0xa331, 0x2003, 0x0000, 0x7828, 0xc09d,
+       0x782a, 0x7827, 0x0048, 0x7853, 0x0400, 0x157f, 0x037f, 0x007f,
+       0x127f, 0x0f7f, 0x017f, 0x007c, 0x007c, 0x007c, 0x007c, 0x2a70,
+       0x2009, 0x0100, 0x2104, 0xa082, 0x0002, 0x0048, 0x12eb, 0x704f,
+       0xffff, 0x0078, 0x12ed, 0x704f, 0x0000, 0x7053, 0xffff, 0x706b,
+       0x0000, 0x706f, 0x0000, 0x1078, 0x8ddf, 0x2061, 0xa58c, 0x6003,
+       0x0909, 0x6007, 0x0000, 0x600b, 0x8800, 0x600f, 0x0200, 0x6013,
+       0x00ff, 0x6017, 0x0003, 0x601b, 0x0000, 0x601f, 0x07d0, 0x2061,
+       0xa594, 0x6003, 0x8000, 0x6007, 0x0000, 0x600b, 0x0000, 0x600f,
+       0x0200, 0x6013, 0x00ff, 0x6017, 0x0000, 0x601b, 0x0001, 0x601f,
+       0x0000, 0x2061, 0xa5a3, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b,
+       0x4943, 0x600f, 0x2020, 0x2001, 0xa325, 0x2003, 0x0000, 0x007c,
+       0x2091, 0x8000, 0x0068, 0x132a, 0x007e, 0x017e, 0x2079, 0x0000,
+       0x7818, 0xd084, 0x00c0, 0x1330, 0x017f, 0x792e, 0x007f, 0x782a,
+       0x007f, 0x7826, 0x3900, 0x783a, 0x7823, 0x8002, 0x781b, 0x0001,
+       0x2091, 0x5000, 0x2091, 0x4080, 0x2079, 0xa300, 0x7803, 0x0005,
+       0x0078, 0x1348, 0x007c, 0x2071, 0xa300, 0x7158, 0x712e, 0x2021,
+       0x0001, 0xa190, 0x002d, 0xa298, 0x002d, 0x0048, 0x1361, 0x705c,
+       0xa302, 0x00c8, 0x1361, 0x220a, 0x2208, 0x2310, 0x8420, 0x0078,
+       0x1353, 0x200b, 0x0000, 0x74a6, 0x74aa, 0x007c, 0x0e7e, 0x127e,
+       0x2091, 0x8000, 0x2071, 0xa300, 0x70a8, 0xa0ea, 0x0010, 0x00c8,
+       0x1374, 0xa06e, 0x0078, 0x137e, 0x8001, 0x70aa, 0x702c, 0x2068,
+       0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, 0x127f, 0x0e7f,
+       0x007c, 0x0e7e, 0x2071, 0xa300, 0x127e, 0x2091, 0x8000, 0x70a8,
+       0x8001, 0x00c8, 0x138e, 0xa06e, 0x0078, 0x1397, 0x70aa, 0x702c,
+       0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, 0x127f,
+       0x0e7f, 0x007c, 0x0e7e, 0x127e, 0x2091, 0x8000, 0x2071, 0xa300,
+       0x702c, 0x206a, 0x2d00, 0x702e, 0x70a8, 0x8000, 0x70aa, 0x127f,
+       0x0e7f, 0x007c, 0x8dff, 0x0040, 0x13b6, 0x6804, 0x6807, 0x0000,
+       0x007e, 0x1078, 0x139a, 0x0d7f, 0x0078, 0x13aa, 0x007c, 0x0e7e,
+       0x2071, 0xa300, 0x70a8, 0xa08a, 0x0010, 0xa00d, 0x0e7f, 0x007c,
+       0x0e7e, 0x2071, 0xa5d0, 0x7007, 0x0000, 0x701b, 0x0000, 0x701f,
+       0x0000, 0x2071, 0x0000, 0x7010, 0xa085, 0x8004, 0x7012, 0x0e7f,
+       0x007c, 0x0e7e, 0x2270, 0x700b, 0x0000, 0x2071, 0xa5d0, 0x7018,
+       0xa088, 0xa5d9, 0x220a, 0x8000, 0xa084, 0x0007, 0x701a, 0x7004,
+       0xa005, 0x00c0, 0x13e9, 0x0f7e, 0x2079, 0x0010, 0x1078, 0x13fa,
+       0x0f7f, 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0xa5d0, 0x7004, 0xa005,
+       0x00c0, 0x13f8, 0x0f7e, 0x2079, 0x0010, 0x1078, 0x13fa, 0x0f7f,
+       0x0e7f, 0x007c, 0x7000, 0x0079, 0x13fd, 0x1401, 0x146b, 0x1488,
+       0x1488, 0x7018, 0x711c, 0xa106, 0x00c0, 0x1409, 0x7007, 0x0000,
+       0x007c, 0x0d7e, 0xa180, 0xa5d9, 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, 0x142b, 0x7007, 0x0001,
+       0x1078, 0x1430, 0x007c, 0x7007, 0x0002, 0x1078, 0x1446, 0x007c,
+       0x017e, 0x027e, 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x00c8,
+       0x143b, 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, 0x145a,
+       0x2110, 0xa006, 0x700e, 0x22a8, 0x53a6, 0x8203, 0x7822, 0x7803,
+       0x0020, 0x3300, 0x7016, 0x7803, 0x0001, 0x157f, 0x147f, 0x137f,
+       0x027f, 0x017f, 0x007c, 0x137e, 0x147e, 0x157e, 0x2099, 0xa3f9,
+       0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e,
+       0x2091, 0x8000, 0x7803, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084,
+       0x7002, 0x700b, 0xa3f4, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c,
+       0x137e, 0x147e, 0x157e, 0x2001, 0xa428, 0x209c, 0x20a1, 0x0014,
+       0x7803, 0x0026, 0x2001, 0xa429, 0x20ac, 0x53a6, 0x2099, 0xa42a,
+       0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e,
+       0x2091, 0x8000, 0x7803, 0x0001, 0x7007, 0x0004, 0x7000, 0xc08c,
+       0x7002, 0x700b, 0xa425, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c,
+       0x017e, 0x0e7e, 0x2071, 0xa5d0, 0x0f7e, 0x2079, 0x0010, 0x7904,
+       0x7803, 0x0002, 0xd1fc, 0x0040, 0x14c2, 0xa18c, 0x0700, 0x7004,
+       0x1079, 0x14c6, 0x0f7f, 0x0e7f, 0x017f, 0x007c, 0x13fa, 0x14ce,
+       0x14fb, 0x1523, 0x1556, 0x14cc, 0x0078, 0x14cc, 0xa18c, 0x0700,
+       0x00c0, 0x14f4, 0x137e, 0x147e, 0x157e, 0x7014, 0x20a0, 0x2099,
+       0x0014, 0x7803, 0x0040, 0x7010, 0x20a8, 0x53a5, 0x3400, 0x7016,
+       0x157f, 0x147f, 0x137f, 0x700c, 0xa005, 0x0040, 0x1510, 0x1078,
+       0x1430, 0x007c, 0x7008, 0xa080, 0x0002, 0x2003, 0x0100, 0x7007,
+       0x0000, 0x1078, 0x13fa, 0x007c, 0x7008, 0xa080, 0x0002, 0x2003,
+       0x0200, 0x0078, 0x14ef, 0xa18c, 0x0700, 0x00c0, 0x1506, 0x700c,
+       0xa005, 0x0040, 0x1510, 0x1078, 0x1446, 0x007c, 0x7008, 0xa080,
+       0x0002, 0x2003, 0x0200, 0x7007, 0x0000, 0x1078, 0x13fa, 0x007c,
+       0x0d7e, 0x7008, 0x2068, 0x7830, 0x6826, 0x7834, 0x682a, 0x7838,
+       0x682e, 0x783c, 0x6832, 0x680b, 0x0100, 0x0d7f, 0x7007, 0x0000,
+       0x1078, 0x13fa, 0x007c, 0xa18c, 0x0700, 0x00c0, 0x1550, 0x137e,
+       0x147e, 0x157e, 0x2001, 0xa3f7, 0x2004, 0xa080, 0x000d, 0x20a0,
+       0x2099, 0x0014, 0x7803, 0x0040, 0x20a9, 0x0020, 0x53a5, 0x2001,
+       0xa3f9, 0x2004, 0xd0bc, 0x0040, 0x1546, 0x2001, 0xa402, 0x2004,
+       0xa080, 0x000d, 0x20a0, 0x20a9, 0x0020, 0x53a5, 0x157f, 0x147f,
+       0x137f, 0x7007, 0x0000, 0x1078, 0x4e9b, 0x1078, 0x13fa, 0x007c,
+       0x2011, 0x8003, 0x1078, 0x3579, 0x0078, 0x1554, 0xa18c, 0x0700,
+       0x00c0, 0x1563, 0x2001, 0xa427, 0x2003, 0x0100, 0x7007, 0x0000,
+       0x1078, 0x13fa, 0x007c, 0x2011, 0x8004, 0x1078, 0x3579, 0x0078,
+       0x1567, 0x127e, 0x2091, 0x2100, 0x2079, 0x0030, 0x2071, 0xa5e1,
+       0x7803, 0x0004, 0x7003, 0x0000, 0x700f, 0xa5e7, 0x7013, 0xa5e7,
+       0x780f, 0x0076, 0x7803, 0x0004, 0x127f, 0x007c, 0x6934, 0xa184,
+       0x0007, 0x0079, 0x1583, 0x158b, 0x15d1, 0x158b, 0x158b, 0x158b,
+       0x15b6, 0x159a, 0x158f, 0xa085, 0x0001, 0x0078, 0x15eb, 0x684c,
+       0xd0bc, 0x0040, 0x158b, 0x6860, 0x682e, 0x685c, 0x682a, 0x6858,
+       0x0078, 0x15d9, 0xa18c, 0x00ff, 0xa186, 0x001e, 0x00c0, 0x158b,
+       0x684c, 0xd0bc, 0x0040, 0x158b, 0x6860, 0x682e, 0x685c, 0x682a,
+       0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080,
+       0x2015, 0x2004, 0x6832, 0x6858, 0x0078, 0x15e1, 0xa18c, 0x00ff,
+       0xa186, 0x0015, 0x00c0, 0x158b, 0x684c, 0xd0ac, 0x0040, 0x158b,
+       0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080,
+       0x2015, 0x2004, 0x6832, 0xa006, 0x682e, 0x682a, 0x6858, 0x0078,
+       0x15e1, 0x684c, 0xd0ac, 0x0040, 0x158b, 0xa006, 0x682e, 0x682a,
+       0x6858, 0xa18c, 0x000f, 0xa188, 0x2015, 0x210c, 0x6932, 0x2d08,
+       0x691a, 0x6826, 0x684c, 0xc0dd, 0x684e, 0xa006, 0x680a, 0x697c,
+       0x6912, 0x6980, 0x6916, 0x007c, 0x20e1, 0x0007, 0x20e1, 0x2000,
+       0x2001, 0x020a, 0x2004, 0x82ff, 0x0040, 0x160e, 0xa280, 0x0004,
+       0x0d7e, 0x206c, 0x684c, 0xd0dc, 0x00c0, 0x160a, 0x1078, 0x157e,
+       0x0040, 0x160a, 0x0d7f, 0xa280, 0x0000, 0x2003, 0x0002, 0xa016,
+       0x0078, 0x160e, 0x6808, 0x8000, 0x680a, 0x0d7f, 0x127e, 0x047e,
+       0x037e, 0x027e, 0x2091, 0x2100, 0x027f, 0x037f, 0x047f, 0x7000,
+       0xa005, 0x00c0, 0x1622, 0x7206, 0x2001, 0x1643, 0x007e, 0x2260,
+       0x0078, 0x17be, 0x710c, 0x220a, 0x8108, 0x230a, 0x8108, 0x240a,
+       0x8108, 0xa182, 0xa602, 0x0048, 0x162f, 0x2009, 0xa5e7, 0x710e,
+       0x7010, 0xa102, 0xa082, 0x0009, 0x0040, 0x163a, 0xa080, 0x001b,
+       0x00c0, 0x163d, 0x2009, 0x0138, 0x200a, 0x7000, 0xa005, 0x00c0,
+       0x1643, 0x1078, 0x179f, 0x127f, 0x007c, 0x127e, 0x027e, 0x037e,
+       0x0c7e, 0x007e, 0x2091, 0x2100, 0x007f, 0x047f, 0x037f, 0x027f,
+       0x0d7e, 0x0c7e, 0x2460, 0x6110, 0x2168, 0x6a62, 0x6b5e, 0xa005,
+       0x0040, 0x16cf, 0x6808, 0xa005, 0x0040, 0x173c, 0x7000, 0xa005,
+       0x00c0, 0x1664, 0x0078, 0x16c4, 0x700c, 0x7110, 0xa106, 0x00c0,
+       0x1745, 0x7004, 0xa406, 0x00c0, 0x16c4, 0x2001, 0x0005, 0x2004,
+       0xd08c, 0x0040, 0x1681, 0x047e, 0x1078, 0x18e2, 0x047f, 0x2460,
+       0x6010, 0xa080, 0x0002, 0x2004, 0xa005, 0x0040, 0x173c, 0x0078,
+       0x165e, 0x2001, 0x0207, 0x2004, 0xd09c, 0x00c0, 0x166d, 0x7804,
+       0xa084, 0x6000, 0x0040, 0x1692, 0xa086, 0x6000, 0x0040, 0x1692,
+       0x0078, 0x166d, 0x7100, 0xa186, 0x0002, 0x00c0, 0x16b2, 0x0e7e,
+       0x2b68, 0x6818, 0x2060, 0x1078, 0x1fea, 0x2804, 0xac70, 0x6034,
+       0xd09c, 0x00c0, 0x16a7, 0x7108, 0x720c, 0x0078, 0x16a9, 0x7110,
+       0x7214, 0x6810, 0xa100, 0x6812, 0x6814, 0xa201, 0x6816, 0x0e7f,
+       0x0078, 0x16b6, 0xa186, 0x0001, 0x00c0, 0x16be, 0x7820, 0x6910,
+       0xa100, 0x6812, 0x7824, 0x6914, 0xa101, 0x6816, 0x7803, 0x0004,
+       0x7003, 0x0000, 0x7004, 0x2060, 0x6100, 0xa18e, 0x0004, 0x00c0,
+       0x1745, 0x2009, 0x0048, 0x1078, 0x756c, 0x0078, 0x1745, 0x6808,
+       0xa005, 0x0040, 0x173c, 0x7000, 0xa005, 0x00c0, 0x16d9, 0x0078,
+       0x173c, 0x700c, 0x7110, 0xa106, 0x00c0, 0x16e2, 0x7004, 0xa406,
+       0x00c0, 0x173c, 0x2001, 0x0005, 0x2004, 0xd08c, 0x0040, 0x16f6,
+       0x047e, 0x1078, 0x18e2, 0x047f, 0x2460, 0x6010, 0xa080, 0x0002,
+       0x2004, 0xa005, 0x0040, 0x173c, 0x0078, 0x16d3, 0x2001, 0x0207,
+       0x2004, 0xd09c, 0x00c0, 0x16e2, 0x2001, 0x0005, 0x2004, 0xd08c,
+       0x00c0, 0x16e8, 0x7804, 0xa084, 0x6000, 0x0040, 0x170d, 0xa086,
+       0x6000, 0x0040, 0x170d, 0x0078, 0x16e2, 0x7007, 0x0000, 0xa016,
+       0x2218, 0x7000, 0xa08e, 0x0001, 0x0040, 0x172e, 0xa08e, 0x0002,
+       0x00c0, 0x173c, 0x0c7e, 0x0e7e, 0x6818, 0x2060, 0x1078, 0x1fea,
+       0x2804, 0xac70, 0x6034, 0xd09c, 0x00c0, 0x172a, 0x7308, 0x720c,
+       0x0078, 0x172c, 0x7310, 0x7214, 0x0e7f, 0x0c7f, 0x7820, 0xa318,
+       0x7824, 0xa211, 0x6810, 0xa300, 0x6812, 0x6814, 0xa201, 0x6816,
+       0x7803, 0x0004, 0x7003, 0x0000, 0x6100, 0xa18e, 0x0004, 0x00c0,
+       0x1745, 0x2009, 0x0048, 0x1078, 0x756c, 0x0c7f, 0x0d7f, 0x127f,
+       0x007c, 0x0f7e, 0x0e7e, 0x027e, 0x037e, 0x047e, 0x1078, 0x1af7,
+       0x027e, 0x2071, 0xa5e1, 0x7000, 0xa086, 0x0000, 0x0040, 0x1790,
+       0x7004, 0xac06, 0x00c0, 0x1781, 0x2079, 0x0030, 0x7000, 0xa086,
+       0x0003, 0x0040, 0x1781, 0x7804, 0xd0fc, 0x00c0, 0x177d, 0x2001,
+       0x0207, 0x2004, 0xd09c, 0x00c0, 0x1763, 0x7803, 0x0004, 0x7804,
+       0xd0ac, 0x00c0, 0x176f, 0x7803, 0x0002, 0x7803, 0x0009, 0x7003,
+       0x0003, 0x7007, 0x0000, 0x0078, 0x1781, 0x1078, 0x18e2, 0x0078,
+       0x1753, 0x157e, 0x20a9, 0x0009, 0x2009, 0xa5e7, 0x2104, 0xac06,
+       0x00c0, 0x178b, 0x200a, 0xa188, 0x0003, 0x00f0, 0x1786, 0x157f,
+       0x027f, 0x2001, 0x015d, 0x201c, 0x831a, 0x2302, 0x2001, 0x0138,
+       0x2202, 0x047f, 0x037f, 0x027f, 0x0e7f, 0x0f7f, 0x007c, 0x700c,
+       0x7110, 0xa106, 0x00c0, 0x17a7, 0x7003, 0x0000, 0x007c, 0x2104,
+       0x7006, 0x2060, 0x8108, 0x211c, 0x8108, 0x2124, 0x8108, 0xa182,
+       0xa602, 0x0048, 0x17b5, 0x2009, 0xa5e7, 0x7112, 0x700c, 0xa106,
+       0x00c0, 0x17be, 0x2001, 0x0138, 0x2003, 0x0008, 0x8cff, 0x00c0,
+       0x17c5, 0x1078, 0x1b22, 0x0078, 0x1823, 0x6010, 0x2068, 0x2d58,
+       0x6828, 0xa406, 0x00c0, 0x17d0, 0x682c, 0xa306, 0x0040, 0x17fe,
+       0x601c, 0xa086, 0x0008, 0x0040, 0x17fe, 0x6024, 0xd0f4, 0x00c0,
+       0x17fa, 0xd0d4, 0x0040, 0x17f6, 0x6038, 0xa402, 0x6034, 0xa303,
+       0x0040, 0x17e4, 0x00c8, 0x17f6, 0x643a, 0x6336, 0x6c2a, 0x6b2e,
+       0x047e, 0x037e, 0x2400, 0x6c7c, 0xa402, 0x6812, 0x2300, 0x6b80,
+       0xa303, 0x6816, 0x037f, 0x047f, 0x0078, 0x17fa, 0x1078, 0x8d8e,
+       0x0040, 0x17c1, 0x1078, 0x2035, 0x00c0, 0x17c1, 0x0c7e, 0x7004,
+       0x2060, 0x6024, 0xc0d4, 0x6026, 0x0c7f, 0x684c, 0xd0f4, 0x0040,
+       0x180f, 0x6817, 0xffff, 0x6813, 0xffff, 0x0078, 0x17c1, 0x6824,
+       0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc, 0x000f,
+       0x2009, 0x0011, 0x1078, 0x1824, 0x0040, 0x1822, 0x2009, 0x0001,
+       0x1078, 0x1824, 0x2d58, 0x007c, 0x8aff, 0x0040, 0x18bb, 0xa03e,
+       0x2730, 0x6850, 0xd0fc, 0x00c0, 0x1846, 0xd0f4, 0x00c0, 0x1856,
+       0x0d7e, 0x2804, 0xac68, 0x2900, 0x0079, 0x1836, 0x189d, 0x185d,
+       0x185d, 0x189d, 0x189d, 0x1895, 0x189d, 0x185d, 0x189d, 0x1863,
+       0x1863, 0x189d, 0x189d, 0x189d, 0x188c, 0x1863, 0xc0fc, 0x6852,
+       0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0x0d7e, 0xd99c, 0x0040, 0x18a0,
+       0x2804, 0xac68, 0x6f08, 0x6e0c, 0x0078, 0x18a0, 0xc0f4, 0x6852,
+       0x6b6c, 0x6a70, 0x0d7e, 0x0078, 0x18a7, 0x6b08, 0x6a0c, 0x6d00,
+       0x6c04, 0x0078, 0x18a0, 0x7b0c, 0xd3bc, 0x0040, 0x1884, 0x7004,
+       0x0e7e, 0x2070, 0x701c, 0x0e7f, 0xa086, 0x0008, 0x00c0, 0x1884,
+       0x7b08, 0xa39c, 0x0fff, 0x2d20, 0x0d7f, 0x0d7e, 0x6a14, 0x82ff,
+       0x00c0, 0x187f, 0x6810, 0xa302, 0x0048, 0x187f, 0x6b10, 0x2011,
+       0x0000, 0x2468, 0x0078, 0x1886, 0x6b10, 0x6a14, 0x6d00, 0x6c04,
+       0x6f08, 0x6e0c, 0x0078, 0x18a0, 0x0d7f, 0x0d7e, 0x6834, 0xa084,
+       0x00ff, 0xa086, 0x001e, 0x00c0, 0x189d, 0x0d7f, 0x1078, 0x1fd1,
+       0x00c0, 0x1824, 0xa00e, 0x0078, 0x18bb, 0x0d7f, 0x1078, 0x1328,
+       0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a, 0x7e3e, 0x7902, 0x7000,
+       0x8000, 0x7002, 0x0d7f, 0x6828, 0xa300, 0x682a, 0x682c, 0xa201,
+       0x682e, 0x2300, 0x6b10, 0xa302, 0x6812, 0x2200, 0x6a14, 0xa203,
+       0x6816, 0x1078, 0x1fd1, 0x007c, 0x1078, 0x1328, 0x1078, 0x1c52,
+       0x7004, 0x2060, 0x0d7e, 0x6010, 0x2068, 0x7003, 0x0000, 0x1078,
+       0x1ac6, 0x1078, 0x8a44, 0x0040, 0x18db, 0x6808, 0x8001, 0x680a,
+       0x697c, 0x6912, 0x6980, 0x6916, 0x682b, 0xffff, 0x682f, 0xffff,
+       0x6850, 0xc0bd, 0x6852, 0x0d7f, 0x1078, 0x8758, 0x0078, 0x1aad,
+       0x1078, 0x1328, 0x127e, 0x2091, 0x2100, 0x007e, 0x017e, 0x2b68,
+       0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700, 0x00c0,
+       0x18be, 0xa184, 0x0003, 0xa086, 0x0003, 0x0040, 0x18e0, 0x7000,
+       0x0079, 0x18fa, 0x1902, 0x1904, 0x1a06, 0x1a84, 0x1a9b, 0x1902,
+       0x1902, 0x1902, 0x1078, 0x1328, 0x8001, 0x7002, 0xa184, 0x0880,
+       0x00c0, 0x1919, 0x8aff, 0x0040, 0x199b, 0x2009, 0x0001, 0x1078,
+       0x1824, 0x0040, 0x1aad, 0x2009, 0x0001, 0x1078, 0x1824, 0x0078,
+       0x1aad, 0x7803, 0x0004, 0x7003, 0x0000, 0xd1bc, 0x00c0, 0x1979,
+       0x027e, 0x037e, 0x7808, 0xd0ec, 0x00c0, 0x1930, 0x7c20, 0x7d24,
+       0x7e30, 0x7f34, 0x7803, 0x0009, 0x7003, 0x0004, 0x0078, 0x1932,
+       0x1078, 0x1b9f, 0x6b28, 0x6a2c, 0x2400, 0x686e, 0xa31a, 0x2500,
+       0x6872, 0xa213, 0x6b2a, 0x6a2e, 0x0c7e, 0x7004, 0x2060, 0x6024,
+       0xd0f4, 0x00c0, 0x1945, 0x633a, 0x6236, 0x0c7f, 0x2400, 0x6910,
+       0xa100, 0x6812, 0x2500, 0x6914, 0xa101, 0x6816, 0x037f, 0x027f,
+       0x2600, 0x681e, 0x2700, 0x6822, 0x1078, 0x1fea, 0x2a00, 0x6826,
+       0x2c00, 0x681a, 0x2800, 0x6832, 0x6850, 0xc0fd, 0x6852, 0x6808,
+       0x8001, 0x680a, 0x00c0, 0x196e, 0x684c, 0xd0e4, 0x0040, 0x196e,
+       0x7004, 0x2060, 0x2009, 0x0048, 0x1078, 0x756c, 0x7000, 0xa086,
+       0x0004, 0x0040, 0x1aad, 0x7003, 0x0000, 0x1078, 0x179f, 0x0078,
+       0x1aad, 0x057e, 0x7d0c, 0xd5bc, 0x00c0, 0x1980, 0x1078, 0xa20c,
+       0x057f, 0x1078, 0x1ac6, 0x0f7e, 0x7004, 0x2078, 0x1078, 0x4893,
+       0x0040, 0x198d, 0x7824, 0xc0f5, 0x7826, 0x0f7f, 0x682b, 0xffff,
+       0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x6912, 0x6980,
+       0x6916, 0x0078, 0x1aad, 0x7004, 0x0c7e, 0x2060, 0x6024, 0x0c7f,
+       0xd0f4, 0x0040, 0x19a8, 0x6808, 0x8001, 0x680a, 0x0078, 0x1aad,
+       0x684c, 0xc0f5, 0x684e, 0x7814, 0xa005, 0x00c0, 0x19c0, 0x7003,
+       0x0000, 0x6808, 0x8001, 0x680a, 0x00c0, 0x19bc, 0x7004, 0x2060,
+       0x2009, 0x0048, 0x1078, 0x756c, 0x1078, 0x179f, 0x0078, 0x1aad,
+       0x7814, 0x6910, 0xa102, 0x6812, 0x6914, 0xa183, 0x0000, 0x6816,
+       0x7814, 0x7908, 0xa18c, 0x0fff, 0xa188, 0x0007, 0x8114, 0x8214,
+       0x8214, 0xa10a, 0x8104, 0x8004, 0x8004, 0xa20a, 0x810b, 0x810b,
+       0x810b, 0x1078, 0x1b4d, 0x7803, 0x0004, 0x780f, 0xffff, 0x7803,
+       0x0001, 0x7804, 0xd0fc, 0x0040, 0x19e1, 0x7803, 0x0002, 0x7803,
+       0x0004, 0x780f, 0x0076, 0x7004, 0x7007, 0x0000, 0x2060, 0x2009,
+       0x0048, 0x1078, 0x756c, 0x1078, 0x1b81, 0x0040, 0x19bc, 0x7908,
+       0xd1ec, 0x00c0, 0x19ff, 0x2009, 0x0009, 0x0078, 0x1a01, 0x2009,
+       0x0019, 0x7902, 0x7003, 0x0003, 0x0078, 0x1aad, 0x8001, 0x7002,
+       0xd194, 0x0040, 0x1a18, 0x7804, 0xd0fc, 0x00c0, 0x18ea, 0x8aff,
+       0x0040, 0x1aad, 0x2009, 0x0001, 0x1078, 0x1824, 0x0078, 0x1aad,
+       0xa184, 0x0880, 0x00c0, 0x1a25, 0x8aff, 0x0040, 0x1aad, 0x2009,
+       0x0001, 0x1078, 0x1824, 0x0078, 0x1aad, 0x7803, 0x0004, 0x7003,
+       0x0000, 0xd1bc, 0x00c0, 0x1a65, 0x027e, 0x037e, 0x7808, 0xd0ec,
+       0x00c0, 0x1a38, 0x7803, 0x0009, 0x7003, 0x0004, 0x0078, 0x1a3a,
+       0x1078, 0x1b9f, 0x6b28, 0x6a2c, 0x1078, 0x1fea, 0x0d7e, 0x0f7e,
+       0x2d78, 0x2804, 0xac68, 0x6034, 0xd09c, 0x00c0, 0x1a55, 0x6808,
+       0x2008, 0xa31a, 0x680c, 0xa213, 0x7810, 0xa100, 0x7812, 0x690c,
+       0x7814, 0xa101, 0x7816, 0x0078, 0x1a61, 0x6810, 0x2008, 0xa31a,
+       0x6814, 0xa213, 0x7810, 0xa100, 0x7812, 0x6914, 0x7814, 0xa101,
+       0x7816, 0x0f7f, 0x0d7f, 0x0078, 0x1934, 0x057e, 0x7d0c, 0x1078,
+       0xa20c, 0x057f, 0x1078, 0x1ac6, 0x0f7e, 0x7004, 0x2078, 0x1078,
+       0x4893, 0x0040, 0x1a76, 0x7824, 0xc0f5, 0x7826, 0x0f7f, 0x682b,
+       0xffff, 0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x6912,
+       0x6980, 0x6916, 0x0078, 0x1aad, 0x7803, 0x0004, 0x7003, 0x0000,
+       0x7004, 0xa00d, 0x0040, 0x1a97, 0x6808, 0x8001, 0x680a, 0x00c0,
+       0x1a97, 0x7004, 0x2060, 0x2009, 0x0048, 0x1078, 0x756c, 0x1078,
+       0x179f, 0x0078, 0x1aad, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004,
+       0x2060, 0x6010, 0xa005, 0x0040, 0x1a97, 0x2068, 0x6808, 0x8000,
+       0x680a, 0x6c28, 0x6b2c, 0x1078, 0x17be, 0x017f, 0x007f, 0x127f,
+       0x007c, 0x127e, 0x2091, 0x2100, 0x7000, 0xa086, 0x0003, 0x00c0,
+       0x1ac4, 0x700c, 0x7110, 0xa106, 0x0040, 0x1ac4, 0x20e1, 0x9028,
+       0x700f, 0xa5e7, 0x7013, 0xa5e7, 0x127f, 0x007c, 0x0c7e, 0x1078,
+       0x1af7, 0x20e1, 0x9028, 0x700c, 0x7110, 0xa106, 0x0040, 0x1aed,
+       0x2104, 0xa005, 0x0040, 0x1ada, 0x2060, 0x6010, 0x2060, 0x6008,
+       0x8001, 0x600a, 0xa188, 0x0003, 0xa182, 0xa602, 0x0048, 0x1ae2,
+       0x2009, 0xa5e7, 0x7112, 0x700c, 0xa106, 0x00c0, 0x1acb, 0x2001,
+       0x0138, 0x2003, 0x0008, 0x0078, 0x1acb, 0x2001, 0x015d, 0x200c,
+       0x810a, 0x2102, 0x2001, 0x0138, 0x2202, 0x0c7f, 0x007c, 0x2001,
+       0x0138, 0x2014, 0x2003, 0x0000, 0x2021, 0xb015, 0x2001, 0x0141,
+       0x201c, 0xd3dc, 0x00c0, 0x1b14, 0x2001, 0x0109, 0x201c, 0xa39c,
+       0x0048, 0x00c0, 0x1b14, 0x2001, 0x0111, 0x201c, 0x83ff, 0x00c0,
+       0x1b14, 0x8421, 0x00c0, 0x1afe, 0x007c, 0x2011, 0x0201, 0x2009,
+       0x003c, 0x2204, 0xa005, 0x00c0, 0x1b21, 0x8109, 0x00c0, 0x1b19,
+       0x007c, 0x007c, 0x1078, 0x1b15, 0x0040, 0x1b4a, 0x7908, 0xd1ec,
+       0x00c0, 0x1b3a, 0x1078, 0x1b81, 0x0040, 0x1b3a, 0x7803, 0x0009,
+       0x7904, 0xd1fc, 0x0040, 0x1b30, 0x7803, 0x0006, 0x1078, 0x1b15,
+       0x0040, 0x1b4a, 0x780c, 0xd0a4, 0x00c0, 0x1b4a, 0x7007, 0x0000,
+       0x1078, 0x1b81, 0x0040, 0x1b4c, 0x7803, 0x0019, 0x7003, 0x0003,
+       0x0078, 0x1b4c, 0x1078, 0x1ac6, 0x007c, 0x0e7e, 0x2071, 0x0200,
+       0x7808, 0xa084, 0xf000, 0xa10d, 0x1078, 0x1af7, 0x2019, 0x5000,
+       0x8319, 0x0040, 0x1b6b, 0x2001, 0xa602, 0x2004, 0xa086, 0x0000,
+       0x0040, 0x1b6b, 0x2001, 0x0021, 0xd0fc, 0x0040, 0x1b58, 0x1078,
+       0x1e5d, 0x0078, 0x1b56, 0x20e1, 0x7000, 0x7324, 0x7420, 0x7028,
+       0x7028, 0x7426, 0x7037, 0x0001, 0x810f, 0x712e, 0x702f, 0x0100,
+       0x7037, 0x0008, 0x7326, 0x7422, 0x2001, 0x0138, 0x2202, 0x0e7f,
+       0x007c, 0x7908, 0xa18c, 0x0fff, 0xa182, 0x0009, 0x0048, 0x1b8c,
+       0xa085, 0x0001, 0x0078, 0x1b9e, 0x2001, 0x020a, 0x81ff, 0x0040,
+       0x1b97, 0x20e1, 0x6000, 0x200c, 0x200c, 0x200c, 0x200c, 0x20e1,
+       0x7000, 0x200c, 0x200c, 0x7003, 0x0000, 0xa006, 0x007c, 0x7c20,
+       0x7d24, 0x7e30, 0x7f34, 0x700c, 0x7110, 0xa106, 0x0040, 0x1c24,
+       0x7004, 0x017e, 0x210c, 0xa106, 0x017f, 0x0040, 0x1c24, 0x0d7e,
+       0x0c7e, 0x216c, 0x2d00, 0xa005, 0x0040, 0x1c22, 0x6824, 0xd0d4,
+       0x00c0, 0x1c22, 0x6810, 0x2068, 0x6850, 0xd0fc, 0x0040, 0x1bec,
+       0x8108, 0x2104, 0x6b2c, 0xa306, 0x00c0, 0x1c22, 0x8108, 0x2104,
+       0x6a28, 0xa206, 0x00c0, 0x1c22, 0x6850, 0xc0fc, 0xc0f5, 0x6852,
+       0x686c, 0x7822, 0x6870, 0x7826, 0x681c, 0x7832, 0x6820, 0x7836,
+       0x6818, 0x2060, 0x6034, 0xd09c, 0x0040, 0x1be7, 0x6830, 0x2004,
+       0xac68, 0x6808, 0x783a, 0x680c, 0x783e, 0x0078, 0x1c20, 0xa006,
+       0x783a, 0x783e, 0x0078, 0x1c20, 0x8108, 0x2104, 0xa005, 0x00c0,
+       0x1c22, 0x8108, 0x2104, 0xa005, 0x00c0, 0x1c22, 0x6850, 0xc0f5,
+       0x6852, 0x6830, 0x2004, 0x6918, 0xa160, 0xa180, 0x000d, 0x2004,
+       0xd09c, 0x00c0, 0x1c12, 0x6008, 0x7822, 0x686e, 0x600c, 0x7826,
+       0x6872, 0x6000, 0x7832, 0x6004, 0x7836, 0xa006, 0x783a, 0x783e,
+       0x0078, 0x1c20, 0x6010, 0x7822, 0x686e, 0x6014, 0x7826, 0x6872,
+       0x6000, 0x7832, 0x6004, 0x7836, 0x6008, 0x783a, 0x600c, 0x783e,
+       0x7803, 0x0011, 0x0c7f, 0x0d7f, 0x007c, 0x0f7e, 0x0e7e, 0x017e,
+       0x027e, 0x2071, 0xa5e1, 0x2079, 0x0030, 0x2011, 0x0050, 0x7000,
+       0xa086, 0x0000, 0x0040, 0x1c4d, 0x8211, 0x0040, 0x1c4b, 0x2001,
+       0x0005, 0x2004, 0xd08c, 0x0040, 0x1c34, 0x7904, 0xa18c, 0x0780,
+       0x017e, 0x1078, 0x18e2, 0x017f, 0x81ff, 0x00c0, 0x1c4b, 0x2011,
+       0x0050, 0x0078, 0x1c2f, 0xa085, 0x0001, 0x027f, 0x017f, 0x0e7f,
+       0x0f7f, 0x007c, 0x7803, 0x0004, 0x2009, 0x0064, 0x7804, 0xd0ac,
+       0x0040, 0x1ca3, 0x8109, 0x00c0, 0x1c56, 0x2009, 0x0100, 0x210c,
+       0xa18a, 0x0003, 0x1048, 0x1328, 0x1078, 0x1f75, 0x0e7e, 0x0f7e,
+       0x2071, 0xa5d0, 0x2079, 0x0010, 0x7004, 0xa086, 0x0000, 0x0040,
+       0x1c9b, 0x7800, 0x007e, 0x7820, 0x007e, 0x7830, 0x007e, 0x7834,
+       0x007e, 0x7838, 0x007e, 0x783c, 0x007e, 0x7803, 0x0004, 0x7823,
+       0x0000, 0x0005, 0x0005, 0x2079, 0x0030, 0x7804, 0xd0ac, 0x10c0,
+       0x1328, 0x2079, 0x0010, 0x007f, 0x783e, 0x007f, 0x783a, 0x007f,
+       0x7836, 0x007f, 0x7832, 0x007f, 0x7822, 0x007f, 0x7802, 0x0f7f,
+       0x0e7f, 0x0078, 0x1ca1, 0x0f7f, 0x0e7f, 0x7804, 0xd0ac, 0x10c0,
+       0x1328, 0x1078, 0x61d3, 0x007c, 0x0e7e, 0x2071, 0xa602, 0x7003,
+       0x0000, 0x0e7f, 0x007c, 0x0d7e, 0xa280, 0x0004, 0x206c, 0x694c,
+       0xd1dc, 0x00c0, 0x1d26, 0x6934, 0xa184, 0x0007, 0x0079, 0x1cb8,
+       0x1cc0, 0x1d11, 0x1cc0, 0x1cc0, 0x1cc0, 0x1cf6, 0x1cd3, 0x1cc2,
+       0x1078, 0x1328, 0x684c, 0xd0b4, 0x0040, 0x1e34, 0x6860, 0x682e,
+       0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a, 0x6880, 0x680e,
+       0x6958, 0x0078, 0x1d19, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e,
+       0x00c0, 0x1cc0, 0x684c, 0xd0b4, 0x0040, 0x1e34, 0x6860, 0x682e,
+       0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a, 0x6880, 0x680e,
+       0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080,
+       0x2015, 0x2004, 0x6832, 0x6958, 0x0078, 0x1d22, 0xa18c, 0x00ff,
+       0xa186, 0x0015, 0x00c0, 0x1d26, 0x684c, 0xd0b4, 0x0040, 0x1e34,
+       0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080,
+       0x2015, 0x2004, 0x6832, 0x6958, 0xa006, 0x682e, 0x682a, 0x0078,
+       0x1d22, 0x684c, 0xd0b4, 0x0040, 0x18bc, 0x6958, 0xa006, 0x682e,
+       0x682a, 0x2d00, 0x681a, 0x6834, 0xa084, 0x000f, 0xa080, 0x2015,
+       0x2004, 0x6832, 0x6926, 0x684c, 0xc0dd, 0x684e, 0x0d7f, 0x007c,
+       0x0f7e, 0x2079, 0x0020, 0x7804, 0xd0fc, 0x10c0, 0x1e5d, 0x0e7e,
+       0x0d7e, 0x2071, 0xa602, 0x7000, 0xa005, 0x00c0, 0x1dab, 0x0c7e,
+       0x7206, 0xa280, 0x0004, 0x205c, 0x7004, 0x2068, 0x7803, 0x0004,
+       0x6818, 0x0d7e, 0x2068, 0x686c, 0x7812, 0x6890, 0x0f7e, 0x20e1,
+       0x9040, 0x2079, 0x0200, 0x781a, 0x2079, 0x0100, 0x8004, 0x78d6,
+       0x0f7f, 0x0d7f, 0x2b68, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830,
+       0x2040, 0x6034, 0xa0cc, 0x000f, 0x6908, 0x2001, 0x04fd, 0x2004,
+       0xa086, 0x0007, 0x0040, 0x1d6d, 0xa184, 0x0007, 0x0040, 0x1d6d,
+       0x017e, 0x2009, 0x0008, 0xa102, 0x017f, 0xa108, 0x791a, 0x7116,
+       0x701e, 0x680c, 0xa081, 0x0000, 0x781e, 0x701a, 0xa006, 0x700e,
+       0x7012, 0x7004, 0x692c, 0x6814, 0xa106, 0x00c0, 0x1d84, 0x6928,
+       0x6810, 0xa106, 0x0040, 0x1d91, 0x037e, 0x047e, 0x6b14, 0x6c10,
+       0x1078, 0x2035, 0x047f, 0x037f, 0x0040, 0x1d91, 0x0c7f, 0x0078,
+       0x1dab, 0x8aff, 0x00c0, 0x1d99, 0x0c7f, 0xa085, 0x0001, 0x0078,
+       0x1dab, 0x127e, 0x2091, 0x8000, 0x2079, 0x0020, 0x2009, 0x0001,
+       0x1078, 0x1daf, 0x0040, 0x1da8, 0x2009, 0x0001, 0x1078, 0x1daf,
+       0x127f, 0x0c7f, 0xa006, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x077e,
+       0x067e, 0x057e, 0x047e, 0x037e, 0x027e, 0x8aff, 0x0040, 0x1e2d,
+       0x700c, 0x7214, 0xa23a, 0x7010, 0x7218, 0xa203, 0x0048, 0x1e2c,
+       0xa705, 0x0040, 0x1e2c, 0xa03e, 0x2730, 0x6850, 0xd0fc, 0x00c0,
+       0x1ddf, 0x0d7e, 0x2804, 0xac68, 0x2900, 0x0079, 0x1dcf, 0x1e0e,
+       0x1def, 0x1def, 0x1e0e, 0x1e0e, 0x1e06, 0x1e0e, 0x1def, 0x1e0e,
+       0x1df5, 0x1df5, 0x1e0e, 0x1e0e, 0x1e0e, 0x1dfd, 0x1df5, 0xc0fc,
+       0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0xd99c, 0x0040, 0x1e12,
+       0x0d7e, 0x2804, 0xac68, 0x6f08, 0x6e0c, 0x0078, 0x1e11, 0x6b08,
+       0x6a0c, 0x6d00, 0x6c04, 0x0078, 0x1e11, 0x6b10, 0x6a14, 0x6d00,
+       0x6c04, 0x6f08, 0x6e0c, 0x0078, 0x1e11, 0x0d7f, 0x0d7e, 0x6834,
+       0xa084, 0x00ff, 0xa086, 0x001e, 0x00c0, 0x1e0e, 0x0d7f, 0x1078,
+       0x1fd1, 0x00c0, 0x1db5, 0xa00e, 0x0078, 0x1e2d, 0x0d7f, 0x1078,
+       0x1328, 0x0d7f, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a, 0x7e3e,
+       0x7902, 0x7000, 0x8000, 0x7002, 0x6828, 0xa300, 0x682a, 0x682c,
+       0xa201, 0x682e, 0x700c, 0xa300, 0x700e, 0x7010, 0xa201, 0x7012,
+       0x1078, 0x1fd1, 0x0078, 0x1e2d, 0xa006, 0x027f, 0x037f, 0x047f,
+       0x057f, 0x067f, 0x077f, 0x007c, 0x1078, 0x1328, 0x027e, 0x2001,
+       0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003,
+       0x0000, 0x7004, 0x2060, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8a44,
+       0x0040, 0x1e4d, 0x6850, 0xc0bd, 0x6852, 0x0d7f, 0x1078, 0x8758,
+       0x20e1, 0x9040, 0x1078, 0x719a, 0x2011, 0x0000, 0x1078, 0x6efc,
+       0x1078, 0x61d3, 0x027f, 0x0078, 0x1f29, 0x127e, 0x2091, 0x2200,
+       0x007e, 0x017e, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x2079, 0x0020,
+       0x2071, 0xa602, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002,
+       0xa184, 0x0700, 0x00c0, 0x1e36, 0x7000, 0x0079, 0x1e77, 0x1f29,
+       0x1e7b, 0x1ef6, 0x1f27, 0x8001, 0x7002, 0xd19c, 0x00c0, 0x1e8f,
+       0x8aff, 0x0040, 0x1eae, 0x2009, 0x0001, 0x1078, 0x1daf, 0x0040,
+       0x1f29, 0x2009, 0x0001, 0x1078, 0x1daf, 0x0078, 0x1f29, 0x7803,
+       0x0004, 0xd194, 0x0040, 0x1e9f, 0x6850, 0xc0fc, 0x6852, 0x8aff,
+       0x00c0, 0x1ea4, 0x684c, 0xc0f5, 0x684e, 0x0078, 0x1ea4, 0x1078,
+       0x1fea, 0x6850, 0xc0fd, 0x6852, 0x2a00, 0x6826, 0x2c00, 0x681a,
+       0x2800, 0x6832, 0x7003, 0x0000, 0x0078, 0x1f29, 0x711c, 0x81ff,
+       0x0040, 0x1ec4, 0x7918, 0x7922, 0x7827, 0x0000, 0x7803, 0x0001,
+       0x7000, 0x8000, 0x7002, 0x700c, 0xa100, 0x700e, 0x7010, 0xa081,
+       0x0000, 0x7012, 0x0078, 0x1f29, 0x0f7e, 0x027e, 0x781c, 0x007e,
+       0x7818, 0x007e, 0x2079, 0x0100, 0x7a14, 0xa284, 0x0004, 0xa085,
+       0x0012, 0x7816, 0x037e, 0x2019, 0x1000, 0x8319, 0x1040, 0x1328,
+       0x7820, 0xd0bc, 0x00c0, 0x1ed5, 0x037f, 0x79c8, 0x007f, 0xa102,
+       0x017f, 0x007e, 0x017e, 0x79c4, 0x007f, 0xa103, 0x78c6, 0x007f,
+       0x78ca, 0xa284, 0x0004, 0xa085, 0x0012, 0x7816, 0x027f, 0x0f7f,
+       0x7803, 0x0008, 0x7003, 0x0000, 0x0078, 0x1f29, 0x8001, 0x7002,
+       0xd194, 0x0040, 0x1f0b, 0x7804, 0xd0fc, 0x00c0, 0x1e6d, 0xd19c,
+       0x00c0, 0x1f25, 0x8aff, 0x0040, 0x1f29, 0x2009, 0x0001, 0x1078,
+       0x1daf, 0x0078, 0x1f29, 0x027e, 0x037e, 0x6b28, 0x6a2c, 0x1078,
+       0x1fea, 0x0d7e, 0x2804, 0xac68, 0x6034, 0xd09c, 0x00c0, 0x1f1e,
+       0x6808, 0xa31a, 0x680c, 0xa213, 0x0078, 0x1f22, 0x6810, 0xa31a,
+       0x6814, 0xa213, 0x0d7f, 0x0078, 0x1e9f, 0x0078, 0x1e9f, 0x1078,
+       0x1328, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x017f, 0x007f, 0x127f,
+       0x007c, 0x0f7e, 0x0e7e, 0x2071, 0xa602, 0x7000, 0xa086, 0x0000,
+       0x0040, 0x1f72, 0x2079, 0x0020, 0x017e, 0x2009, 0x0207, 0x210c,
+       0xd194, 0x0040, 0x1f4f, 0x2009, 0x020c, 0x210c, 0xa184, 0x0003,
+       0x0040, 0x1f4f, 0x20e1, 0x9040, 0x2001, 0x020c, 0x2102, 0x2009,
+       0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0xa106, 0x00c0, 0x1f5a,
+       0x20e1, 0x9040, 0x7804, 0xd0fc, 0x0040, 0x1f3d, 0x1078, 0x1e5d,
+       0x7000, 0xa086, 0x0000, 0x00c0, 0x1f3d, 0x017f, 0x7803, 0x0004,
+       0x7804, 0xd0ac, 0x00c0, 0x1f68, 0x20e1, 0x9040, 0x7803, 0x0002,
+       0x7003, 0x0000, 0x0e7f, 0x0f7f, 0x007c, 0x027e, 0x0c7e, 0x0d7e,
+       0x0e7e, 0x0f7e, 0x2071, 0xa602, 0x2079, 0x0020, 0x7000, 0xa086,
+       0x0000, 0x0040, 0x1fae, 0x7004, 0x2060, 0x6010, 0x2068, 0x1078,
+       0x8a44, 0x0040, 0x1f98, 0x6850, 0xc0b5, 0x6852, 0x680c, 0x7a1c,
+       0xa206, 0x00c0, 0x1f98, 0x6808, 0x7a18, 0xa206, 0x0040, 0x1fb4,
+       0x2001, 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004,
+       0x7003, 0x0000, 0x7004, 0x2060, 0x1078, 0x8758, 0x20e1, 0x9040,
+       0x1078, 0x719a, 0x2011, 0x0000, 0x1078, 0x6efc, 0x0f7f, 0x0e7f,
+       0x0d7f, 0x0c7f, 0x027f, 0x007c, 0x6810, 0x6a14, 0xa205, 0x00c0,
+       0x1f98, 0x684c, 0xc0dc, 0x684e, 0x2c10, 0x1078, 0x1cab, 0x2001,
+       0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003,
+       0x0000, 0x2069, 0xa5ab, 0x6833, 0x0000, 0x683f, 0x0000, 0x0078,
+       0x1fae, 0x8840, 0x2804, 0xa005, 0x00c0, 0x1fe5, 0x6004, 0xa005,
+       0x0040, 0x1fe7, 0x681a, 0x2060, 0x6034, 0xa084, 0x000f, 0xa080,
+       0x2015, 0x2044, 0x88ff, 0x1040, 0x1328, 0x8a51, 0x007c, 0x2051,
+       0x0000, 0x007c, 0x8a50, 0x8841, 0x2804, 0xa005, 0x00c0, 0x2004,
+       0x2c00, 0xad06, 0x0040, 0x1ff9, 0x6000, 0xa005, 0x00c0, 0x1ff9,
+       0x2d00, 0x2060, 0x681a, 0x6034, 0xa084, 0x000f, 0xa080, 0x2025,
+       0x2044, 0x88ff, 0x1040, 0x1328, 0x007c, 0x0000, 0x0011, 0x0015,
+       0x0019, 0x001d, 0x0021, 0x0025, 0x0029, 0x0000, 0x000f, 0x0015,
+       0x001b, 0x0021, 0x0027, 0x0000, 0x0000, 0x0000, 0x200a, 0x2006,
+       0x0000, 0x0000, 0x2014, 0x0000, 0x200a, 0x0000, 0x2011, 0x200e,
+       0x0000, 0x0000, 0x0000, 0x2014, 0x2011, 0x0000, 0x200c, 0x200c,
+       0x0000, 0x0000, 0x2014, 0x0000, 0x200c, 0x0000, 0x2012, 0x2012,
+       0x0000, 0x0000, 0x0000, 0x2014, 0x2012, 0x0a7e, 0x097e, 0x087e,
+       0x6b2e, 0x6c2a, 0x6858, 0xa055, 0x0040, 0x20d8, 0x2d60, 0x6034,
+       0xa0cc, 0x000f, 0xa9c0, 0x2015, 0xa986, 0x0007, 0x0040, 0x2050,
+       0xa986, 0x000e, 0x0040, 0x2050, 0xa986, 0x000f, 0x00c0, 0x2054,
+       0x605c, 0xa422, 0x6060, 0xa31a, 0x2804, 0xa045, 0x00c0, 0x2062,
+       0x0050, 0x205c, 0x0078, 0x20d8, 0x6004, 0xa065, 0x0040, 0x20d8,
+       0x0078, 0x203f, 0x2804, 0xa005, 0x0040, 0x2080, 0xac68, 0xd99c,
+       0x00c0, 0x2070, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0078, 0x2074,
+       0x6810, 0xa422, 0x6814, 0xa31b, 0x0048, 0x209f, 0x2300, 0xa405,
+       0x0040, 0x2086, 0x8a51, 0x0040, 0x20d8, 0x8840, 0x0078, 0x2062,
+       0x6004, 0xa065, 0x0040, 0x20d8, 0x0078, 0x203f, 0x8a51, 0x0040,
+       0x20d8, 0x8840, 0x2804, 0xa005, 0x00c0, 0x2099, 0x6004, 0xa065,
+       0x0040, 0x20d8, 0x6034, 0xa0cc, 0x000f, 0xa9c0, 0x2015, 0x2804,
+       0x2040, 0x2b68, 0x6850, 0xc0fc, 0x6852, 0x0078, 0x20cc, 0x8422,
+       0x8420, 0x831a, 0xa399, 0x0000, 0x0d7e, 0x2b68, 0x6c6e, 0x6b72,
+       0x0d7f, 0xd99c, 0x00c0, 0x20ba, 0x6908, 0x2400, 0xa122, 0x690c,
+       0x2300, 0xa11b, 0x1048, 0x1328, 0x6800, 0xa420, 0x6804, 0xa319,
+       0x0078, 0x20c6, 0x6910, 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b,
+       0x1048, 0x1328, 0x6800, 0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e,
+       0x6b22, 0x6850, 0xc0fd, 0x6852, 0x2c00, 0x681a, 0x2800, 0x6832,
+       0x2a00, 0x6826, 0x007f, 0x007f, 0x007f, 0xa006, 0x0078, 0x20dd,
+       0x087f, 0x097f, 0x0a7f, 0xa085, 0x0001, 0x007c, 0x2001, 0x0005,
+       0x2004, 0xa084, 0x0007, 0x0079, 0x20e5, 0x20ed, 0x20ee, 0x20f1,
+       0x20f4, 0x20f9, 0x20fc, 0x2101, 0x2106, 0x007c, 0x1078, 0x1e5d,
+       0x007c, 0x1078, 0x18e2, 0x007c, 0x1078, 0x18e2, 0x1078, 0x1e5d,
+       0x007c, 0x1078, 0x14b0, 0x007c, 0x1078, 0x1e5d, 0x1078, 0x14b0,
+       0x007c, 0x1078, 0x18e2, 0x1078, 0x14b0, 0x007c, 0x1078, 0x18e2,
+       0x1078, 0x1e5d, 0x1078, 0x14b0, 0x007c, 0x127e, 0x2091, 0x2300,
+       0x2079, 0x0200, 0x2071, 0xa880, 0x2069, 0xa300, 0x2009, 0x0004,
+       0x7912, 0x7817, 0x0004, 0x1078, 0x24b5, 0x781b, 0x0002, 0x20e1,
+       0x8700, 0x127f, 0x007c, 0x127e, 0x2091, 0x2300, 0x781c, 0xa084,
+       0x0007, 0x0079, 0x212b, 0x214f, 0x2133, 0x2137, 0x213b, 0x2141,
+       0x2145, 0x2149, 0x214d, 0x1078, 0x5372, 0x0078, 0x214f, 0x1078,
+       0x53b3, 0x0078, 0x214f, 0x1078, 0x5372, 0x1078, 0x53b3, 0x0078,
+       0x214f, 0x1078, 0x2151, 0x0078, 0x214f, 0x1078, 0x2151, 0x0078,
+       0x214f, 0x1078, 0x2151, 0x0078, 0x214f, 0x1078, 0x2151, 0x127f,
+       0x007c, 0x007e, 0x017e, 0x027e, 0x7930, 0xa184, 0x0003, 0x0040,
+       0x215d, 0x20e1, 0x9040, 0x0078, 0x2186, 0xa184, 0x0030, 0x0040,
+       0x216e, 0x6a00, 0xa286, 0x0003, 0x00c0, 0x2168, 0x0078, 0x216a,
+       0x1078, 0x4171, 0x20e1, 0x9010, 0x0078, 0x2186, 0xa184, 0x00c0,
+       0x0040, 0x2180, 0x0e7e, 0x037e, 0x047e, 0x057e, 0x2071, 0xa5e1,
+       0x1078, 0x1ac6, 0x057f, 0x047f, 0x037f, 0x0e7f, 0x0078, 0x2186,
+       0xa184, 0x0300, 0x0040, 0x2186, 0x20e1, 0x9020, 0x7932, 0x027f,
+       0x017f, 0x007f, 0x007c, 0x017e, 0x0e7e, 0x0f7e, 0x2071, 0xa300,
+       0x7128, 0x2001, 0xa58f, 0x2102, 0x2001, 0xa597, 0x2102, 0xa182,
+       0x0211, 0x00c8, 0x219f, 0x2009, 0x0008, 0x0078, 0x21c9, 0xa182,
+       0x0259, 0x00c8, 0x21a7, 0x2009, 0x0007, 0x0078, 0x21c9, 0xa182,
+       0x02c1, 0x00c8, 0x21af, 0x2009, 0x0006, 0x0078, 0x21c9, 0xa182,
+       0x0349, 0x00c8, 0x21b7, 0x2009, 0x0005, 0x0078, 0x21c9, 0xa182,
+       0x0421, 0x00c8, 0x21bf, 0x2009, 0x0004, 0x0078, 0x21c9, 0xa182,
+       0x0581, 0x00c8, 0x21c7, 0x2009, 0x0003, 0x0078, 0x21c9, 0x2009,
+       0x0002, 0x2079, 0x0200, 0x7912, 0x7817, 0x0004, 0x1078, 0x24b5,
+       0x0f7f, 0x0e7f, 0x017f, 0x007c, 0x127e, 0x2091, 0x2200, 0x2061,
+       0x0100, 0x2071, 0xa300, 0x6024, 0x6026, 0x6053, 0x0030, 0x6033,
+       0x00ef, 0x60e7, 0x0000, 0x60eb, 0x00ef, 0x60e3, 0x0008, 0x604b,
+       0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080, 0x602f, 0x0000, 0x6007,
+       0x0eaf, 0x600f, 0x00ff, 0x602b, 0x002f, 0x127f, 0x007c, 0x2001,
+       0xa32f, 0x2003, 0x0000, 0x2001, 0xa32e, 0x2003, 0x0001, 0x007c,
+       0x127e, 0x2091, 0x2200, 0x007e, 0x017e, 0x027e, 0x6124, 0xa184,
+       0x002c, 0x00c0, 0x220f, 0xa184, 0x0007, 0x0079, 0x2215, 0xa195,
+       0x0004, 0xa284, 0x0007, 0x0079, 0x2215, 0x2241, 0x221d, 0x2221,
+       0x2225, 0x222b, 0x222f, 0x2235, 0x223b, 0x1078, 0x5ad2, 0x0078,
+       0x2241, 0x1078, 0x5bc1, 0x0078, 0x2241, 0x1078, 0x5bc1, 0x1078,
+       0x5ad2, 0x0078, 0x2241, 0x1078, 0x2246, 0x0078, 0x2241, 0x1078,
+       0x5ad2, 0x1078, 0x2246, 0x0078, 0x2241, 0x1078, 0x5bc1, 0x1078,
+       0x2246, 0x0078, 0x2241, 0x1078, 0x5bc1, 0x1078, 0x5ad2, 0x1078,
+       0x2246, 0x027f, 0x017f, 0x007f, 0x127f, 0x007c, 0x6124, 0xd1ac,
+       0x0040, 0x2342, 0x017e, 0x047e, 0x0c7e, 0x644c, 0xa486, 0xf0f0,
+       0x00c0, 0x2259, 0x2061, 0x0100, 0x644a, 0x6043, 0x0090, 0x6043,
+       0x0010, 0x74c2, 0xa48c, 0xff00, 0x7034, 0xd084, 0x0040, 0x2271,
+       0xa186, 0xf800, 0x00c0, 0x2271, 0x7038, 0xd084, 0x00c0, 0x2271,
+       0xc085, 0x703a, 0x037e, 0x2418, 0x2011, 0x8016, 0x1078, 0x3579,
+       0x037f, 0xa196, 0xff00, 0x0040, 0x22b3, 0x6030, 0xa084, 0x00ff,
+       0x810f, 0xa116, 0x0040, 0x22b3, 0x7130, 0xd184, 0x00c0, 0x22b3,
+       0x2011, 0xa352, 0x2214, 0xd2ec, 0x0040, 0x228e, 0xc18d, 0x7132,
+       0x2011, 0xa352, 0x2214, 0xd2ac, 0x00c0, 0x22b3, 0x6240, 0xa294,
+       0x0010, 0x0040, 0x229a, 0x6248, 0xa294, 0xff00, 0xa296, 0xff00,
+       0x0040, 0x22b3, 0x7030, 0xd08c, 0x0040, 0x2305, 0x7034, 0xd08c,
+       0x00c0, 0x22aa, 0x2001, 0xa30c, 0x200c, 0xd1ac, 0x00c0, 0x2305,
+       0xc1ad, 0x2102, 0x037e, 0x73c0, 0x2011, 0x8013, 0x1078, 0x3579,
+       0x037f, 0x0078, 0x2305, 0x7034, 0xd08c, 0x00c0, 0x22bf, 0x2001,
+       0xa30c, 0x200c, 0xd1ac, 0x00c0, 0x2305, 0xc1ad, 0x2102, 0x037e,
+       0x73c0, 0x2011, 0x8013, 0x1078, 0x3579, 0x037f, 0x7130, 0xc185,
+       0x7132, 0x2011, 0xa352, 0x220c, 0xd1a4, 0x0040, 0x22e9, 0x017e,
+       0x2009, 0x0001, 0x2011, 0x0100, 0x1078, 0x5a6d, 0x2019, 0x000e,
+       0x1078, 0x9e3b, 0xa484, 0x00ff, 0xa080, 0x293f, 0x200c, 0xa18c,
+       0xff00, 0x810f, 0x8127, 0xa006, 0x2009, 0x000e, 0x1078, 0x9ec0,
+       0x017f, 0xd1ac, 0x00c0, 0x22f6, 0x017e, 0x2009, 0x0000, 0x2019,
+       0x0004, 0x1078, 0x27e2, 0x017f, 0x0078, 0x2305, 0x157e, 0x20a9,
+       0x007f, 0x2009, 0x0000, 0x1078, 0x4501, 0x00c0, 0x2301, 0x1078,
+       0x4235, 0x8108, 0x00f0, 0x22fb, 0x157f, 0x0c7f, 0x047f, 0x0f7e,
+       0x2079, 0xa5be, 0x783c, 0xa086, 0x0000, 0x0040, 0x2317, 0x6027,
+       0x0004, 0x783f, 0x0000, 0x2079, 0x0140, 0x7803, 0x0000, 0x0f7f,
+       0x2011, 0x0003, 0x1078, 0x6ef2, 0x2011, 0x0002, 0x1078, 0x6efc,
+       0x1078, 0x6dda, 0x1078, 0x595a, 0x037e, 0x2019, 0x0000, 0x1078,
+       0x6e6c, 0x037f, 0x60e3, 0x0000, 0x017f, 0x2001, 0xa300, 0x2014,
+       0xa296, 0x0004, 0x00c0, 0x233a, 0xd19c, 0x00c0, 0x233a, 0x6228,
+       0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0xa321, 0x2003, 0x0000,
+       0x6027, 0x0020, 0xd194, 0x0040, 0x2426, 0x0f7e, 0x2079, 0xa5be,
+       0x783c, 0xa086, 0x0001, 0x00c0, 0x2366, 0x017e, 0x6027, 0x0004,
+       0x783f, 0x0000, 0x2079, 0x0140, 0x7803, 0x1000, 0x7803, 0x0000,
+       0x2079, 0xa5ab, 0x7807, 0x0000, 0x7833, 0x0000, 0x1078, 0x6109,
+       0x1078, 0x61d3, 0x017f, 0x0f7f, 0x0078, 0x2426, 0x0f7f, 0x017e,
+       0x3900, 0xa082, 0xa6cd, 0x00c8, 0x2371, 0x017e, 0x1078, 0x728a,
+       0x017f, 0x6220, 0xd2b4, 0x0040, 0x23dc, 0x1078, 0x595a, 0x1078,
+       0x6c41, 0x6027, 0x0004, 0x0f7e, 0x2019, 0xa5b4, 0x2304, 0xa07d,
+       0x0040, 0x23b2, 0x7804, 0xa086, 0x0032, 0x00c0, 0x23b2, 0x0d7e,
+       0x0c7e, 0x0e7e, 0x2069, 0x0140, 0x618c, 0x6288, 0x7818, 0x608e,
+       0x7808, 0x608a, 0x6043, 0x0002, 0x2001, 0x0003, 0x8001, 0x00c0,
+       0x2396, 0x6043, 0x0000, 0x6803, 0x1000, 0x6803, 0x0000, 0x618e,
+       0x628a, 0x1078, 0x6010, 0x1078, 0x6109, 0x7810, 0x2070, 0x7037,
+       0x0103, 0x2f60, 0x1078, 0x753d, 0x0e7f, 0x0c7f, 0x0d7f, 0x0f7f,
+       0x017f, 0x007c, 0x0f7f, 0x0d7e, 0x2069, 0x0140, 0x6804, 0xa084,
+       0x4000, 0x0040, 0x23bf, 0x6803, 0x1000, 0x6803, 0x0000, 0x0d7f,
+       0x0c7e, 0x2061, 0xa5ab, 0x6028, 0xa09a, 0x00c8, 0x00c8, 0x23cf,
+       0x8000, 0x602a, 0x0c7f, 0x1078, 0x6c33, 0x0078, 0x2425, 0x2019,
+       0xa5b4, 0x2304, 0xa065, 0x0040, 0x23d9, 0x2009, 0x0027, 0x1078,
+       0x756c, 0x0c7f, 0x0078, 0x2425, 0xd2bc, 0x0040, 0x2425, 0x1078,
+       0x5967, 0x6017, 0x0010, 0x6027, 0x0004, 0x0d7e, 0x2069, 0x0140,
+       0x6804, 0xa084, 0x4000, 0x0040, 0x23f1, 0x6803, 0x1000, 0x6803,
+       0x0000, 0x0d7f, 0x0c7e, 0x2061, 0xa5ab, 0x6044, 0xa09a, 0x00c8,
+       0x00c8, 0x2414, 0x8000, 0x6046, 0x603c, 0x0c7f, 0xa005, 0x0040,
+       0x2425, 0x2009, 0x07d0, 0x1078, 0x595f, 0xa080, 0x0007, 0x2004,
+       0xa086, 0x0006, 0x00c0, 0x2410, 0x6017, 0x0012, 0x0078, 0x2425,
+       0x6017, 0x0016, 0x0078, 0x2425, 0x037e, 0x2019, 0x0001, 0x1078,
+       0x6e6c, 0x037f, 0x2019, 0xa5ba, 0x2304, 0xa065, 0x0040, 0x2424,
+       0x2009, 0x004f, 0x1078, 0x756c, 0x0c7f, 0x017f, 0xd19c, 0x0040,
+       0x247c, 0x7034, 0xd0ac, 0x00c0, 0x2457, 0x017e, 0x157e, 0x6027,
+       0x0008, 0x602f, 0x0020, 0x20a9, 0x000a, 0x00f0, 0x2435, 0x602f,
+       0x0000, 0x6150, 0xa185, 0x1400, 0x6052, 0x20a9, 0x0320, 0x00e0,
+       0x243f, 0x2091, 0x6000, 0x6020, 0xd09c, 0x00c0, 0x244e, 0x157f,
+       0x6152, 0x017f, 0x6027, 0x0008, 0x0078, 0x247c, 0x1078, 0x250d,
+       0x00f0, 0x243f, 0x157f, 0x6152, 0x017f, 0x6027, 0x0008, 0x017e,
+       0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x1078, 0x6ef2, 0x2011,
+       0x0002, 0x1078, 0x6efc, 0x1078, 0x6dda, 0x1078, 0x595a, 0x037e,
+       0x2019, 0x0000, 0x1078, 0x6e6c, 0x037f, 0x60e3, 0x0000, 0x1078,
+       0xa22a, 0x1078, 0xa248, 0x2001, 0xa300, 0x2003, 0x0004, 0x6027,
+       0x0008, 0x1078, 0x1246, 0x017f, 0xa18c, 0xffd0, 0x6126, 0x007c,
+       0x007e, 0x017e, 0x027e, 0x0e7e, 0x0f7e, 0x127e, 0x2091, 0x8000,
+       0x2071, 0xa300, 0x71b8, 0x70ba, 0xa116, 0x0040, 0x24ae, 0x81ff,
+       0x0040, 0x2498, 0x2011, 0x8011, 0x1078, 0x3579, 0x0078, 0x24ae,
+       0x2011, 0x8012, 0x1078, 0x3579, 0x2001, 0xa371, 0x2004, 0xd0fc,
+       0x00c0, 0x24ae, 0x037e, 0x0c7e, 0x2061, 0x0100, 0x2019, 0x0028,
+       0x2009, 0x0000, 0x1078, 0x27e2, 0x0c7f, 0x037f, 0x127f, 0x0f7f,
+       0x0e7f, 0x027f, 0x017f, 0x007f, 0x007c, 0x0c7e, 0x0f7e, 0x007e,
+       0x027e, 0x2061, 0x0100, 0xa190, 0x24d1, 0x2204, 0x60f2, 0x2011,
+       0x24de, 0x6000, 0xa082, 0x0003, 0x00c8, 0x24ca, 0x2001, 0x00ff,
+       0x0078, 0x24cb, 0x2204, 0x60ee, 0x027f, 0x007f, 0x0f7f, 0x0c7f,
+       0x007c, 0x0840, 0x0840, 0x0840, 0x0580, 0x0420, 0x0348, 0x02c0,
+       0x0258, 0x0210, 0x01a8, 0x01a8, 0x01a8, 0x01a8, 0x0140, 0x00f8,
+       0x00d0, 0x00b0, 0x00a0, 0x2028, 0xa18c, 0x00ff, 0x2130, 0xa094,
+       0xff00, 0x00c0, 0x24ee, 0x81ff, 0x0040, 0x24f2, 0x1078, 0x5623,
+       0x0078, 0x24f9, 0xa080, 0x293f, 0x200c, 0xa18c, 0xff00, 0x810f,
+       0xa006, 0x007c, 0xa080, 0x293f, 0x200c, 0xa18c, 0x00ff, 0x007c,
+       0x0c7e, 0x2061, 0xa300, 0x6030, 0x0040, 0x2509, 0xc09d, 0x0078,
+       0x250a, 0xc09c, 0x6032, 0x0c7f, 0x007c, 0x007e, 0x157e, 0x0f7e,
+       0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd08c, 0x00c0, 0x251a,
+       0x00f0, 0x2514, 0x0f7f, 0x157f, 0x007f, 0x007c, 0x0c7e, 0x007e,
+       0x2061, 0x0100, 0x6030, 0x007e, 0x6048, 0x007e, 0x60e4, 0x007e,
+       0x60e8, 0x007e, 0x6050, 0x007e, 0x60f0, 0x007e, 0x60ec, 0x007e,
+       0x600c, 0x007e, 0x6004, 0x007e, 0x6028, 0x007e, 0x60e0, 0x007e,
+       0x602f, 0x0100, 0x602f, 0x0000, 0x0005, 0x0005, 0x0005, 0x0005,
+       0x602f, 0x0040, 0x602f, 0x0000, 0x007f, 0x60e2, 0x007f, 0x602a,
+       0x007f, 0x6006, 0x007f, 0x600e, 0x007f, 0x60ee, 0x007f, 0x60f2,
+       0x007f, 0x6052, 0x007f, 0x60ea, 0x007f, 0x60e6, 0x007f, 0x604a,
+       0x007f, 0x6032, 0x007f, 0x0c7f, 0x007c, 0x257d, 0x2581, 0x2585,
+       0x258b, 0x2591, 0x2597, 0x259d, 0x25a5, 0x25ad, 0x25b3, 0x25b9,
+       0x25c1, 0x25c9, 0x25d1, 0x25d9, 0x25e3, 0x25ed, 0x25ed, 0x25ed,
+       0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed,
+       0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x107e, 0x007e, 0x0078,
+       0x2606, 0x107e, 0x007e, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078,
+       0x2200, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x0078,
+       0x2606, 0x107e, 0x007e, 0x1078, 0x20de, 0x0078, 0x2606, 0x107e,
+       0x007e, 0x1078, 0x20de, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078,
+       0x2200, 0x1078, 0x20de, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078,
+       0x2200, 0x1078, 0x20de, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078,
+       0x2123, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078, 0x2123, 0x0078,
+       0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x1078, 0x2123, 0x0078,
+       0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x1078, 0x2123, 0x0078,
+       0x2606, 0x107e, 0x007e, 0x1078, 0x20de, 0x1078, 0x2123, 0x0078,
+       0x2606, 0x107e, 0x007e, 0x1078, 0x20de, 0x1078, 0x2123, 0x0078,
+       0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x1078, 0x20de, 0x1078,
+       0x2123, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x1078,
+       0x20de, 0x1078, 0x2123, 0x0078, 0x2606, 0x0005, 0x0078, 0x25ed,
+       0xb084, 0x003c, 0x8004, 0x8004, 0x0079, 0x25f6, 0x2606, 0x2583,
+       0x2587, 0x258d, 0x2593, 0x2599, 0x259f, 0x25a7, 0x25af, 0x25b5,
+       0x25bb, 0x25c3, 0x25cb, 0x25d3, 0x25db, 0x25e5, 0x0008, 0x25f0,
+       0x007f, 0x107f, 0x2091, 0x8001, 0x007c, 0x0c7e, 0x027e, 0x047e,
+       0x2021, 0x0000, 0x1078, 0x4897, 0x00c0, 0x2705, 0x70c8, 0xd09c,
+       0x0040, 0x2624, 0xd084, 0x00c0, 0x2624, 0xd0bc, 0x00c0, 0x2705,
+       0x1078, 0x2709, 0x0078, 0x2705, 0xd094, 0x0040, 0x262b, 0x7093,
+       0xffff, 0x0078, 0x2705, 0x2001, 0x010c, 0x203c, 0x7280, 0xd284,
+       0x0040, 0x2694, 0xd28c, 0x00c0, 0x2694, 0x037e, 0x7390, 0xa38e,
+       0xffff, 0x0040, 0x263e, 0x83ff, 0x00c0, 0x2640, 0x2019, 0x0001,
+       0x8314, 0xa2e0, 0xa9c0, 0x2c04, 0xa38c, 0x0001, 0x0040, 0x264d,
+       0xa084, 0xff00, 0x8007, 0x0078, 0x264f, 0xa084, 0x00ff, 0xa70e,
+       0x0040, 0x2689, 0xa08e, 0x0000, 0x0040, 0x2689, 0xa08e, 0x00ff,
+       0x00c0, 0x2666, 0x7230, 0xd284, 0x00c0, 0x268f, 0x7280, 0xc28d,
+       0x7282, 0x7093, 0xffff, 0x037f, 0x0078, 0x2694, 0x2009, 0x0000,
+       0x1078, 0x24e3, 0x1078, 0x4499, 0x00c0, 0x268c, 0x6004, 0xa084,
+       0x00ff, 0xa086, 0x0006, 0x00c0, 0x2683, 0x7030, 0xd08c, 0x0040,
+       0x267d, 0x6000, 0xd0bc, 0x0040, 0x2683, 0x1078, 0x271f, 0x0040,
+       0x268c, 0x0078, 0x2689, 0x1078, 0x2857, 0x1078, 0x274c, 0x0040,
+       0x268c, 0x8318, 0x0078, 0x2640, 0x7392, 0x0078, 0x2691, 0x7093,
+       0xffff, 0x037f, 0x0078, 0x2705, 0xa780, 0x293f, 0x203c, 0xa7bc,
+       0xff00, 0x873f, 0x2041, 0x007e, 0x7090, 0xa096, 0xffff, 0x00c0,
+       0x26a6, 0x2009, 0x0000, 0x28a8, 0x0078, 0x26b2, 0xa812, 0x0048,
+       0x26ae, 0x2008, 0xa802, 0x20a8, 0x0078, 0x26b2, 0x7093, 0xffff,
+       0x0078, 0x2705, 0x2700, 0x157e, 0x017e, 0xa106, 0x0040, 0x26f9,
+       0xc484, 0x1078, 0x4501, 0x0040, 0x26c3, 0x1078, 0x4499, 0x00c0,
+       0x2702, 0x0078, 0x26c4, 0xc485, 0x6004, 0xa084, 0x00ff, 0xa086,
+       0x0006, 0x00c0, 0x26d3, 0x7030, 0xd08c, 0x0040, 0x26f1, 0x6000,
+       0xd0bc, 0x00c0, 0x26f1, 0x7280, 0xd28c, 0x0040, 0x26e9, 0x6004,
+       0xa084, 0x00ff, 0xa082, 0x0006, 0x0048, 0x26f9, 0xd484, 0x00c0,
+       0x26e5, 0x1078, 0x44bc, 0x0078, 0x26e7, 0x1078, 0x2921, 0x0078,
+       0x26f9, 0x1078, 0x2857, 0x1078, 0x274c, 0x0040, 0x2702, 0x0078,
+       0x26f9, 0x1078, 0x28ec, 0x0040, 0x26f9, 0x1078, 0x271f, 0x0040,
+       0x2702, 0x017f, 0x8108, 0x157f, 0x00f0, 0x26b2, 0x7093, 0xffff,
+       0x0078, 0x2705, 0x017f, 0x157f, 0x7192, 0x047f, 0x027f, 0x0c7f,
+       0x007c, 0x0c7e, 0x017e, 0x7093, 0x0000, 0x2009, 0x007e, 0x1078,
+       0x4499, 0x00c0, 0x271c, 0x1078, 0x2857, 0x1078, 0x274c, 0x0040,
+       0x271c, 0x70c8, 0xc0bd, 0x70ca, 0x017f, 0x0c7f, 0x007c, 0x017e,
+       0x077e, 0x0d7e, 0x0c7e, 0x2c68, 0x2001, 0xa356, 0x2004, 0xa084,
+       0x00ff, 0x6842, 0x1078, 0x74d7, 0x0040, 0x2747, 0x2d00, 0x601a,
+       0x601f, 0x0001, 0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0000,
+       0x1078, 0x443f, 0x127e, 0x2091, 0x8000, 0x708c, 0x8000, 0x708e,
+       0x127f, 0x2009, 0x0004, 0x1078, 0x756c, 0xa085, 0x0001, 0x0c7f,
+       0x0d7f, 0x077f, 0x017f, 0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e,
+       0x2c68, 0x2001, 0xa356, 0x2004, 0xa084, 0x00ff, 0x6842, 0x1078,
+       0x74d7, 0x0040, 0x2785, 0x2d00, 0x601a, 0x6800, 0xc0c4, 0x6802,
+       0x68a0, 0xa086, 0x007e, 0x0040, 0x276e, 0x6804, 0xa084, 0x00ff,
+       0xa086, 0x0006, 0x00c0, 0x276e, 0x1078, 0x2813, 0x601f, 0x0001,
+       0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0002, 0x1078, 0x443f,
+       0x127e, 0x2091, 0x8000, 0x708c, 0x8000, 0x708e, 0x127f, 0x2009,
+       0x0002, 0x1078, 0x756c, 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f,
+       0x017f, 0x007c, 0x0c7e, 0x027e, 0x2009, 0x0080, 0x1078, 0x4499,
+       0x00c0, 0x2798, 0x1078, 0x279b, 0x0040, 0x2798, 0x70cf, 0xffff,
+       0x027f, 0x0c7f, 0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e, 0x2c68,
+       0x1078, 0x74d7, 0x0040, 0x27bd, 0x2d00, 0x601a, 0x601f, 0x0001,
+       0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0002, 0x1078, 0x443f,
+       0x127e, 0x2091, 0x8000, 0x70d0, 0x8000, 0x70d2, 0x127f, 0x2009,
+       0x0002, 0x1078, 0x756c, 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f,
+       0x017f, 0x007c, 0x0c7e, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2009,
+       0x007f, 0x1078, 0x4499, 0x00c0, 0x27de, 0x2c68, 0x1078, 0x74d7,
+       0x0040, 0x27de, 0x2d00, 0x601a, 0x6312, 0x601f, 0x0001, 0x620a,
+       0x2009, 0x0022, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f, 0x0d7f,
+       0x0c7f, 0x007c, 0x0e7e, 0x0c7e, 0x067e, 0x037e, 0x027e, 0x1078,
+       0x5d60, 0x1078, 0x5d02, 0x1078, 0x7ddf, 0x2130, 0x81ff, 0x0040,
+       0x27f7, 0x20a9, 0x007e, 0x2009, 0x0000, 0x0078, 0x27fb, 0x20a9,
+       0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x4501, 0x00c0, 0x2804,
+       0x1078, 0x471b, 0x1078, 0x4235, 0x017f, 0x8108, 0x00f0, 0x27fb,
+       0x86ff, 0x00c0, 0x280d, 0x1078, 0x119b, 0x027f, 0x037f, 0x067f,
+       0x0c7f, 0x0e7f, 0x007c, 0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e,
+       0x6218, 0x2270, 0x72a0, 0x027e, 0x2019, 0x0029, 0x1078, 0x5d53,
+       0x077e, 0x2039, 0x0000, 0x1078, 0x5c78, 0x2c08, 0x1078, 0x9c38,
+       0x077f, 0x017f, 0x2e60, 0x1078, 0x471b, 0x6210, 0x6314, 0x1078,
+       0x4235, 0x6212, 0x6316, 0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f,
+       0x007c, 0x0e7e, 0x007e, 0x6018, 0xa080, 0x0028, 0x2004, 0xd0bc,
+       0x00c0, 0x284d, 0x2071, 0xa300, 0x708c, 0xa005, 0x0040, 0x284a,
+       0x8001, 0x708e, 0x007f, 0x0e7f, 0x007c, 0x2071, 0xa300, 0x70d0,
+       0xa005, 0x0040, 0x284a, 0x8001, 0x70d2, 0x0078, 0x284a, 0x6000,
+       0xc08c, 0x6002, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x037e, 0x027e,
+       0x017e, 0x157e, 0x2178, 0x81ff, 0x00c0, 0x286a, 0x20a9, 0x0001,
+       0x0078, 0x2885, 0x2001, 0xa352, 0x2004, 0xd0c4, 0x0040, 0x2881,
+       0xd0a4, 0x0040, 0x2881, 0x047e, 0x6018, 0xa080, 0x0028, 0x2024,
+       0xa4a4, 0x00ff, 0x8427, 0xa006, 0x2009, 0x002d, 0x1078, 0x9ec0,
+       0x047f, 0x20a9, 0x00ff, 0x2011, 0x0000, 0x027e, 0xa28e, 0x007e,
+       0x0040, 0x28c9, 0xa28e, 0x007f, 0x0040, 0x28c9, 0xa28e, 0x0080,
+       0x0040, 0x28c9, 0xa288, 0xa434, 0x210c, 0x81ff, 0x0040, 0x28c9,
+       0x8fff, 0x1040, 0x28d5, 0x0c7e, 0x2160, 0x2001, 0x0001, 0x1078,
+       0x48a2, 0x0c7f, 0x2019, 0x0029, 0x1078, 0x5d53, 0x077e, 0x2039,
+       0x0000, 0x1078, 0x5c78, 0x0c7e, 0x027e, 0x2160, 0x6204, 0xa294,
+       0x00ff, 0xa286, 0x0006, 0x00c0, 0x28b9, 0x6007, 0x0404, 0x0078,
+       0x28be, 0x2001, 0x0004, 0x8007, 0xa215, 0x6206, 0x027f, 0x0c7f,
+       0x017e, 0x2c08, 0x1078, 0x9c38, 0x017f, 0x077f, 0x2160, 0x1078,
+       0x471b, 0x027f, 0x8210, 0x00f0, 0x2885, 0x157f, 0x017f, 0x027f,
+       0x037f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0x047e, 0x027e, 0x017e,
+       0x2001, 0xa352, 0x2004, 0xd0c4, 0x0040, 0x28e8, 0xd0a4, 0x0040,
+       0x28e8, 0xa006, 0x2220, 0x8427, 0x2009, 0x0029, 0x1078, 0x9ec0,
+       0x017f, 0x027f, 0x047f, 0x007c, 0x017e, 0x027e, 0x037e, 0x0c7e,
+       0x7280, 0x82ff, 0x0040, 0x291a, 0xa290, 0xa352, 0x2214, 0xd2ac,
+       0x00c0, 0x291a, 0x2100, 0x1078, 0x24fa, 0x81ff, 0x0040, 0x291c,
+       0x2019, 0x0001, 0x8314, 0xa2e0, 0xa9c0, 0x2c04, 0xd384, 0x0040,
+       0x290e, 0xa084, 0xff00, 0x8007, 0x0078, 0x2910, 0xa084, 0x00ff,
+       0xa116, 0x0040, 0x291c, 0xa096, 0x00ff, 0x0040, 0x291a, 0x8318,
+       0x0078, 0x2902, 0xa085, 0x0001, 0x0c7f, 0x037f, 0x027f, 0x017f,
+       0x007c, 0x017e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0xa180, 0xa434,
+       0x2004, 0xa065, 0x0040, 0x293b, 0x017e, 0x0c7e, 0x1078, 0x8ec0,
+       0x017f, 0x1040, 0x1328, 0x611a, 0x1078, 0x2813, 0x1078, 0x753d,
+       0x017f, 0x1078, 0x44bc, 0x127f, 0x0c7f, 0x017f, 0x007c, 0x7eef,
+       0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc, 0x80da, 0x7ad9,
+       0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1, 0x79ce, 0x78cd,
+       0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6, 0x77c5, 0x76c3,
+       0x80bc, 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4, 0x72b3, 0x80b2,
+       0x80b1, 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa, 0x6ea9, 0x80a7,
+       0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d, 0x809b, 0x8098,
+       0x6797, 0x6690, 0x658f, 0x6488, 0x6384, 0x6282, 0x8081, 0x8080,
+       0x617c, 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074, 0x8073, 0x8072,
+       0x8071, 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a, 0x5b69, 0x8067,
+       0x5a66, 0x5965, 0x5863, 0x575c, 0x565a, 0x5559, 0x8056, 0x8055,
+       0x5454, 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d, 0x804c, 0x804b,
+       0x4e4a, 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043, 0x803c, 0x803a,
+       0x8039, 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932, 0x4831, 0x802e,
+       0x472d, 0x462c, 0x452b, 0x442a, 0x4329, 0x4227, 0x8026, 0x8025,
+       0x4123, 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18, 0x8017, 0x8010,
+       0x3b0f, 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000, 0x8000, 0x3800,
+       0x3700, 0x3600, 0x8000, 0x3500, 0x8000, 0x8000, 0x8000, 0x3400,
+       0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3300, 0x3200,
+       0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3100, 0x3000,
+       0x8000, 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00, 0x2c00, 0x8000,
+       0x8000, 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900, 0x2800, 0x8000,
+       0x2700, 0x2600, 0x2500, 0x2400, 0x2300, 0x2200, 0x8000, 0x8000,
+       0x2100, 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, 0x8000, 0x8000,
+       0x1b00, 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000, 0x8000, 0x8000,
+       0x8000, 0x8000, 0x1800, 0x8000, 0x1700, 0x1600, 0x1500, 0x8000,
+       0x1400, 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00, 0x8000, 0x8000,
+       0x0e00, 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900, 0x8000, 0x8000,
+       0x0800, 0x0700, 0x8000, 0x0600, 0x8000, 0x8000, 0x8000, 0x0500,
+       0x0400, 0x0300, 0x8000, 0x0200, 0x8000, 0x8000, 0x8000, 0x0100,
+       0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x8000,
+       0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+       0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x2071,
+       0xa381, 0x7003, 0x0002, 0xa006, 0x7012, 0x7016, 0x703a, 0x703e,
+       0x7033, 0xa391, 0x7037, 0xa391, 0x7007, 0x0001, 0x2061, 0xa3d1,
+       0x6003, 0x0002, 0x007c, 0x0090, 0x2a66, 0x0068, 0x2a66, 0x2071,
+       0xa381, 0x2b78, 0x7818, 0xd084, 0x00c0, 0x2a66, 0x2a60, 0x7820,
+       0xa08e, 0x0069, 0x00c0, 0x2b56, 0x0079, 0x2aea, 0x007c, 0x2071,
+       0xa381, 0x7004, 0x0079, 0x2a6c, 0x2a70, 0x2a71, 0x2a7b, 0x2a8d,
+       0x007c, 0x0090, 0x2a7a, 0x0068, 0x2a7a, 0x2b78, 0x7818, 0xd084,
+       0x0040, 0x2a99, 0x007c, 0x2b78, 0x2061, 0xa3d1, 0x6008, 0xa08e,
+       0x0100, 0x0040, 0x2a88, 0xa086, 0x0200, 0x0040, 0x2b4e, 0x007c,
+       0x7014, 0x2068, 0x2a60, 0x7018, 0x007a, 0x7010, 0x2068, 0x6834,
+       0xa086, 0x0103, 0x0040, 0x2a95, 0x007c, 0x2a60, 0x2b78, 0x7018,
+       0x007a, 0x2a60, 0x7820, 0xa08a, 0x0040, 0x00c8, 0x2aa2, 0x61b8,
+       0x0079, 0x2aaa, 0x2100, 0xa08a, 0x003f, 0x00c8, 0x2b4a, 0x61b8,
+       0x0079, 0x2aea, 0x2b2c, 0x2b5e, 0x2b66, 0x2b6a, 0x2b72, 0x2b78,
+       0x2b7c, 0x2b88, 0x2b8c, 0x2b96, 0x2b9a, 0x2b4a, 0x2b4a, 0x2b4a,
+       0x2b9e, 0x2b4a, 0x2bae, 0x2bc5, 0x2bdc, 0x2c58, 0x2c5d, 0x2c8a,
+       0x2ce4, 0x2cf5, 0x2d13, 0x2d54, 0x2d5e, 0x2d6b, 0x2d7e, 0x2d9d,
+       0x2da6, 0x2de3, 0x2de9, 0x2b4a, 0x2e05, 0x2b4a, 0x2b4a, 0x2b4a,
+       0x2b4a, 0x2b4a, 0x2e0c, 0x2e16, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a,
+       0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2e1e, 0x2b4a, 0x2b4a, 0x2b4a,
+       0x2b4a, 0x2b4a, 0x2e30, 0x2e47, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a,
+       0x2b4a, 0x2b4a, 0x2e59, 0x2eb0, 0x2f0e, 0x2f1f, 0x2b4a, 0x2b4a,
+       0x2b4a, 0x38f1, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a,
+       0x2b4a, 0x2b4a, 0x2b96, 0x2b9a, 0x2f36, 0x2b4a, 0x2f43, 0x397d,
+       0x39da, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a,
+       0x2b4a, 0x2b4a, 0x2f90, 0x30c5, 0x30e1, 0x30ed, 0x3150, 0x31a9,
+       0x31b4, 0x31f3, 0x3202, 0x3211, 0x3214, 0x2f47, 0x3238, 0x3284,
+       0x3291, 0x33a2, 0x34cd, 0x34f7, 0x3604, 0x3614, 0x3621, 0x365b,
+       0x372a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x3792, 0x37ae, 0x3828,
+       0x38e2, 0x713c, 0x0078, 0x2b2c, 0x2021, 0x4000, 0x1078, 0x3553,
+       0x127e, 0x2091, 0x8000, 0x0068, 0x2b39, 0x7818, 0xd084, 0x0040,
+       0x2b3c, 0x127f, 0x0078, 0x2b30, 0x7c22, 0x7926, 0x7a2a, 0x7b2e,
+       0x781b, 0x0001, 0x2091, 0x4080, 0x7007, 0x0001, 0x2091, 0x5000,
+       0x127f, 0x007c, 0x2021, 0x4001, 0x0078, 0x2b2e, 0x2021, 0x4002,
+       0x0078, 0x2b2e, 0x2021, 0x4003, 0x0078, 0x2b2e, 0x2021, 0x4005,
+       0x0078, 0x2b2e, 0x2021, 0x4006, 0x0078, 0x2b2e, 0xa02e, 0x2520,
+       0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0078, 0x3562, 0x7823, 0x0004,
+       0x7824, 0x007a, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930,
+       0x0078, 0x3566, 0x7924, 0x7828, 0x2114, 0x200a, 0x0078, 0x2b2c,
+       0x7924, 0x2114, 0x0078, 0x2b2c, 0x2099, 0x0009, 0x20a1, 0x0009,
+       0x20a9, 0x0007, 0x53a3, 0x7924, 0x7a28, 0x7b2c, 0x0078, 0x2b2c,
+       0x7824, 0x2060, 0x0078, 0x2ba0, 0x2009, 0x0001, 0x2011, 0x0013,
+       0x2019, 0x0010, 0x783b, 0x0017, 0x0078, 0x2b2c, 0x7d38, 0x7c3c,
+       0x0078, 0x2b60, 0x7d38, 0x7c3c, 0x0078, 0x2b6c, 0x2061, 0x1000,
+       0x610c, 0xa006, 0x2c14, 0xa200, 0x8c60, 0x8109, 0x00c0, 0x2ba2,
+       0x2010, 0xa005, 0x0040, 0x2b2c, 0x0078, 0x2b52, 0x2069, 0xa351,
+       0x7824, 0x7930, 0xa11a, 0x00c8, 0x2b5a, 0x8019, 0x0040, 0x2b5a,
+       0x684a, 0x6942, 0x782c, 0x6852, 0x7828, 0x6856, 0xa006, 0x685a,
+       0x685e, 0x1078, 0x4dbd, 0x0078, 0x2b2c, 0x2069, 0xa351, 0x7824,
+       0x7934, 0xa11a, 0x00c8, 0x2b5a, 0x8019, 0x0040, 0x2b5a, 0x684e,
+       0x6946, 0x782c, 0x6862, 0x7828, 0x6866, 0xa006, 0x686a, 0x686e,
+       0x1078, 0x494d, 0x0078, 0x2b2c, 0xa02e, 0x2520, 0x81ff, 0x00c0,
+       0x2b56, 0x7924, 0x7b28, 0x7a2c, 0x20a9, 0x0005, 0x20a1, 0xa388,
+       0x41a1, 0x1078, 0x3518, 0x0040, 0x2b56, 0x2009, 0x0020, 0x1078,
+       0x3562, 0x701b, 0x2bf4, 0x007c, 0x6834, 0x2008, 0xa084, 0x00ff,
+       0xa096, 0x0011, 0x0040, 0x2c00, 0xa096, 0x0019, 0x00c0, 0x2b56,
+       0x810f, 0xa18c, 0x00ff, 0x0040, 0x2b56, 0x710e, 0x700c, 0x8001,
+       0x0040, 0x2c31, 0x700e, 0x1078, 0x3518, 0x0040, 0x2b56, 0x2009,
+       0x0020, 0x2061, 0xa3d1, 0x6224, 0x6328, 0x642c, 0x6530, 0xa290,
+       0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x1078,
+       0x3562, 0x701b, 0x2c24, 0x007c, 0x6834, 0xa084, 0x00ff, 0xa096,
+       0x0002, 0x0040, 0x2c2f, 0xa096, 0x000a, 0x00c0, 0x2b56, 0x0078,
+       0x2c06, 0x7010, 0x2068, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x436e,
+       0x00c0, 0x2c3f, 0x7007, 0x0003, 0x701b, 0x2c41, 0x007c, 0x1078,
+       0x4a60, 0x127e, 0x2091, 0x8000, 0x20a9, 0x0005, 0x2099, 0xa388,
+       0x530a, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9,
+       0x0000, 0xad80, 0x000d, 0x2009, 0x0020, 0x127f, 0x0078, 0x3566,
+       0x61a0, 0x7824, 0x60a2, 0x0078, 0x2b2c, 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, 0x2b56, 0x7924, 0x810f, 0xa18c,
+       0x00ff, 0x1078, 0x4501, 0x00c0, 0x2b5a, 0x7e38, 0xa684, 0x3fff,
+       0xa082, 0x4000, 0x0048, 0x2c9e, 0x0078, 0x2b5a, 0x7c28, 0x7d2c,
+       0x1078, 0x46d6, 0xd28c, 0x00c0, 0x2ca9, 0x1078, 0x466a, 0x0078,
+       0x2cab, 0x1078, 0x46a4, 0x00c0, 0x2cd5, 0x2061, 0xaa00, 0x127e,
+       0x2091, 0x8000, 0x6000, 0xa086, 0x0000, 0x0040, 0x2cc3, 0x6010,
+       0xa06d, 0x0040, 0x2cc3, 0x683c, 0xa406, 0x00c0, 0x2cc3, 0x6840,
+       0xa506, 0x0040, 0x2cce, 0x127f, 0xace0, 0x0010, 0x2001, 0xa315,
+       0x2004, 0xac02, 0x00c8, 0x2b56, 0x0078, 0x2caf, 0x1078, 0x8758,
+       0x127f, 0x0040, 0x2b56, 0x0078, 0x2b2c, 0xa00e, 0x2001, 0x0005,
+       0x1078, 0x4a60, 0x127e, 0x2091, 0x8000, 0x1078, 0x8cc0, 0x1078,
+       0x4982, 0x127f, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x1078,
+       0x3530, 0x0040, 0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x1078,
+       0x46e4, 0x0040, 0x2b56, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56,
+       0x1078, 0x3542, 0x0040, 0x2b5a, 0x1078, 0x475f, 0x0040, 0x2b56,
+       0x2019, 0x0005, 0x1078, 0x4705, 0x0040, 0x2b56, 0x7828, 0xa08a,
+       0x1000, 0x00c8, 0x2b5a, 0x8003, 0x800b, 0x810b, 0xa108, 0x1078,
+       0x58e1, 0x0078, 0x2b2c, 0x127e, 0x2091, 0x8000, 0x81ff, 0x0040,
+       0x2d1d, 0x2009, 0x0001, 0x0078, 0x2d4e, 0x2029, 0x00ff, 0x644c,
+       0x2400, 0xa506, 0x0040, 0x2d48, 0x2508, 0x1078, 0x4501, 0x00c0,
+       0x2d48, 0x1078, 0x475f, 0x00c0, 0x2d33, 0x2009, 0x0002, 0x62a8,
+       0x2518, 0x0078, 0x2d4e, 0x2019, 0x0004, 0x1078, 0x4705, 0x00c0,
+       0x2d3d, 0x2009, 0x0006, 0x0078, 0x2d4e, 0x7824, 0xa08a, 0x1000,
+       0x00c8, 0x2d51, 0x8003, 0x800b, 0x810b, 0xa108, 0x1078, 0x58e1,
+       0x8529, 0x00c8, 0x2d20, 0x127f, 0x0078, 0x2b2c, 0x127f, 0x0078,
+       0x2b56, 0x127f, 0x0078, 0x2b5a, 0x1078, 0x3530, 0x0040, 0x2b5a,
+       0x1078, 0x461b, 0x1078, 0x46d6, 0x0078, 0x2b2c, 0x81ff, 0x00c0,
+       0x2b56, 0x1078, 0x3530, 0x0040, 0x2b5a, 0x1078, 0x460a, 0x1078,
+       0x46d6, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530,
+       0x0040, 0x2b5a, 0x1078, 0x46a7, 0x0040, 0x2b56, 0x1078, 0x43c1,
+       0x1078, 0x4663, 0x1078, 0x46d6, 0x0078, 0x2b2c, 0x1078, 0x3530,
+       0x0040, 0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x62a0, 0x2019,
+       0x0005, 0x0c7e, 0x1078, 0x471b, 0x0c7f, 0x1078, 0x5d53, 0x077e,
+       0x2039, 0x0000, 0x1078, 0x5c78, 0x2009, 0x0000, 0x1078, 0x9c38,
+       0x077f, 0x1078, 0x46d6, 0x0078, 0x2b2c, 0x1078, 0x3530, 0x0040,
+       0x2b5a, 0x1078, 0x46d6, 0x2208, 0x0078, 0x2b2c, 0x157e, 0x0d7e,
+       0x0e7e, 0x2069, 0xa413, 0x6810, 0x6914, 0xa10a, 0x00c8, 0x2db2,
+       0x2009, 0x0000, 0x6816, 0x2011, 0x0000, 0x2019, 0x0000, 0x20a9,
+       0x00ff, 0x2069, 0xa434, 0x2d04, 0xa075, 0x0040, 0x2dc7, 0x704c,
+       0x1078, 0x2dd1, 0xa210, 0x7080, 0x1078, 0x2dd1, 0xa318, 0x8d68,
+       0x00f0, 0x2dbb, 0x2300, 0xa218, 0x0e7f, 0x0d7f, 0x157f, 0x0078,
+       0x2b2c, 0x0f7e, 0x017e, 0xa07d, 0x0040, 0x2de0, 0x2001, 0x0000,
+       0x8000, 0x2f0c, 0x81ff, 0x0040, 0x2de0, 0x2178, 0x0078, 0x2dd8,
+       0x017f, 0x0f7f, 0x007c, 0x2069, 0xa413, 0x6910, 0x62a4, 0x0078,
+       0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x614c, 0xa190, 0x293f, 0x2214,
+       0xa294, 0x00ff, 0x606c, 0xa084, 0xff00, 0xa215, 0x6368, 0x67c8,
+       0xd79c, 0x0040, 0x2dff, 0x2031, 0x0001, 0x0078, 0x2e01, 0x2031,
+       0x0000, 0x7e3a, 0x7f3e, 0x0078, 0x2b2c, 0x613c, 0x6240, 0x2019,
+       0xa5a0, 0x231c, 0x0078, 0x2b2c, 0x127e, 0x2091, 0x8000, 0x6134,
+       0xa006, 0x2010, 0x2018, 0x127f, 0x0078, 0x2b2c, 0x1078, 0x3542,
+       0x0040, 0x2b5a, 0x6244, 0x6338, 0x0078, 0x2b2c, 0x613c, 0x6240,
+       0x7824, 0x603e, 0x7b28, 0x6342, 0x2069, 0xa351, 0x831f, 0xa305,
+       0x6816, 0x782c, 0x2069, 0xa5a0, 0x2d1c, 0x206a, 0x0078, 0x2b2c,
+       0x017e, 0x127e, 0x2091, 0x8000, 0x7824, 0x6036, 0xd094, 0x0040,
+       0x2e43, 0x7828, 0xa085, 0x0001, 0x2009, 0xa5a9, 0x200a, 0x2001,
+       0xffff, 0x1078, 0x5975, 0x127f, 0x017f, 0x0078, 0x2b2c, 0x1078,
+       0x3542, 0x0040, 0x2b5a, 0x7828, 0xa00d, 0x0040, 0x2b5a, 0x782c,
+       0xa005, 0x0040, 0x2b5a, 0x6244, 0x6146, 0x6338, 0x603a, 0x0078,
+       0x2b2c, 0x2001, 0xa300, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2b56,
+       0x0c7e, 0x2061, 0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196,
+       0x00ff, 0x00c0, 0x2e70, 0x6030, 0xa085, 0xff00, 0x0078, 0x2e7f,
+       0xa182, 0x007f, 0x00c8, 0x2ea9, 0xa188, 0x293f, 0x210c, 0xa18c,
+       0x00ff, 0x6030, 0xa116, 0x0040, 0x2ea9, 0x810f, 0xa105, 0x127e,
+       0x2091, 0x8000, 0x007e, 0x1078, 0x74d7, 0x007f, 0x0040, 0x2ea5,
+       0x601a, 0x600b, 0xbc09, 0x601f, 0x0001, 0x1078, 0x3518, 0x0040,
+       0x2eac, 0x6837, 0x0000, 0x7007, 0x0003, 0x6833, 0x0000, 0x6838,
+       0xc0fd, 0x683a, 0x701b, 0x2f07, 0x2d00, 0x6012, 0x2009, 0x0032,
+       0x1078, 0x756c, 0x127f, 0x0c7f, 0x007c, 0x127f, 0x0c7f, 0x0078,
+       0x2b56, 0x0c7f, 0x0078, 0x2b5a, 0x1078, 0x753d, 0x0078, 0x2ea5,
+       0x2001, 0xa300, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2b56, 0x0c7e,
+       0x2061, 0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196, 0x00ff,
+       0x00c0, 0x2ec7, 0x6030, 0xa085, 0xff00, 0x0078, 0x2ed6, 0xa182,
+       0x007f, 0x00c8, 0x2f00, 0xa188, 0x293f, 0x210c, 0xa18c, 0x00ff,
+       0x6030, 0xa116, 0x0040, 0x2f00, 0x810f, 0xa105, 0x127e, 0x2091,
+       0x8000, 0x007e, 0x1078, 0x74d7, 0x007f, 0x0040, 0x2efc, 0x601a,
+       0x600b, 0xbc05, 0x601f, 0x0001, 0x1078, 0x3518, 0x0040, 0x2f03,
+       0x6837, 0x0000, 0x7007, 0x0003, 0x6833, 0x0000, 0x6838, 0xc0fd,
+       0x683a, 0x701b, 0x2f07, 0x2d00, 0x6012, 0x2009, 0x0032, 0x1078,
+       0x756c, 0x127f, 0x0c7f, 0x007c, 0x127f, 0x0c7f, 0x0078, 0x2b56,
+       0x0c7f, 0x0078, 0x2b5a, 0x1078, 0x753d, 0x0078, 0x2efc, 0x6830,
+       0xa086, 0x0100, 0x0040, 0x2b56, 0x0078, 0x2b2c, 0x2061, 0xa62d,
+       0x127e, 0x2091, 0x8000, 0x6000, 0xd084, 0x0040, 0x2f1c, 0x6104,
+       0x6208, 0x127f, 0x0078, 0x2b2c, 0x127f, 0x0078, 0x2b5a, 0x81ff,
+       0x00c0, 0x2b56, 0x127e, 0x2091, 0x8000, 0x6244, 0x6060, 0xa202,
+       0x0048, 0x2f33, 0xa085, 0x0001, 0x1078, 0x2500, 0x1078, 0x3bf5,
+       0x127f, 0x0078, 0x2b2c, 0x127f, 0x0078, 0x2b5a, 0x127e, 0x2091,
+       0x8000, 0x20a9, 0x0011, 0x2001, 0xa340, 0x20a0, 0xa006, 0x40a4,
+       0x127f, 0x0078, 0x2b2c, 0x7d38, 0x7c3c, 0x0078, 0x2bde, 0x7824,
+       0xa09c, 0x00ff, 0xa39a, 0x0003, 0x00c8, 0x2b56, 0x624c, 0xa084,
+       0xff00, 0x8007, 0xa206, 0x00c0, 0x2f5f, 0x2001, 0xa340, 0x2009,
+       0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x3566, 0x81ff,
+       0x00c0, 0x2b56, 0x1078, 0x3542, 0x0040, 0x2b5a, 0x6004, 0xa084,
+       0x00ff, 0xa086, 0x0006, 0x00c0, 0x2b56, 0x0c7e, 0x1078, 0x3518,
+       0x0c7f, 0x0040, 0x2b56, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a,
+       0x1078, 0x8b85, 0x0040, 0x2b56, 0x7007, 0x0003, 0x701b, 0x2f81,
+       0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x2b56, 0xad80, 0x000e,
+       0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x3566,
+       0x1078, 0x3518, 0x0040, 0x2b56, 0x1078, 0x421a, 0x2009, 0x001c,
+       0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3562, 0x701b, 0x2fa1,
+       0x007c, 0xade8, 0x000d, 0x6800, 0xa005, 0x0040, 0x2b5a, 0x6804,
+       0xd0ac, 0x0040, 0x2fae, 0xd0a4, 0x0040, 0x2b5a, 0xd094, 0x0040,
+       0x2fb9, 0x0c7e, 0x2061, 0x0100, 0x6104, 0xa18c, 0xffdf, 0x6106,
+       0x0c7f, 0xd08c, 0x0040, 0x2fc4, 0x0c7e, 0x2061, 0x0100, 0x6104,
+       0xa18d, 0x0010, 0x6106, 0x0c7f, 0x2009, 0x0100, 0x210c, 0xa18a,
+       0x0002, 0x0048, 0x2fd9, 0xd084, 0x0040, 0x2fd9, 0x6a28, 0xa28a,
+       0x007f, 0x00c8, 0x2b5a, 0xa288, 0x293f, 0x210c, 0xa18c, 0x00ff,
+       0x6152, 0xd0dc, 0x0040, 0x2fe2, 0x6828, 0xa08a, 0x007f, 0x00c8,
+       0x2b5a, 0x604e, 0x6808, 0xa08a, 0x0100, 0x0048, 0x2b5a, 0xa08a,
+       0x0841, 0x00c8, 0x2b5a, 0xa084, 0x0007, 0x00c0, 0x2b5a, 0x680c,
+       0xa005, 0x0040, 0x2b5a, 0x6810, 0xa005, 0x0040, 0x2b5a, 0x6848,
+       0x6940, 0xa10a, 0x00c8, 0x2b5a, 0x8001, 0x0040, 0x2b5a, 0x684c,
+       0x6944, 0xa10a, 0x00c8, 0x2b5a, 0x8001, 0x0040, 0x2b5a, 0x6804,
+       0xd0fc, 0x0040, 0x3038, 0x1078, 0x3518, 0x0040, 0x2b56, 0x2009,
+       0x0014, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0xa290, 0x0038, 0xa399,
+       0x0000, 0x1078, 0x3562, 0x701b, 0x301e, 0x007c, 0xade8, 0x000d,
+       0x20a9, 0x0014, 0x2d98, 0x2069, 0xa36d, 0x2da0, 0x53a3, 0x7010,
+       0xa0e8, 0x000d, 0x2001, 0xa371, 0x200c, 0xd1e4, 0x0040, 0x3038,
+       0x0c7e, 0x2061, 0x0100, 0x6004, 0xa085, 0x0b00, 0x6006, 0x0c7f,
+       0x20a9, 0x001c, 0x2d98, 0x2069, 0xa351, 0x2da0, 0x53a3, 0x6814,
+       0xa08c, 0x00ff, 0x613e, 0x8007, 0xa084, 0x00ff, 0x6042, 0x1078,
+       0x4dbd, 0x1078, 0x48dd, 0x1078, 0x494d, 0x6000, 0xa086, 0x0000,
+       0x00c0, 0x30c3, 0x6808, 0x602a, 0x1078, 0x218b, 0x6818, 0x691c,
+       0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, 0x611a,
+       0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0040, 0x3070, 0x6830, 0x6934,
+       0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0078, 0x3072,
+       0xa084, 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x1078, 0x59a8,
+       0x6904, 0xd1fc, 0x0040, 0x30a5, 0x0c7e, 0x2009, 0x0000, 0x20a9,
+       0x0001, 0x6b70, 0xd384, 0x0040, 0x30a2, 0x0078, 0x308c, 0x839d,
+       0x00c8, 0x30a2, 0x3508, 0x8109, 0x1078, 0x5364, 0x6878, 0x6016,
+       0x6874, 0x2008, 0xa084, 0xff00, 0x8007, 0x600a, 0xa184, 0x00ff,
+       0x6006, 0x8108, 0x00c0, 0x30a0, 0x6003, 0x0003, 0x0078, 0x30a2,
+       0x6003, 0x0001, 0x00f0, 0x3087, 0x0c7f, 0x0c7e, 0x2061, 0x0100,
+       0x602f, 0x0040, 0x602f, 0x0000, 0x0c7f, 0x1078, 0x3784, 0x0040,
+       0x30b3, 0x1078, 0x2500, 0x60bc, 0xa005, 0x0040, 0x30bf, 0x6003,
+       0x0001, 0x2091, 0x301d, 0x1078, 0x4171, 0x0078, 0x30c3, 0x6003,
+       0x0004, 0x2091, 0x301d, 0x0078, 0x2b2c, 0x6000, 0xa086, 0x0000,
+       0x0040, 0x2b56, 0x2069, 0xa351, 0x7830, 0x6842, 0x7834, 0x6846,
+       0x6804, 0xd0fc, 0x0040, 0x30d8, 0x2009, 0x0030, 0x0078, 0x30da,
+       0x2009, 0x001c, 0x2d00, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078,
+       0x3566, 0xa006, 0x1078, 0x2500, 0x81ff, 0x00c0, 0x2b56, 0x1078,
+       0x421a, 0x1078, 0x4171, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56,
+       0x6180, 0x81ff, 0x0040, 0x3107, 0x703f, 0x0000, 0x2001, 0xa9c0,
+       0x2009, 0x0040, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x127e, 0x2091,
+       0x8000, 0x1078, 0x3566, 0x701b, 0x2b29, 0x127f, 0x007c, 0x703f,
+       0x0001, 0x0d7e, 0x2069, 0xa9c0, 0x20a9, 0x0040, 0x20a1, 0xa9c0,
+       0x2019, 0xffff, 0x43a4, 0x654c, 0xa588, 0x293f, 0x210c, 0xa18c,
+       0x00ff, 0x216a, 0xa00e, 0x2011, 0x0002, 0x2100, 0xa506, 0x0040,
+       0x3139, 0x1078, 0x4501, 0x00c0, 0x3139, 0x6014, 0x821c, 0x0048,
+       0x3131, 0xa398, 0xa9c0, 0xa085, 0xff00, 0x8007, 0x201a, 0x0078,
+       0x3138, 0xa398, 0xa9c0, 0x2324, 0xa4a4, 0xff00, 0xa405, 0x201a,
+       0x8210, 0x8108, 0xa182, 0x0080, 0x00c8, 0x3140, 0x0078, 0x311d,
+       0x8201, 0x8007, 0x2d0c, 0xa105, 0x206a, 0x0d7f, 0x20a9, 0x0040,
+       0x20a1, 0xa9c0, 0x2099, 0xa9c0, 0x1078, 0x41be, 0x0078, 0x30f6,
+       0x1078, 0x3542, 0x0040, 0x2b5a, 0x0c7e, 0x1078, 0x3518, 0x0c7f,
+       0x00c0, 0x315e, 0x2009, 0x0002, 0x0078, 0x2b56, 0x2001, 0xa352,
+       0x2004, 0xd0b4, 0x0040, 0x3185, 0x6000, 0xd08c, 0x00c0, 0x3185,
+       0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x3185, 0x6837,
+       0x0000, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x8bd9, 0x00c0, 0x317c,
+       0x2009, 0x0003, 0x0078, 0x2b56, 0x7007, 0x0003, 0x701b, 0x3181,
+       0x007c, 0x1078, 0x3542, 0x0040, 0x2b5a, 0x20a9, 0x002b, 0x2c98,
+       0xade8, 0x0002, 0x2da0, 0x53a3, 0x20a9, 0x0004, 0xac80, 0x0006,
+       0x2098, 0xad80, 0x0006, 0x20a0, 0x1078, 0x41be, 0x20a9, 0x0004,
+       0xac80, 0x000a, 0x2098, 0xad80, 0x000a, 0x20a0, 0x1078, 0x41be,
+       0x2d00, 0x2009, 0x002b, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078,
+       0x3566, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530, 0x0040, 0x2b5a,
+       0x1078, 0x46ef, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x7828,
+       0xa08a, 0x1000, 0x00c8, 0x2b5a, 0x1078, 0x3542, 0x0040, 0x2b5a,
+       0x1078, 0x475f, 0x0040, 0x2b56, 0x2019, 0x0004, 0x1078, 0x4705,
+       0x7924, 0x810f, 0x7a28, 0x1078, 0x31cf, 0x0078, 0x2b2c, 0xa186,
+       0x00ff, 0x0040, 0x31d7, 0x1078, 0x31e7, 0x0078, 0x31e6, 0x2029,
+       0x007e, 0x2061, 0xa300, 0x644c, 0x2400, 0xa506, 0x0040, 0x31e3,
+       0x2508, 0x1078, 0x31e7, 0x8529, 0x00c8, 0x31dc, 0x007c, 0x1078,
+       0x4501, 0x00c0, 0x31f2, 0x2200, 0x8003, 0x800b, 0x810b, 0xa108,
+       0x1078, 0x58e1, 0x007c, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530,
+       0x0040, 0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x1078, 0x46fa,
+       0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530, 0x0040,
+       0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x1078, 0x46e4, 0x0078,
+       0x2b2c, 0x6100, 0x0078, 0x2b2c, 0x1078, 0x3542, 0x0040, 0x2b5a,
+       0x2001, 0xa300, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2b56, 0x0d7e,
+       0xace8, 0x000a, 0x7924, 0xd184, 0x0040, 0x3228, 0xace8, 0x0006,
+       0x680c, 0x8007, 0x783e, 0x6808, 0x8007, 0x783a, 0x6b04, 0x831f,
+       0x6a00, 0x8217, 0x0d7f, 0x6100, 0xa18c, 0x0200, 0x0078, 0x2b2c,
+       0xa006, 0x1078, 0x2500, 0x7824, 0xa084, 0x00ff, 0xa086, 0x00ff,
+       0x0040, 0x3245, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x421a, 0x7828,
+       0xa08a, 0x1000, 0x00c8, 0x2b5a, 0x7924, 0xa18c, 0xff00, 0x810f,
+       0xa186, 0x00ff, 0x0040, 0x325b, 0xa182, 0x007f, 0x00c8, 0x2b5a,
+       0x2100, 0x1078, 0x24fa, 0x027e, 0x0c7e, 0x127e, 0x2091, 0x8000,
+       0x2061, 0xa5be, 0x601b, 0x0000, 0x601f, 0x0000, 0x2061, 0x0100,
+       0x6030, 0xa084, 0x00ff, 0x810f, 0xa105, 0x604a, 0x6043, 0x0090,
+       0x6043, 0x0010, 0x2009, 0x002d, 0x2011, 0x4196, 0x1078, 0x596c,
+       0x7924, 0xa18c, 0xff00, 0x810f, 0x7a28, 0x1078, 0x31cf, 0x127f,
+       0x0c7f, 0x027f, 0x0078, 0x2b2c, 0x7924, 0xa18c, 0xff00, 0x810f,
+       0x0c7e, 0x1078, 0x4499, 0x2c08, 0x0c7f, 0x00c0, 0x2b5a, 0x0078,
+       0x2b2c, 0x81ff, 0x0040, 0x3298, 0x2009, 0x0001, 0x0078, 0x2b56,
+       0x60c8, 0xd09c, 0x00c0, 0x32a0, 0x2009, 0x0005, 0x0078, 0x2b56,
+       0x1078, 0x3518, 0x00c0, 0x32a8, 0x2009, 0x0002, 0x0078, 0x2b56,
+       0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3562, 0x701b,
+       0x32b2, 0x007c, 0x2009, 0x0080, 0x1078, 0x4501, 0x00c0, 0x32bf,
+       0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x0040, 0x32c3, 0x2021,
+       0x400a, 0x0078, 0x2b2e, 0x0d7e, 0xade8, 0x000d, 0x6900, 0x6a08,
+       0x6b0c, 0x6c10, 0x6d14, 0x6e18, 0x6820, 0xa0be, 0x0100, 0x0040,
+       0x3336, 0xa0be, 0x0112, 0x0040, 0x3336, 0xa0be, 0x0113, 0x0040,
+       0x3336, 0xa0be, 0x0114, 0x0040, 0x3336, 0xa0be, 0x0117, 0x0040,
+       0x3336, 0xa0be, 0x011a, 0x0040, 0x3336, 0xa0be, 0x0121, 0x0040,
+       0x332c, 0xa0be, 0x0131, 0x0040, 0x332c, 0xa0be, 0x0171, 0x0040,
+       0x3336, 0xa0be, 0x0173, 0x0040, 0x3336, 0xa0be, 0x01a1, 0x00c0,
+       0x32fe, 0x6830, 0x8007, 0x6832, 0x0078, 0x333c, 0xa0be, 0x0212,
+       0x0040, 0x3332, 0xa0be, 0x0213, 0x0040, 0x3332, 0xa0be, 0x0214,
+       0x0040, 0x3324, 0xa0be, 0x0217, 0x0040, 0x331e, 0xa0be, 0x021a,
+       0x00c0, 0x3317, 0x6838, 0x8007, 0x683a, 0x0078, 0x3336, 0xa0be,
+       0x0300, 0x0040, 0x3336, 0x0d7f, 0x0078, 0x2b5a, 0xad80, 0x0010,
+       0x20a9, 0x0007, 0x1078, 0x337e, 0xad80, 0x000e, 0x20a9, 0x0001,
+       0x1078, 0x337e, 0x0078, 0x3336, 0xad80, 0x000c, 0x1078, 0x338c,
+       0x0078, 0x333c, 0xad80, 0x000e, 0x1078, 0x338c, 0xad80, 0x000c,
+       0x20a9, 0x0001, 0x1078, 0x337e, 0x0c7e, 0x1078, 0x3518, 0x0040,
+       0x336f, 0x6838, 0xc0fd, 0x683a, 0x6837, 0x0119, 0x6853, 0x0000,
+       0x684f, 0x0020, 0x685b, 0x0001, 0x810b, 0x697e, 0x6883, 0x0000,
+       0x6a86, 0x6b8a, 0x6c8e, 0x6d92, 0x6996, 0x689b, 0x0000, 0x0c7f,
+       0x0d7f, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000,
+       0x6804, 0x2068, 0x1078, 0x8ba1, 0x00c0, 0x336a, 0x2009, 0x0003,
+       0x0078, 0x2b56, 0x7007, 0x0003, 0x701b, 0x3375, 0x007c, 0x0c7f,
+       0x0d7f, 0x2009, 0x0002, 0x0078, 0x2b56, 0x6820, 0xa086, 0x8001,
+       0x00c0, 0x2b2c, 0x2009, 0x0004, 0x0078, 0x2b56, 0x017e, 0x2008,
+       0x2044, 0x8000, 0x204c, 0x8000, 0x290a, 0x8108, 0x280a, 0x8108,
+       0x00f0, 0x3380, 0x017f, 0x007c, 0x017e, 0x0a7e, 0x0b7e, 0x2008,
+       0x2044, 0x8000, 0x204c, 0x8000, 0x2054, 0x8000, 0x205c, 0x2b0a,
+       0x8108, 0x2a0a, 0x8108, 0x290a, 0x8108, 0x280a, 0x0b7f, 0x0a7f,
+       0x017f, 0x007c, 0x81ff, 0x0040, 0x33a9, 0x2009, 0x0001, 0x0078,
+       0x2b56, 0x7924, 0x2140, 0xa18c, 0xff00, 0x810f, 0xa182, 0x0080,
+       0x0048, 0x2b5a, 0xa182, 0x00ff, 0x00c8, 0x2b5a, 0x7a2c, 0x7b28,
+       0x6068, 0xa306, 0x00c0, 0x33c4, 0x606c, 0xa24e, 0x0040, 0x2b5a,
+       0xa9cc, 0xff00, 0x0040, 0x2b5a, 0x0c7e, 0x1078, 0x346d, 0x2c68,
+       0x0c7f, 0x0040, 0x33fc, 0xa0c6, 0x4000, 0x00c0, 0x33e2, 0x0c7e,
+       0x007e, 0x2d60, 0x2009, 0x0000, 0x1078, 0x47cb, 0x00c0, 0x33d9,
+       0xc185, 0x6000, 0xd0bc, 0x0040, 0x33de, 0xc18d, 0x007f, 0x0c7f,
+       0x0078, 0x33f9, 0xa0c6, 0x4007, 0x00c0, 0x33e9, 0x2408, 0x0078,
+       0x33f9, 0xa0c6, 0x4008, 0x00c0, 0x33f1, 0x2708, 0x2610, 0x0078,
+       0x33f9, 0xa0c6, 0x4009, 0x00c0, 0x33f7, 0x0078, 0x33f9, 0x2001,
+       0x4006, 0x2020, 0x0078, 0x2b2e, 0x2d00, 0x7022, 0x017e, 0x0b7e,
+       0x0c7e, 0x0e7e, 0x2c70, 0x1078, 0x74d7, 0x0040, 0x3442, 0x2d00,
+       0x601a, 0x2001, 0xa356, 0x2004, 0xa084, 0x00ff, 0x6842, 0x2e58,
+       0x0e7f, 0x0e7e, 0x0c7e, 0x1078, 0x3518, 0x0c7f, 0x2b70, 0x00c0,
+       0x3423, 0x1078, 0x753d, 0x0e7f, 0x0c7f, 0x0b7f, 0x017f, 0x2009,
+       0x0002, 0x0078, 0x2b56, 0x6837, 0x0000, 0x2d00, 0x6012, 0x6833,
+       0x0000, 0x6838, 0xc0fd, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078,
+       0x2813, 0x127f, 0x601f, 0x0001, 0x2001, 0x0000, 0x1078, 0x442b,
+       0x2001, 0x0002, 0x1078, 0x443f, 0x2009, 0x0002, 0x1078, 0x756c,
+       0xa085, 0x0001, 0x0e7f, 0x0c7f, 0x0b7f, 0x017f, 0x00c0, 0x344c,
+       0x2009, 0x0003, 0x0078, 0x2b56, 0x7007, 0x0003, 0x701b, 0x3451,
+       0x007c, 0x6830, 0xa086, 0x0100, 0x7020, 0x2060, 0x00c0, 0x345f,
+       0x2009, 0x0004, 0x6204, 0xa294, 0x00ff, 0x0078, 0x2b56, 0x2009,
+       0x0000, 0x1078, 0x47cb, 0x00c0, 0x3466, 0xc185, 0x6000, 0xd0bc,
+       0x0040, 0x346b, 0xc18d, 0x0078, 0x2b2c, 0x0e7e, 0x0d7e, 0x2029,
+       0x0000, 0x2021, 0x0080, 0x20a9, 0x007f, 0x2071, 0xa4b4, 0x2e04,
+       0xa005, 0x00c0, 0x3482, 0x2100, 0xa406, 0x00c0, 0x34b3, 0x2428,
+       0x0078, 0x34b3, 0x2068, 0x6f10, 0x2700, 0xa306, 0x00c0, 0x34a4,
+       0x6e14, 0x2600, 0xa206, 0x00c0, 0x34a4, 0x2400, 0xa106, 0x00c0,
+       0x34a0, 0x2d60, 0xd884, 0x0040, 0x34c8, 0x6004, 0xa084, 0x00ff,
+       0xa086, 0x0006, 0x00c0, 0x34c8, 0x2001, 0x4000, 0x0078, 0x34c9,
+       0x2001, 0x4007, 0x0078, 0x34c9, 0x2400, 0xa106, 0x00c0, 0x34b3,
+       0x6e14, 0x87ff, 0x00c0, 0x34af, 0x86ff, 0x0040, 0x347f, 0x2001,
+       0x4008, 0x0078, 0x34c9, 0x8420, 0x8e70, 0x00f0, 0x3477, 0x85ff,
+       0x00c0, 0x34c2, 0x2001, 0x4009, 0x0078, 0x34c9, 0x2001, 0x0001,
+       0x0078, 0x34c9, 0x1078, 0x4499, 0x00c0, 0x34be, 0x6312, 0x6216,
+       0xa006, 0xa005, 0x0d7f, 0x0e7f, 0x007c, 0x81ff, 0x00c0, 0x2b56,
+       0x1078, 0x3518, 0x0040, 0x2b56, 0x6837, 0x0000, 0x6838, 0xc0fd,
+       0x683a, 0x7824, 0xa005, 0x0040, 0x2b5a, 0xa096, 0x00ff, 0x0040,
+       0x34e5, 0xa092, 0x0004, 0x00c8, 0x2b5a, 0x2010, 0x2d18, 0x1078,
+       0x27c2, 0x0040, 0x2b56, 0x7007, 0x0003, 0x701b, 0x34f0, 0x007c,
+       0x6830, 0xa086, 0x0100, 0x0040, 0x2b56, 0x0078, 0x2b2c, 0x7924,
+       0xa18c, 0xff00, 0x810f, 0xa182, 0x0080, 0x0048, 0x2b5a, 0xa182,
+       0x00ff, 0x00c8, 0x2b5a, 0x127e, 0x2091, 0x8000, 0x1078, 0x8a89,
+       0x00c0, 0x3515, 0xa190, 0xa434, 0x2204, 0xa065, 0x0040, 0x3515,
+       0x1078, 0x4235, 0x127f, 0x0078, 0x2b2c, 0x127f, 0x0078, 0x2b56,
+       0x1078, 0x1381, 0x0040, 0x352f, 0xa006, 0x6802, 0x7010, 0xa005,
+       0x00c0, 0x3527, 0x2d00, 0x7012, 0x7016, 0x0078, 0x352d, 0x7014,
+       0x6802, 0x2060, 0x2d00, 0x6006, 0x7016, 0xad80, 0x000d, 0x007c,
+       0x7924, 0x810f, 0xa18c, 0x00ff, 0x1078, 0x4501, 0x00c0, 0x353f,
+       0x7e28, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0048, 0x3540, 0xa066,
+       0x8cff, 0x007c, 0x7e24, 0x860f, 0xa18c, 0x00ff, 0x1078, 0x4501,
+       0x00c0, 0x3550, 0xa6b4, 0x00ff, 0xa682, 0x4000, 0x0048, 0x3551,
+       0xa066, 0x8cff, 0x007c, 0x017e, 0x7110, 0x81ff, 0x0040, 0x355e,
+       0x2168, 0x6904, 0x1078, 0x139a, 0x0078, 0x3555, 0x7112, 0x7116,
+       0x017f, 0x007c, 0x2031, 0x0001, 0x0078, 0x3568, 0x2031, 0x0000,
+       0x2061, 0xa3d1, 0x6606, 0x6112, 0x600e, 0x6226, 0x632a, 0x642e,
+       0x6532, 0x2c10, 0x1078, 0x13d1, 0x7007, 0x0002, 0x701b, 0x2b2c,
+       0x007c, 0x0f7e, 0x127e, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001,
+       0xa38f, 0x2004, 0xa005, 0x00c0, 0x3594, 0x0068, 0x3594, 0x7818,
+       0xd084, 0x00c0, 0x3594, 0x7a22, 0x7b26, 0x7c2a, 0x781b, 0x0001,
+       0x2091, 0x4080, 0x0078, 0x35b9, 0x017e, 0x0c7e, 0x0e7e, 0x2071,
+       0xa381, 0x7138, 0xa182, 0x0008, 0x0048, 0x35a2, 0x7030, 0x2060,
+       0x0078, 0x35b3, 0x7030, 0xa0e0, 0x0008, 0xac82, 0xa3d1, 0x0048,
+       0x35ab, 0x2061, 0xa391, 0x2c00, 0x7032, 0x81ff, 0x00c0, 0x35b1,
+       0x7036, 0x8108, 0x713a, 0x2262, 0x6306, 0x640a, 0x0e7f, 0x0c7f,
+       0x017f, 0x127f, 0x0f7f, 0x007c, 0x0e7e, 0x2071, 0xa381, 0x7038,
+       0xa005, 0x0040, 0x35f5, 0x127e, 0x2091, 0x8000, 0x0068, 0x35f4,
+       0x0f7e, 0x2079, 0x0000, 0x7818, 0xd084, 0x00c0, 0x35f3, 0x0c7e,
+       0x7034, 0x2060, 0x2c04, 0x7822, 0x6004, 0x7826, 0x6008, 0x782a,
+       0x781b, 0x0001, 0x2091, 0x4080, 0x7038, 0x8001, 0x703a, 0xa005,
+       0x00c0, 0x35e9, 0x7033, 0xa391, 0x7037, 0xa391, 0x0c7f, 0x0078,
+       0x35f3, 0xac80, 0x0008, 0xa0fa, 0xa3d1, 0x0048, 0x35f1, 0x2001,
+       0xa391, 0x7036, 0x0c7f, 0x0f7f, 0x127f, 0x0e7f, 0x007c, 0x027e,
+       0x2001, 0xa352, 0x2004, 0xd0c4, 0x0040, 0x3602, 0x2011, 0x8014,
+       0x1078, 0x3579, 0x027f, 0x007c, 0x81ff, 0x00c0, 0x2b56, 0x127e,
+       0x2091, 0x8000, 0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x1078,
+       0x4171, 0x127f, 0x0078, 0x2b2c, 0x7824, 0x2008, 0xa18c, 0xfffd,
+       0x00c0, 0x361f, 0x61d4, 0xa10d, 0x61d6, 0x0078, 0x2b2c, 0x0078,
+       0x2b5a, 0x81ff, 0x00c0, 0x2b56, 0x6000, 0xa086, 0x0003, 0x00c0,
+       0x2b56, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x00c0, 0x2b56, 0x1078,
+       0x3542, 0x0040, 0x2b5a, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006,
+       0x00c0, 0x363e, 0x7828, 0xa005, 0x0040, 0x2b2c, 0x0c7e, 0x1078,
+       0x3518, 0x0c7f, 0x0040, 0x2b56, 0x6837, 0x0000, 0x6833, 0x0000,
+       0x6838, 0xc0fd, 0x683a, 0x1078, 0x8c4d, 0x0040, 0x2b56, 0x7007,
+       0x0003, 0x701b, 0x3654, 0x007c, 0x6830, 0xa086, 0x0100, 0x0040,
+       0x2b56, 0x0078, 0x2b2c, 0x2001, 0xa300, 0x2004, 0xa086, 0x0003,
+       0x00c0, 0x2b56, 0x7f24, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078,
+       0x3518, 0x0040, 0x2b56, 0x2009, 0x0000, 0x2031, 0x0000, 0x7023,
+       0x0000, 0x702f, 0x0000, 0xad80, 0x0005, 0x7026, 0x20a0, 0x1078,
+       0x4501, 0x00c0, 0x36d8, 0x6004, 0xa0c4, 0x00ff, 0xa8c6, 0x0006,
+       0x0040, 0x3688, 0xa0c4, 0xff00, 0xa8c6, 0x0600, 0x00c0, 0x36d8,
+       0x2001, 0xa352, 0x2004, 0xd0ac, 0x00c0, 0x3695, 0x1078, 0x47cb,
+       0x00c0, 0x3695, 0xd79c, 0x0040, 0x36d8, 0xd794, 0x00c0, 0x369b,
+       0xd784, 0x0040, 0x36a7, 0xac80, 0x0006, 0x2098, 0x3400, 0x20a9,
+       0x0004, 0x53a3, 0x1078, 0x338c, 0xd794, 0x0040, 0x36b0, 0xac80,
+       0x000a, 0x2098, 0x3400, 0x20a9, 0x0004, 0x53a3, 0x1078, 0x338c,
+       0x21a2, 0xd794, 0x0040, 0x36d0, 0xac80, 0x0000, 0x2098, 0x94a0,
+       0x20a9, 0x0002, 0x53a3, 0xac80, 0x0003, 0x20a6, 0x94a0, 0xac80,
+       0x0004, 0x2098, 0x3400, 0x20a9, 0x0002, 0x53a3, 0x1078, 0x337e,
+       0xac80, 0x0026, 0x2098, 0x20a9, 0x0002, 0x53a3, 0x0078, 0x36d1,
+       0x94a0, 0xd794, 0x0040, 0x36d6, 0xa6b0, 0x000b, 0xa6b0, 0x0005,
+       0x8108, 0xd78c, 0x0040, 0x36e2, 0xa186, 0x0100, 0x0040, 0x36f3,
+       0x0078, 0x36e6, 0xa186, 0x007e, 0x0040, 0x36f3, 0xd794, 0x0040,
+       0x36ed, 0xa686, 0x0020, 0x0078, 0x36ef, 0xa686, 0x0028, 0x0040,
+       0x36fc, 0x0078, 0x3677, 0x86ff, 0x00c0, 0x36fa, 0x7120, 0x810b,
+       0x0078, 0x2b2c, 0x702f, 0x0001, 0x711e, 0x7020, 0xa600, 0x7022,
+       0x772a, 0x2061, 0xa3d1, 0x6007, 0x0000, 0x6612, 0x7024, 0x600e,
+       0x6226, 0x632a, 0x642e, 0x6532, 0x2c10, 0x1078, 0x13d1, 0x7007,
+       0x0002, 0x701b, 0x3714, 0x007c, 0x702c, 0xa005, 0x00c0, 0x3726,
+       0x711c, 0x7024, 0x20a0, 0x7728, 0x2031, 0x0000, 0x2061, 0xa3d1,
+       0x6224, 0x6328, 0x642c, 0x6530, 0x0078, 0x3677, 0x7120, 0x810b,
+       0x0078, 0x2b2c, 0x2029, 0x007e, 0x7924, 0x7a28, 0x7b2c, 0x7c38,
+       0xa184, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0048, 0x2b5a, 0xa502,
+       0x0048, 0x2b5a, 0xa184, 0x00ff, 0xa0e2, 0x0020, 0x0048, 0x2b5a,
+       0xa502, 0x0048, 0x2b5a, 0xa284, 0xff00, 0x8007, 0xa0e2, 0x0020,
+       0x0048, 0x2b5a, 0xa502, 0x0048, 0x2b5a, 0xa284, 0x00ff, 0xa0e2,
+       0x0020, 0x0048, 0x2b5a, 0xa502, 0x0048, 0x2b5a, 0xa384, 0xff00,
+       0x8007, 0xa0e2, 0x0020, 0x0048, 0x2b5a, 0xa502, 0x0048, 0x2b5a,
+       0xa384, 0x00ff, 0xa0e2, 0x0020, 0x0048, 0x2b5a, 0xa502, 0x0048,
+       0x2b5a, 0xa484, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0048, 0x2b5a,
+       0xa502, 0x0048, 0x2b5a, 0xa484, 0x00ff, 0xa0e2, 0x0020, 0x0048,
+       0x2b5a, 0xa502, 0x0048, 0x2b5a, 0x2061, 0xa5a3, 0x6102, 0x6206,
+       0x630a, 0x640e, 0x0078, 0x2b2c, 0x007e, 0x2001, 0xa352, 0x2004,
+       0xd0cc, 0x007f, 0x007c, 0x007e, 0x2001, 0xa371, 0x2004, 0xd0bc,
+       0x007f, 0x007c, 0x6160, 0x7a24, 0x6300, 0x82ff, 0x00c0, 0x379b,
+       0x7926, 0x0078, 0x2b2c, 0x83ff, 0x00c0, 0x2b5a, 0x2001, 0xfff0,
+       0xa200, 0x00c8, 0x2b5a, 0x2019, 0xffff, 0x6064, 0xa302, 0xa200,
+       0x0048, 0x2b5a, 0x7926, 0x6262, 0x0078, 0x2b2c, 0x2001, 0xa300,
+       0x2004, 0xa086, 0x0003, 0x00c0, 0x2b56, 0x7c28, 0x7d24, 0x7e38,
+       0x7f2c, 0x1078, 0x3518, 0x0040, 0x2b56, 0x2009, 0x0000, 0x2019,
+       0x0000, 0x7023, 0x0000, 0x702f, 0x0000, 0xad80, 0x0003, 0x7026,
+       0x20a0, 0xa1e0, 0xa434, 0x2c64, 0x8cff, 0x0040, 0x37e8, 0x6004,
+       0xa084, 0x00ff, 0xa086, 0x0006, 0x0040, 0x37dd, 0x6004, 0xa084,
+       0xff00, 0xa086, 0x0600, 0x00c0, 0x37e8, 0x6014, 0x20a2, 0x94a0,
+       0x6010, 0x8007, 0xa105, 0x8007, 0x20a2, 0x94a0, 0xa398, 0x0002,
+       0x8108, 0xa182, 0x00ff, 0x0040, 0x37f3, 0xa386, 0x002a, 0x0040,
+       0x37fc, 0x0078, 0x37c9, 0x83ff, 0x00c0, 0x37fa, 0x7120, 0x810c,
+       0x0078, 0x2b2c, 0x702f, 0x0001, 0x711e, 0x7020, 0xa300, 0x7022,
+       0x2061, 0xa3d1, 0x6007, 0x0000, 0x6312, 0x7024, 0x600e, 0x6426,
+       0x652a, 0x662e, 0x6732, 0x2c10, 0x1078, 0x13d1, 0x7007, 0x0002,
+       0x701b, 0x3813, 0x007c, 0x702c, 0xa005, 0x00c0, 0x3824, 0x711c,
+       0x7024, 0x20a0, 0x2019, 0x0000, 0x2061, 0xa3d1, 0x6424, 0x6528,
+       0x662c, 0x6730, 0x0078, 0x37c9, 0x7120, 0x810c, 0x0078, 0x2b2c,
+       0x81ff, 0x00c0, 0x2b56, 0x60c8, 0xd09c, 0x0040, 0x2b56, 0x1078,
+       0x3518, 0x0040, 0x2b56, 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
+       0x1078, 0x3562, 0x701b, 0x383d, 0x007c, 0x0d7e, 0xade8, 0x000d,
+       0x6828, 0xa0be, 0x7000, 0x0040, 0x3850, 0xa0be, 0x7100, 0x0040,
+       0x3850, 0xa0be, 0x7200, 0x0040, 0x3850, 0x0d7f, 0x0078, 0x2b5a,
+       0x6820, 0x6924, 0x1078, 0x24e3, 0x00c0, 0x387b, 0x1078, 0x4499,
+       0x00c0, 0x387b, 0x7122, 0x6612, 0x6516, 0x6e18, 0x0c7e, 0x1078,
+       0x3518, 0x0040, 0x387b, 0x1078, 0x3518, 0x0040, 0x387b, 0x0c7f,
+       0x0d7f, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000,
+       0x6804, 0x2068, 0x1078, 0x8bbd, 0x0040, 0x2b56, 0x7007, 0x0003,
+       0x701b, 0x387e, 0x007c, 0x0d7f, 0x0078, 0x2b56, 0x7120, 0x1078,
+       0x2921, 0x6820, 0xa086, 0x8001, 0x0040, 0x2b56, 0x2d00, 0x701e,
+       0x6804, 0xa080, 0x0002, 0x007e, 0x20a9, 0x002a, 0x2098, 0x20a0,
+       0x1078, 0x41be, 0x007f, 0xade8, 0x000d, 0x6a08, 0x6b0c, 0x6c10,
+       0x6d14, 0x2061, 0xa3d1, 0x6007, 0x0000, 0x6e00, 0x6f28, 0xa7c6,
+       0x7000, 0x00c0, 0x38a5, 0x0078, 0x38a9, 0xa7c6, 0x7100, 0x00c0,
+       0x38b1, 0xa6c2, 0x0004, 0x0048, 0x2b5a, 0x2009, 0x0004, 0x0078,
+       0x3566, 0xa7c6, 0x7200, 0x00c0, 0x2b5a, 0xa6c2, 0x0054, 0x0048,
+       0x2b5a, 0x600e, 0x6013, 0x002a, 0x6226, 0x632a, 0x642e, 0x6532,
+       0x2c10, 0x1078, 0x13d1, 0x7007, 0x0002, 0x701b, 0x38c8, 0x007c,
+       0x701c, 0x2068, 0x6804, 0xa080, 0x0001, 0x2004, 0xa080, 0x0002,
+       0x007e, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x1078, 0x41be, 0x007f,
+       0x2009, 0x002a, 0x2061, 0xa3d1, 0x6224, 0x6328, 0x642c, 0x6530,
+       0x0078, 0x3566, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530, 0x0040,
+       0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x1078, 0x4710, 0x0078,
+       0x2b2c, 0x7824, 0xd084, 0x0040, 0x3150, 0x1078, 0x3542, 0x0040,
+       0x2b5a, 0x0c7e, 0x1078, 0x3518, 0x0c7f, 0x00c0, 0x3903, 0x2009,
+       0x0002, 0x0078, 0x2b56, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006,
+       0x0040, 0x3910, 0xa08e, 0x0004, 0x0040, 0x3910, 0xa08e, 0x0005,
+       0x00c0, 0x3934, 0x2001, 0xa352, 0x2004, 0xd0b4, 0x0040, 0x3185,
+       0x6000, 0xd08c, 0x00c0, 0x3185, 0x6837, 0x0000, 0x6838, 0xc0fd,
+       0x683a, 0x1078, 0x8bd9, 0x00c0, 0x3929, 0x2009, 0x0003, 0x0078,
+       0x2b56, 0x7007, 0x0003, 0x701b, 0x392e, 0x007c, 0x1078, 0x3542,
+       0x0040, 0x2b5a, 0x0078, 0x3185, 0x2009, 0xa32e, 0x210c, 0x81ff,
+       0x0040, 0x393e, 0x2009, 0x0001, 0x0078, 0x2b56, 0x2001, 0xa300,
+       0x2004, 0xa086, 0x0003, 0x0040, 0x3949, 0x2009, 0x0007, 0x0078,
+       0x2b56, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x0040, 0x3953, 0x2009,
+       0x0008, 0x0078, 0x2b56, 0x609c, 0xd0a4, 0x00c0, 0x395a, 0xd0ac,
+       0x00c0, 0x3185, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd,
+       0x683a, 0x1078, 0x8c4d, 0x00c0, 0x3969, 0x2009, 0x0003, 0x0078,
+       0x2b56, 0x7007, 0x0003, 0x701b, 0x396e, 0x007c, 0x6830, 0xa086,
+       0x0100, 0x00c0, 0x3977, 0x2009, 0x0004, 0x0078, 0x2b56, 0x1078,
+       0x3542, 0x0040, 0x2b5a, 0x0078, 0x3912, 0x81ff, 0x2009, 0x0001,
+       0x00c0, 0x2b56, 0x6000, 0xa086, 0x0003, 0x2009, 0x0007, 0x00c0,
+       0x2b56, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x2009, 0x0008, 0x00c0,
+       0x2b56, 0x1078, 0x3542, 0x0040, 0x2b5a, 0x6004, 0xa084, 0x00ff,
+       0xa086, 0x0006, 0x2009, 0x0009, 0x00c0, 0x2b56, 0x0c7e, 0x1078,
+       0x3518, 0x0c7f, 0x2009, 0x0002, 0x0040, 0x2b56, 0x6837, 0x0000,
+       0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x7928, 0xa194, 0xff00,
+       0xa18c, 0x00ff, 0xa006, 0x82ff, 0x00c0, 0x39bc, 0xc0ed, 0x6952,
+       0x792c, 0x6956, 0x0078, 0x39c5, 0xa28e, 0x0100, 0x00c0, 0x2b5a,
+       0xc0e5, 0x6853, 0x0000, 0x6857, 0x0000, 0x683e, 0x1078, 0x8df6,
+       0x2009, 0x0003, 0x0040, 0x2b56, 0x7007, 0x0003, 0x701b, 0x39d1,
+       0x007c, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004, 0x0040, 0x2b56,
+       0x0078, 0x2b2c, 0x81ff, 0x2009, 0x0001, 0x00c0, 0x2b56, 0x6000,
+       0xa086, 0x0003, 0x2009, 0x0007, 0x00c0, 0x2b56, 0x1078, 0x3542,
+       0x0040, 0x2b5a, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x2009,
+       0x0009, 0x00c0, 0x2b56, 0x0c7e, 0x1078, 0x3518, 0x0c7f, 0x2009,
+       0x0002, 0x0040, 0x2b56, 0xad80, 0x000f, 0x2009, 0x0008, 0x7a2c,
+       0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3562, 0x701b, 0x3a08, 0x007c,
+       0x0d7e, 0xade8, 0x000f, 0x6800, 0xa086, 0x0500, 0x00c0, 0x3a1b,
+       0x6804, 0xa005, 0x00c0, 0x3a1b, 0x6808, 0xa084, 0xff00, 0x00c0,
+       0x3a1b, 0x0078, 0x3a1e, 0x0d7f, 0x00c0, 0x2b5a, 0x0d7f, 0x6837,
+       0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x0c7e, 0x1078,
+       0x3542, 0x00c0, 0x3a2e, 0x0c7f, 0x0078, 0x2b5a, 0x1078, 0x8e52,
+       0x2009, 0x0003, 0x0c7f, 0x0040, 0x2b56, 0x7007, 0x0003, 0x701b,
+       0x3a3a, 0x007c, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004, 0x0040,
+       0x2b56, 0x0078, 0x2b2c, 0x127e, 0x0c7e, 0x0e7e, 0x2061, 0x0100,
+       0x2071, 0xa300, 0x6044, 0xd0a4, 0x00c0, 0x3a6c, 0xd084, 0x0040,
+       0x3a55, 0x1078, 0x3bcc, 0x0078, 0x3a68, 0xd08c, 0x0040, 0x3a5c,
+       0x1078, 0x3ae3, 0x0078, 0x3a68, 0xd094, 0x0040, 0x3a63, 0x1078,
+       0x3ab7, 0x0078, 0x3a68, 0xd09c, 0x0040, 0x3a68, 0x1078, 0x3a76,
+       0x0e7f, 0x0c7f, 0x127f, 0x007c, 0x017e, 0x6128, 0xd19c, 0x00c0,
+       0x3a73, 0xc19d, 0x612a, 0x017f, 0x0078, 0x3a68, 0x624c, 0xa286,
+       0xf0f0, 0x00c0, 0x3a87, 0x6048, 0xa086, 0xf0f0, 0x0040, 0x3a87,
+       0x624a, 0x6043, 0x0090, 0x6043, 0x0010, 0x0078, 0x3ab6, 0xa294,
+       0xff00, 0xa296, 0xf700, 0x0040, 0x3a9c, 0x7134, 0xd1a4, 0x00c0,
+       0x3a9c, 0x6240, 0xa294, 0x0010, 0x0040, 0x3a9c, 0x2009, 0x00f7,
+       0x1078, 0x41de, 0x0078, 0x3ab6, 0x6043, 0x0040, 0x6043, 0x0000,
+       0x7073, 0x0000, 0x708b, 0x0001, 0x70af, 0x0000, 0x70cb, 0x0000,
+       0x2009, 0xa9c0, 0x200b, 0x0000, 0x7083, 0x0000, 0x7077, 0x000f,
+       0x2009, 0x000f, 0x2011, 0x4122, 0x1078, 0x596c, 0x007c, 0x157e,
+       0x7074, 0xa005, 0x00c0, 0x3ae1, 0x2011, 0x4122, 0x1078, 0x58d4,
+       0x6040, 0xa094, 0x0010, 0xa285, 0x0020, 0x6042, 0x20a9, 0x00c8,
+       0x6044, 0xd08c, 0x00c0, 0x3ada, 0x00f0, 0x3ac8, 0x6242, 0x7087,
+       0x0000, 0x6040, 0xa094, 0x0010, 0xa285, 0x0080, 0x6042, 0x6242,
+       0x0078, 0x3ae1, 0x6242, 0x7087, 0x0000, 0x707b, 0x0000, 0x0078,
+       0x3ae1, 0x157f, 0x007c, 0x7078, 0xa08a, 0x0003, 0x00c8, 0x3aec,
+       0x1079, 0x3aef, 0x0078, 0x3aee, 0x1078, 0x1328, 0x007c, 0x3af2,
+       0x3b41, 0x3bcb, 0x0f7e, 0x707b, 0x0001, 0x20e1, 0xa000, 0x20e1,
+       0x8700, 0x1078, 0x218b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2079,
+       0xa800, 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, 0xa80c, 0x207b, 0x1101, 0x7807, 0x0000, 0x2099,
+       0xa305, 0x20a1, 0xa80e, 0x20a9, 0x0004, 0x53a3, 0x2079, 0xa812,
+       0x207b, 0x0000, 0x7807, 0x0000, 0x2099, 0xa800, 0x20a1, 0x020b,
+       0x20a9, 0x0014, 0x53a6, 0x60c3, 0x000c, 0x600f, 0x0000, 0x1078,
+       0x4158, 0x0f7f, 0x707f, 0x0000, 0x6043, 0x0008, 0x6043, 0x0000,
+       0x007c, 0x0d7e, 0x707c, 0x707f, 0x0000, 0xa025, 0x0040, 0x3bb5,
+       0x6020, 0xd0b4, 0x00c0, 0x3bb3, 0x7188, 0x81ff, 0x0040, 0x3ba2,
+       0xa486, 0x000c, 0x00c0, 0x3bad, 0xa480, 0x0018, 0x8004, 0x20a8,
+       0x2011, 0xa880, 0x2019, 0xa800, 0x220c, 0x2304, 0xa106, 0x00c0,
+       0x3b79, 0x8210, 0x8318, 0x00f0, 0x3b5c, 0x6043, 0x0004, 0x608b,
+       0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006, 0x707b, 0x0002, 0x7087,
+       0x0002, 0x2009, 0x07d0, 0x2011, 0x4129, 0x1078, 0x596c, 0x0078,
+       0x3bb3, 0x2069, 0xa880, 0x6930, 0xa18e, 0x1101, 0x00c0, 0x3bad,
+       0x6834, 0xa005, 0x00c0, 0x3bad, 0x6900, 0xa18c, 0x00ff, 0x00c0,
+       0x3b8d, 0x6804, 0xa005, 0x0040, 0x3ba2, 0x2011, 0xa88e, 0x2019,
+       0xa305, 0x20a9, 0x0004, 0x220c, 0x2304, 0xa102, 0x0048, 0x3ba0,
+       0x00c0, 0x3bad, 0x8210, 0x8318, 0x00f0, 0x3b93, 0x0078, 0x3bad,
+       0x708b, 0x0000, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xa880,
+       0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x6043, 0x0008, 0x6043,
+       0x0000, 0x0078, 0x3bb5, 0x0d7f, 0x007c, 0x6020, 0xd0b4, 0x00c0,
+       0x3bb3, 0x60c3, 0x000c, 0x2011, 0xa5b5, 0x2013, 0x0000, 0x707f,
+       0x0000, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x1078,
+       0x6c38, 0x0078, 0x3bb3, 0x007c, 0x7084, 0xa08a, 0x001d, 0x00c8,
+       0x3bd5, 0x1079, 0x3bd8, 0x0078, 0x3bd7, 0x1078, 0x1328, 0x007c,
+       0x3c02, 0x3c11, 0x3c40, 0x3c59, 0x3c85, 0x3cb1, 0x3cdd, 0x3d13,
+       0x3d3f, 0x3d67, 0x3daa, 0x3dd4, 0x3df6, 0x3e0c, 0x3e32, 0x3e45,
+       0x3e4e, 0x3e7e, 0x3eaa, 0x3ed6, 0x3f02, 0x3f38, 0x3f7d, 0x3fac,
+       0x3fce, 0x4010, 0x4036, 0x404f, 0x4050, 0x0c7e, 0x2061, 0xa300,
+       0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0xa084, 0xfff9, 0x6006,
+       0x0c7f, 0x007c, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0002,
+       0x7087, 0x0001, 0x2009, 0x07d0, 0x2011, 0x4129, 0x1078, 0x596c,
+       0x007c, 0x0f7e, 0x707c, 0xa086, 0x0014, 0x00c0, 0x3c3e, 0x6043,
+       0x0000, 0x6020, 0xd0b4, 0x00c0, 0x3c3e, 0x2079, 0xa880, 0x7a30,
+       0xa296, 0x1102, 0x00c0, 0x3c3c, 0x7834, 0xa005, 0x00c0, 0x3c3c,
+       0x7a38, 0xd2fc, 0x0040, 0x3c32, 0x70ac, 0xa005, 0x00c0, 0x3c32,
+       0x70af, 0x0001, 0x2011, 0x4129, 0x1078, 0x58d4, 0x7087, 0x0010,
+       0x1078, 0x3e4e, 0x0078, 0x3c3e, 0x1078, 0x4171, 0x0f7f, 0x007c,
+       0x7087, 0x0003, 0x6043, 0x0004, 0x2011, 0x4129, 0x1078, 0x58d4,
+       0x1078, 0x41c6, 0x20a3, 0x1102, 0x20a3, 0x0000, 0x20a9, 0x000a,
+       0x20a3, 0x0000, 0x00f0, 0x3c50, 0x60c3, 0x0014, 0x1078, 0x4158,
+       0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x3c83, 0x2011, 0x4129,
+       0x1078, 0x58d4, 0xa086, 0x0014, 0x00c0, 0x3c81, 0x2079, 0xa880,
+       0x7a30, 0xa296, 0x1102, 0x00c0, 0x3c81, 0x7834, 0xa005, 0x00c0,
+       0x3c81, 0x7a38, 0xd2fc, 0x0040, 0x3c7b, 0x70ac, 0xa005, 0x00c0,
+       0x3c7b, 0x70af, 0x0001, 0x7087, 0x0004, 0x1078, 0x3c85, 0x0078,
+       0x3c83, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x0005, 0x1078,
+       0x41c6, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011, 0xa88e,
+       0x1078, 0x4211, 0x00c0, 0x3ca3, 0x7070, 0xa005, 0x00c0, 0x3ca3,
+       0x714c, 0xa186, 0xffff, 0x0040, 0x3ca3, 0x1078, 0x40ea, 0x0040,
+       0x3ca3, 0x1078, 0x41f5, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6,
+       0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x4158,
+       0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x3cdb, 0x2011, 0x4129,
+       0x1078, 0x58d4, 0xa086, 0x0014, 0x00c0, 0x3cd9, 0x2079, 0xa880,
+       0x7a30, 0xa296, 0x1103, 0x00c0, 0x3cd9, 0x7834, 0xa005, 0x00c0,
+       0x3cd9, 0x7a38, 0xd2fc, 0x0040, 0x3cd3, 0x70ac, 0xa005, 0x00c0,
+       0x3cd3, 0x70af, 0x0001, 0x7087, 0x0006, 0x1078, 0x3cdd, 0x0078,
+       0x3cdb, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x0007, 0x1078,
+       0x41c6, 0x20a3, 0x1104, 0x20a3, 0x0000, 0x3430, 0x2011, 0xa88e,
+       0x1078, 0x4211, 0x00c0, 0x3d05, 0x7070, 0xa005, 0x00c0, 0x3d05,
+       0x7150, 0xa186, 0xffff, 0x0040, 0x3d05, 0xa180, 0x293f, 0x200c,
+       0xa18c, 0xff00, 0x810f, 0x1078, 0x40ea, 0x0040, 0x3d05, 0x1078,
+       0x378b, 0x0040, 0x3d05, 0x1078, 0x2500, 0x20a9, 0x0008, 0x2298,
+       0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014,
+       0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x3d3d,
+       0x2011, 0x4129, 0x1078, 0x58d4, 0xa086, 0x0014, 0x00c0, 0x3d3b,
+       0x2079, 0xa880, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x3d3b, 0x7834,
+       0xa005, 0x00c0, 0x3d3b, 0x7a38, 0xd2fc, 0x0040, 0x3d35, 0x70ac,
+       0xa005, 0x00c0, 0x3d35, 0x70af, 0x0001, 0x7087, 0x0008, 0x1078,
+       0x3d3f, 0x0078, 0x3d3d, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087,
+       0x0009, 0x1078, 0x41c6, 0x20a3, 0x1105, 0x20a3, 0x0100, 0x3430,
+       0x1078, 0x4211, 0x00c0, 0x3d58, 0x7070, 0xa005, 0x00c0, 0x3d58,
+       0x1078, 0x4051, 0x00c0, 0x3d62, 0xa085, 0x0001, 0x1078, 0x2500,
+       0x20a9, 0x0008, 0x2099, 0xa88e, 0x26a0, 0x53a6, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x4158, 0x007c, 0x0f7e,
+       0x707c, 0xa005, 0x0040, 0x3da8, 0x2011, 0x4129, 0x1078, 0x58d4,
+       0xa086, 0x0014, 0x00c0, 0x3da6, 0x2079, 0xa880, 0x7a30, 0xa296,
+       0x1105, 0x00c0, 0x3da6, 0x7834, 0x2011, 0x0100, 0xa21e, 0x00c0,
+       0x3d91, 0x7a38, 0xd2fc, 0x0040, 0x3d8b, 0x70ac, 0xa005, 0x00c0,
+       0x3d8b, 0x70af, 0x0001, 0x7087, 0x000a, 0x1078, 0x3daa, 0x0078,
+       0x3da8, 0xa005, 0x00c0, 0x3da6, 0x7a38, 0xd2fc, 0x0040, 0x3d9e,
+       0x70ac, 0xa005, 0x00c0, 0x3d9e, 0x70af, 0x0001, 0x7083, 0x0000,
+       0x7087, 0x000e, 0x1078, 0x3e32, 0x0078, 0x3da8, 0x1078, 0x4171,
+       0x0f7f, 0x007c, 0x7087, 0x000b, 0x2011, 0xa80e, 0x22a0, 0x20a9,
+       0x0040, 0x2019, 0xffff, 0x43a4, 0x20a9, 0x0002, 0x2009, 0x0000,
+       0x41a4, 0x1078, 0x41c6, 0x20a3, 0x1106, 0x20a3, 0x0000, 0x1078,
+       0x4211, 0x0040, 0x3dc7, 0x2013, 0x0000, 0x0078, 0x3dcb, 0x6030,
+       0xa085, 0x0100, 0x2012, 0x2298, 0x20a9, 0x0042, 0x53a6, 0x60c3,
+       0x0084, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040,
+       0x3df4, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086, 0x0084, 0x00c0,
+       0x3df2, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1106, 0x00c0, 0x3df2,
+       0x7834, 0xa005, 0x00c0, 0x3df2, 0x7087, 0x000c, 0x1078, 0x3df6,
+       0x0078, 0x3df4, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x000d,
+       0x1078, 0x41c6, 0x20a3, 0x1107, 0x20a3, 0x0000, 0x2099, 0xa88e,
+       0x20a9, 0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
+       0x0084, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040,
+       0x3e30, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086, 0x0084, 0x00c0,
+       0x3e2e, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1107, 0x00c0, 0x3e2e,
+       0x7834, 0xa005, 0x00c0, 0x3e2e, 0x7083, 0x0001, 0x1078, 0x41b8,
+       0x7087, 0x000e, 0x1078, 0x3e32, 0x0078, 0x3e30, 0x1078, 0x4171,
+       0x0f7f, 0x007c, 0x7087, 0x000f, 0x707f, 0x0000, 0x608b, 0xbc85,
+       0x608f, 0xb5b5, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0,
+       0x2011, 0x4129, 0x1078, 0x58c7, 0x007c, 0x707c, 0xa005, 0x0040,
+       0x3e4d, 0x2011, 0x4129, 0x1078, 0x58d4, 0x007c, 0x7087, 0x0011,
+       0x1078, 0x4211, 0x00c0, 0x3e67, 0x7168, 0x81ff, 0x0040, 0x3e67,
+       0x2009, 0x0000, 0x706c, 0xa084, 0x00ff, 0x1078, 0x24e3, 0xa186,
+       0x0080, 0x0040, 0x3e67, 0x2011, 0xa88e, 0x1078, 0x40ea, 0x20e1,
+       0x9080, 0x20e1, 0x4000, 0x2099, 0xa880, 0x20a1, 0x020b, 0x747c,
+       0xa480, 0x0018, 0xa080, 0x0007, 0xa084, 0x03f8, 0x8004, 0x20a8,
+       0x53a6, 0x60c3, 0x0014, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c,
+       0xa005, 0x0040, 0x3ea8, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086,
+       0x0014, 0x00c0, 0x3ea6, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1103,
+       0x00c0, 0x3ea6, 0x7834, 0xa005, 0x00c0, 0x3ea6, 0x7a38, 0xd2fc,
+       0x0040, 0x3ea0, 0x70ac, 0xa005, 0x00c0, 0x3ea0, 0x70af, 0x0001,
+       0x7087, 0x0012, 0x1078, 0x3eaa, 0x0078, 0x3ea8, 0x1078, 0x4171,
+       0x0f7f, 0x007c, 0x7087, 0x0013, 0x1078, 0x41d2, 0x20a3, 0x1103,
+       0x20a3, 0x0000, 0x3430, 0x2011, 0xa88e, 0x1078, 0x4211, 0x00c0,
+       0x3ec8, 0x7070, 0xa005, 0x00c0, 0x3ec8, 0x714c, 0xa186, 0xffff,
+       0x0040, 0x3ec8, 0x1078, 0x40ea, 0x0040, 0x3ec8, 0x1078, 0x41f5,
+       0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x60c3, 0x0014, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c,
+       0xa005, 0x0040, 0x3f00, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086,
+       0x0014, 0x00c0, 0x3efe, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1104,
+       0x00c0, 0x3efe, 0x7834, 0xa005, 0x00c0, 0x3efe, 0x7a38, 0xd2fc,
+       0x0040, 0x3ef8, 0x70ac, 0xa005, 0x00c0, 0x3ef8, 0x70af, 0x0001,
+       0x7087, 0x0014, 0x1078, 0x3f02, 0x0078, 0x3f00, 0x1078, 0x4171,
+       0x0f7f, 0x007c, 0x7087, 0x0015, 0x1078, 0x41d2, 0x20a3, 0x1104,
+       0x20a3, 0x0000, 0x3430, 0x2011, 0xa88e, 0x1078, 0x4211, 0x00c0,
+       0x3f2a, 0x7070, 0xa005, 0x00c0, 0x3f2a, 0x7150, 0xa186, 0xffff,
+       0x0040, 0x3f2a, 0xa180, 0x293f, 0x200c, 0xa18c, 0xff00, 0x810f,
+       0x1078, 0x40ea, 0x0040, 0x3f2a, 0x1078, 0x378b, 0x0040, 0x3f2a,
+       0x1078, 0x2500, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x4158, 0x007c,
+       0x0f7e, 0x707c, 0xa005, 0x0040, 0x3f7b, 0x2011, 0x4129, 0x1078,
+       0x58d4, 0xa086, 0x0014, 0x00c0, 0x3f79, 0x2079, 0xa880, 0x7a30,
+       0xa296, 0x1105, 0x00c0, 0x3f79, 0x7834, 0x2011, 0x0100, 0xa21e,
+       0x00c0, 0x3f5e, 0x7a38, 0xd2fc, 0x0040, 0x3f5c, 0x70ac, 0xa005,
+       0x00c0, 0x3f5c, 0x70af, 0x0001, 0x0078, 0x3f6d, 0xa005, 0x00c0,
+       0x3f79, 0x7a38, 0xd2fc, 0x0040, 0x3f6b, 0x70ac, 0xa005, 0x00c0,
+       0x3f6b, 0x70af, 0x0001, 0x7083, 0x0000, 0x7a38, 0xd2f4, 0x0040,
+       0x3f73, 0x70cb, 0x0008, 0x7087, 0x0016, 0x1078, 0x3f7d, 0x0078,
+       0x3f7b, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x20e1, 0x9080, 0x20e1,
+       0x4000, 0x2099, 0xa880, 0x20a1, 0x020b, 0x20a9, 0x000e, 0x53a6,
+       0x3430, 0x2011, 0xa88e, 0x7087, 0x0017, 0x1078, 0x4211, 0x00c0,
+       0x3f9d, 0x7070, 0xa005, 0x00c0, 0x3f9d, 0x1078, 0x4051, 0x00c0,
+       0x3fa7, 0xa085, 0x0001, 0x1078, 0x2500, 0x20a9, 0x0008, 0x2099,
+       0xa88e, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
+       0x0014, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040,
+       0x3fcc, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086, 0x0084, 0x00c0,
+       0x3fca, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1106, 0x00c0, 0x3fca,
+       0x7834, 0xa005, 0x00c0, 0x3fca, 0x7087, 0x0018, 0x1078, 0x3fce,
+       0x0078, 0x3fcc, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x0019,
+       0x1078, 0x41d2, 0x20a3, 0x1106, 0x20a3, 0x0000, 0x3430, 0x2099,
+       0xa88e, 0x2039, 0xa80e, 0x27a0, 0x20a9, 0x0040, 0x53a3, 0x1078,
+       0x4211, 0x00c0, 0x4002, 0x2728, 0x2514, 0x8207, 0xa084, 0x00ff,
+       0x8000, 0x2018, 0xa294, 0x00ff, 0x8007, 0xa205, 0x202a, 0x6030,
+       0x2310, 0x8214, 0xa2a0, 0xa80e, 0x2414, 0xa38c, 0x0001, 0x0040,
+       0x3ffd, 0xa294, 0xff00, 0x0078, 0x4000, 0xa294, 0x00ff, 0x8007,
+       0xa215, 0x2222, 0x2798, 0x26a0, 0x20a9, 0x0040, 0x53a6, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x1078, 0x4158, 0x007c,
+       0x0f7e, 0x707c, 0xa005, 0x0040, 0x4034, 0x2011, 0x4129, 0x1078,
+       0x58d4, 0xa086, 0x0084, 0x00c0, 0x4032, 0x2079, 0xa880, 0x7a30,
+       0xa296, 0x1107, 0x00c0, 0x4032, 0x7834, 0xa005, 0x00c0, 0x4032,
+       0x7083, 0x0001, 0x1078, 0x41b8, 0x7087, 0x001a, 0x1078, 0x4036,
+       0x0078, 0x4034, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x001b,
+       0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xa880, 0x20a1, 0x020b,
+       0x747c, 0xa480, 0x0018, 0xa080, 0x0007, 0xa084, 0x03f8, 0x8004,
+       0x20a8, 0x53a6, 0x60c3, 0x0084, 0x1078, 0x4158, 0x007c, 0x007c,
+       0x007c, 0x087e, 0x097e, 0x2029, 0xa352, 0x252c, 0x20a9, 0x0008,
+       0x2041, 0xa80e, 0x28a0, 0x2099, 0xa88e, 0x53a3, 0x20a9, 0x0008,
+       0x2011, 0x0007, 0xd5d4, 0x0040, 0x4067, 0x2011, 0x0000, 0x2800,
+       0xa200, 0x200c, 0xa1a6, 0xffff, 0x00c0, 0x4079, 0xd5d4, 0x0040,
+       0x4074, 0x8210, 0x0078, 0x4075, 0x8211, 0x00f0, 0x4067, 0x0078,
+       0x40e1, 0x82ff, 0x00c0, 0x408b, 0xd5d4, 0x0040, 0x4085, 0xa1a6,
+       0x3fff, 0x0040, 0x4071, 0x0078, 0x4089, 0xa1a6, 0x3fff, 0x0040,
+       0x40e1, 0xa18d, 0xc000, 0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4,
+       0x0040, 0x4094, 0x2019, 0x0010, 0x2120, 0xd5d4, 0x0040, 0x409b,
+       0x8423, 0x0078, 0x409c, 0x8424, 0x00c8, 0x40a9, 0xd5d4, 0x0040,
+       0x40a4, 0x8319, 0x0078, 0x40a5, 0x8318, 0x00f0, 0x4095, 0x0078,
+       0x40e1, 0x23a8, 0x2021, 0x0001, 0x8426, 0x8425, 0x00f0, 0x40ad,
+       0x2328, 0x8529, 0xa2be, 0x0007, 0x0040, 0x40c1, 0x007e, 0x2039,
+       0x0007, 0x2200, 0xa73a, 0x007f, 0x27a8, 0xa5a8, 0x0010, 0x00f0,
+       0x40bd, 0x754e, 0xa5c8, 0x293f, 0x292c, 0xa5ac, 0x00ff, 0x6532,
+       0x60e7, 0x0000, 0x65ea, 0x706b, 0x0000, 0x756e, 0x2018, 0x2304,
+       0xa405, 0x201a, 0x7073, 0x0001, 0x26a0, 0x2898, 0x20a9, 0x0008,
+       0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0xa085, 0x0001, 0x0078,
+       0x40e7, 0xa006, 0x0078, 0x40e7, 0xa006, 0x1078, 0x1328, 0x097f,
+       0x087f, 0x007c, 0x2118, 0x2021, 0x0000, 0x2001, 0x0007, 0xa39a,
+       0x0010, 0x0048, 0x40f7, 0x8420, 0x8001, 0x0078, 0x40ef, 0x2118,
+       0x84ff, 0x0040, 0x4100, 0xa39a, 0x0010, 0x8421, 0x00c0, 0x40fb,
+       0x2021, 0x0001, 0x83ff, 0x0040, 0x4109, 0x8423, 0x8319, 0x00c0,
+       0x4105, 0xa238, 0x2704, 0xa42c, 0x00c0, 0x4121, 0xa405, 0x203a,
+       0x714e, 0xa1a0, 0x293f, 0x242c, 0xa5ac, 0x00ff, 0x6532, 0x60e7,
+       0x0000, 0x65ea, 0x706b, 0x0000, 0x756e, 0x7073, 0x0001, 0xa084,
+       0x0000, 0x007c, 0x0e7e, 0x2071, 0xa300, 0x7077, 0x0000, 0x0e7f,
+       0x007c, 0x0e7e, 0x0f7e, 0x2001, 0x0002, 0x1078, 0x5975, 0x2079,
+       0x0100, 0x2071, 0x0140, 0x1078, 0x6c41, 0x7004, 0xa084, 0x4000,
+       0x0040, 0x413e, 0x7003, 0x1000, 0x7003, 0x0000, 0x127e, 0x2091,
+       0x8000, 0x2071, 0xa321, 0x2073, 0x0000, 0x7840, 0x027e, 0x017e,
+       0x2009, 0x00f7, 0x1078, 0x41de, 0x017f, 0xa094, 0x0010, 0xa285,
+       0x0080, 0x7842, 0x7a42, 0x027f, 0x127f, 0x0f7f, 0x0e7f, 0x007c,
+       0x127e, 0x2091, 0x8000, 0x2011, 0xa5b5, 0x2013, 0x0000, 0x707f,
+       0x0000, 0x127f, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575,
+       0x1078, 0x6c38, 0x2009, 0x07d0, 0x2011, 0x4129, 0x1078, 0x596c,
+       0x007c, 0x017e, 0x027e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x2009,
+       0x00f7, 0x1078, 0x41de, 0x2061, 0xa5be, 0x601b, 0x0000, 0x601f,
+       0x0000, 0x2061, 0xa300, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043,
+       0x0090, 0x6043, 0x0010, 0x2009, 0x002d, 0x2011, 0x4196, 0x1078,
+       0x58c7, 0x127f, 0x0c7f, 0x027f, 0x017f, 0x007c, 0x0e7e, 0x007e,
+       0x127e, 0x2091, 0x8000, 0x2001, 0x0001, 0x1078, 0x5975, 0x2071,
+       0x0100, 0x1078, 0x6c41, 0x2071, 0x0140, 0x7004, 0xa084, 0x4000,
+       0x0040, 0x41ae, 0x7003, 0x1000, 0x7003, 0x0000, 0x2001, 0x0001,
+       0x1078, 0x2480, 0x1078, 0x4171, 0x127f, 0x007f, 0x0e7f, 0x007c,
+       0x20a9, 0x0040, 0x20a1, 0xa9c0, 0x2099, 0xa88e, 0x3304, 0x8007,
+       0x20a2, 0x9398, 0x94a0, 0x00f0, 0x41be, 0x007c, 0x20e1, 0x9080,
+       0x20e1, 0x4000, 0x2099, 0xa800, 0x20a1, 0x020b, 0x20a9, 0x000c,
+       0x53a6, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xa880,
+       0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6, 0x007c, 0x0c7e, 0x007e,
+       0x2061, 0x0100, 0x810f, 0x2001, 0xa32e, 0x2004, 0xa005, 0x00c0,
+       0x41ef, 0x6030, 0xa084, 0x00ff, 0xa105, 0x0078, 0x41f1, 0xa185,
+       0x00f7, 0x604a, 0x007f, 0x0c7f, 0x007c, 0x017e, 0x047e, 0x2001,
+       0xa352, 0x2004, 0xd0a4, 0x0040, 0x4208, 0xa006, 0x2020, 0x2009,
+       0x002a, 0x1078, 0x9ec0, 0x2001, 0xa30c, 0x200c, 0xc195, 0x2102,
+       0x2019, 0x002a, 0x2009, 0x0000, 0x1078, 0x27e2, 0x047f, 0x017f,
+       0x007c, 0x007e, 0x2001, 0xa30c, 0x2004, 0xd09c, 0x0040, 0x4218,
+       0x007f, 0x007c, 0x007e, 0x017e, 0x127e, 0x2091, 0x8000, 0x2001,
+       0x0101, 0x200c, 0xa18d, 0x0006, 0x2102, 0x127f, 0x017f, 0x007f,
+       0x007c, 0x157e, 0x20a9, 0x00ff, 0x2009, 0xa434, 0xa006, 0x200a,
+       0x8108, 0x00f0, 0x422f, 0x157f, 0x007c, 0x0d7e, 0x037e, 0x157e,
+       0x137e, 0x147e, 0x2069, 0xa351, 0xa006, 0x6002, 0x6007, 0x0707,
+       0x600a, 0x600e, 0x6012, 0xa198, 0x293f, 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, 0x60ae, 0x61a2, 0x0d7e, 0x60a4,
+       0xa06d, 0x0040, 0x4275, 0x1078, 0x139a, 0x60a7, 0x0000, 0x60a8,
+       0xa06d, 0x0040, 0x427d, 0x1078, 0x139a, 0x60ab, 0x0000, 0x0d7f,
+       0xa006, 0x604a, 0x6810, 0x603a, 0x680c, 0x6046, 0x6814, 0xa084,
+       0x00ff, 0x6042, 0x147f, 0x137f, 0x157f, 0x037f, 0x0d7f, 0x007c,
+       0x127e, 0x2091, 0x8000, 0x6944, 0x6e48, 0xa684, 0x3fff, 0xa082,
+       0x4000, 0x00c8, 0x4361, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff,
+       0x00c8, 0x4367, 0x2001, 0xa30c, 0x2004, 0xa084, 0x0003, 0x0040,
+       0x42c2, 0x2001, 0xa30c, 0x2004, 0xd084, 0x00c0, 0x4342, 0xa188,
+       0xa434, 0x2104, 0xa065, 0x0040, 0x4342, 0x6004, 0xa084, 0x00ff,
+       0xa08e, 0x0006, 0x00c0, 0x4342, 0x6000, 0xd0c4, 0x0040, 0x4342,
+       0x0078, 0x42cf, 0xa188, 0xa434, 0x2104, 0xa065, 0x0040, 0x4326,
+       0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x00c0, 0x432c, 0x60a4,
+       0xa00d, 0x0040, 0x42d7, 0x1078, 0x4749, 0x0040, 0x4320, 0x60a8,
+       0xa00d, 0x0040, 0x42f1, 0x1078, 0x479a, 0x00c0, 0x42f1, 0x694c,
+       0xd1fc, 0x00c0, 0x42e7, 0x1078, 0x441c, 0x0078, 0x431b, 0x1078,
+       0x43d6, 0x694c, 0xd1ec, 0x00c0, 0x431b, 0x1078, 0x460a, 0x0078,
+       0x431b, 0x694c, 0xa184, 0xa000, 0x0040, 0x430b, 0xd1ec, 0x0040,
+       0x4304, 0xd1fc, 0x0040, 0x4300, 0x1078, 0x461b, 0x0078, 0x4307,
+       0x1078, 0x461b, 0x0078, 0x430b, 0xd1fc, 0x0040, 0x430b, 0x1078,
+       0x43d6, 0x0078, 0x431b, 0x6050, 0xa00d, 0x0040, 0x4316, 0x2d00,
+       0x200a, 0x6803, 0x0000, 0x6052, 0x0078, 0x431b, 0x2d00, 0x6052,
+       0x604e, 0x6803, 0x0000, 0x1078, 0x5c17, 0xa006, 0x127f, 0x007c,
+       0x2001, 0x0005, 0x2009, 0x0000, 0x0078, 0x436b, 0x2001, 0x0028,
+       0x2009, 0x0000, 0x0078, 0x436b, 0xa082, 0x0006, 0x00c8, 0x4342,
+       0x60a0, 0xd0bc, 0x00c0, 0x433e, 0x6100, 0xd1fc, 0x0040, 0x42cf,
+       0x2001, 0x0029, 0x2009, 0x1000, 0x0078, 0x436b, 0x2001, 0x0028,
+       0x0078, 0x435d, 0x2009, 0xa30c, 0x210c, 0xd18c, 0x0040, 0x434c,
+       0x2001, 0x0004, 0x0078, 0x435d, 0xd184, 0x0040, 0x4353, 0x2001,
+       0x0004, 0x0078, 0x435d, 0x2001, 0x0029, 0x6100, 0xd1fc, 0x0040,
+       0x435d, 0x2009, 0x1000, 0x0078, 0x436b, 0x2009, 0x0000, 0x0078,
+       0x436b, 0x2001, 0x0029, 0x2009, 0x0000, 0x0078, 0x436b, 0x2001,
+       0x0029, 0x2009, 0x0000, 0xa005, 0x127f, 0x007c, 0x6944, 0x6e48,
+       0xa684, 0x3fff, 0xa082, 0x4000, 0x00c8, 0x43bb, 0xa18c, 0xff00,
+       0x810f, 0xa182, 0x00ff, 0x00c8, 0x43a1, 0xa188, 0xa434, 0x2104,
+       0xa065, 0x0040, 0x43a1, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006,
+       0x00c0, 0x43a7, 0x684c, 0xd0ec, 0x0040, 0x4394, 0x1078, 0x461b,
+       0x1078, 0x43d6, 0x0078, 0x439c, 0x1078, 0x43d6, 0x684c, 0xd0fc,
+       0x0040, 0x439c, 0x1078, 0x460a, 0x1078, 0x4663, 0xa006, 0x0078,
+       0x43bf, 0x2001, 0x0028, 0x2009, 0x0000, 0x0078, 0x43bf, 0xa082,
+       0x0006, 0x00c8, 0x43b5, 0x6100, 0xd1fc, 0x0040, 0x438a, 0x2001,
+       0x0029, 0x2009, 0x1000, 0x0078, 0x43bf, 0x2001, 0x0029, 0x2009,
+       0x0000, 0x0078, 0x43bf, 0x2001, 0x0029, 0x2009, 0x0000, 0xa005,
+       0x007c, 0x127e, 0x2091, 0x8000, 0x6050, 0xa00d, 0x0040, 0x43cf,
+       0x2d00, 0x200a, 0x6803, 0x0000, 0x6052, 0x127f, 0x007c, 0x2d00,
+       0x6052, 0x604e, 0x6803, 0x0000, 0x0078, 0x43cd, 0x127e, 0x2091,
+       0x8000, 0x604c, 0xa005, 0x0040, 0x43ec, 0x0e7e, 0x2071, 0xa5ab,
+       0x7004, 0xa086, 0x0002, 0x0040, 0x43f3, 0x0e7f, 0x604c, 0x6802,
+       0x2d00, 0x604e, 0x127f, 0x007c, 0x2d00, 0x6052, 0x604e, 0x6803,
+       0x0000, 0x0078, 0x43ea, 0x701c, 0xac06, 0x00c0, 0x43e5, 0x604c,
+       0x2070, 0x7000, 0x6802, 0x2d00, 0x7002, 0x0e7f, 0x127f, 0x007c,
+       0x127e, 0x2091, 0x8000, 0x604c, 0xa06d, 0x0040, 0x440e, 0x6800,
+       0xa005, 0x00c0, 0x440c, 0x6052, 0x604e, 0xad05, 0x127f, 0x007c,
+       0x604c, 0xa06d, 0x0040, 0x441b, 0x6800, 0xa005, 0x00c0, 0x4419,
+       0x6052, 0x604e, 0xad05, 0x007c, 0x6803, 0x0000, 0x6084, 0xa00d,
+       0x0040, 0x4426, 0x2d00, 0x200a, 0x6086, 0x007c, 0x2d00, 0x6086,
+       0x6082, 0x0078, 0x4425, 0x127e, 0x0c7e, 0x027e, 0x2091, 0x8000,
+       0x6218, 0x2260, 0x6200, 0xa005, 0x0040, 0x4439, 0xc285, 0x0078,
+       0x443a, 0xc284, 0x6202, 0x027f, 0x0c7f, 0x127f, 0x007c, 0x127e,
+       0x0c7e, 0x2091, 0x8000, 0x6218, 0x2260, 0x6204, 0x007e, 0xa086,
+       0x0006, 0x00c0, 0x445e, 0x609c, 0xd0ac, 0x0040, 0x445e, 0x2001,
+       0xa352, 0x2004, 0xd0a4, 0x0040, 0x445e, 0xa284, 0xff00, 0x8007,
+       0xa086, 0x0007, 0x00c0, 0x445e, 0x2011, 0x0600, 0x007f, 0xa294,
+       0xff00, 0xa215, 0x6206, 0x007e, 0xa086, 0x0006, 0x00c0, 0x446e,
+       0x6290, 0x82ff, 0x00c0, 0x446e, 0x1078, 0x1328, 0x007f, 0x0c7f,
+       0x127f, 0x007c, 0x127e, 0x0c7e, 0x2091, 0x8000, 0x6218, 0x2260,
+       0x6204, 0x007e, 0xa086, 0x0006, 0x00c0, 0x4490, 0x609c, 0xd0a4,
+       0x0040, 0x4490, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x00c0, 0x4490,
+       0xa284, 0x00ff, 0xa086, 0x0007, 0x00c0, 0x4490, 0x2011, 0x0006,
+       0x007f, 0xa294, 0x00ff, 0x8007, 0xa215, 0x6206, 0x0c7f, 0x127f,
+       0x007c, 0x027e, 0xa182, 0x00ff, 0x0048, 0x44a2, 0xa085, 0x0001,
+       0x0078, 0x44ba, 0xa190, 0xa434, 0x2204, 0xa065, 0x00c0, 0x44b9,
+       0x017e, 0x0d7e, 0x1078, 0x1366, 0x2d60, 0x0d7f, 0x017f, 0x0040,
+       0x449e, 0x2c00, 0x2012, 0x60a7, 0x0000, 0x60ab, 0x0000, 0x1078,
+       0x4235, 0xa006, 0x027f, 0x007c, 0x127e, 0x2091, 0x8000, 0x027e,
+       0xa182, 0x00ff, 0x0048, 0x44c8, 0xa085, 0x0001, 0x0078, 0x44fe,
+       0x0d7e, 0xa190, 0xa434, 0x2204, 0xa06d, 0x0040, 0x44fc, 0x2013,
+       0x0000, 0x0d7e, 0x0c7e, 0x2d60, 0x60a4, 0xa06d, 0x0040, 0x44da,
+       0x1078, 0x139a, 0x60a8, 0xa06d, 0x0040, 0x44e0, 0x1078, 0x139a,
+       0x0c7f, 0x0d7f, 0x0d7e, 0x0c7e, 0x68ac, 0x2060, 0x8cff, 0x0040,
+       0x44f8, 0x600c, 0x007e, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040,
+       0x44f3, 0x1078, 0x13aa, 0x1078, 0x753d, 0x0c7f, 0x0078, 0x44e6,
+       0x0c7f, 0x0d7f, 0x1078, 0x139a, 0x0d7f, 0xa006, 0x027f, 0x127f,
+       0x007c, 0x017e, 0xa182, 0x00ff, 0x0048, 0x450a, 0xa085, 0x0001,
+       0x0078, 0x4511, 0xa188, 0xa434, 0x2104, 0xa065, 0x0040, 0x4506,
+       0xa006, 0x017f, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x600b,
+       0x0000, 0x600f, 0x0000, 0x6000, 0xc08c, 0x6002, 0x2069, 0xa88e,
+       0x6808, 0x605e, 0x6810, 0x6062, 0x6138, 0xa10a, 0x0048, 0x4529,
+       0x603a, 0x6814, 0x6066, 0x2099, 0xa896, 0xac88, 0x000a, 0x21a0,
+       0x20a9, 0x0004, 0x53a3, 0x2099, 0xa89a, 0xac88, 0x0006, 0x21a0,
+       0x20a9, 0x0004, 0x53a3, 0x2069, 0xa8ae, 0x6808, 0x606a, 0x690c,
+       0x616e, 0x6810, 0x6072, 0x6818, 0x6076, 0xa182, 0x0211, 0x00c8,
+       0x454d, 0x2009, 0x0008, 0x0078, 0x4577, 0xa182, 0x0259, 0x00c8,
+       0x4555, 0x2009, 0x0007, 0x0078, 0x4577, 0xa182, 0x02c1, 0x00c8,
+       0x455d, 0x2009, 0x0006, 0x0078, 0x4577, 0xa182, 0x0349, 0x00c8,
+       0x4565, 0x2009, 0x0005, 0x0078, 0x4577, 0xa182, 0x0421, 0x00c8,
+       0x456d, 0x2009, 0x0004, 0x0078, 0x4577, 0xa182, 0x0581, 0x00c8,
+       0x4575, 0x2009, 0x0003, 0x0078, 0x4577, 0x2009, 0x0002, 0x6192,
+       0x147f, 0x137f, 0x157f, 0x0d7f, 0x007c, 0x017e, 0x027e, 0x0e7e,
+       0x2071, 0xa88d, 0x2e04, 0x6896, 0x2071, 0xa88e, 0x7004, 0x689a,
+       0x701c, 0x689e, 0x6a00, 0x2009, 0xa371, 0x210c, 0xd0bc, 0x0040,
+       0x4597, 0xd1ec, 0x0040, 0x4597, 0xc2ad, 0x0078, 0x4598, 0xc2ac,
+       0xd0c4, 0x0040, 0x45a1, 0xd1e4, 0x0040, 0x45a1, 0xc2bd, 0x0078,
+       0x45a2, 0xc2bc, 0x6a02, 0x0e7f, 0x027f, 0x017f, 0x007c, 0x0d7e,
+       0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x0040, 0x45cb, 0x6900,
+       0x81ff, 0x00c0, 0x45df, 0x6a04, 0xa282, 0x0010, 0x00c8, 0x45e4,
+       0xad88, 0x0004, 0x20a9, 0x0010, 0x2104, 0xa086, 0xffff, 0x0040,
+       0x45c6, 0x8108, 0x00f0, 0x45bc, 0x1078, 0x1328, 0x260a, 0x8210,
+       0x6a06, 0x0078, 0x45df, 0x1078, 0x1381, 0x0040, 0x45e4, 0x2d00,
+       0x60a6, 0x6803, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b,
+       0xffff, 0x8108, 0x00f0, 0x45d7, 0x6807, 0x0001, 0x6e12, 0xa085,
+       0x0001, 0x127f, 0x0d7f, 0x007c, 0xa006, 0x0078, 0x45e1, 0x127e,
+       0x2091, 0x8000, 0x0d7e, 0x60a4, 0xa00d, 0x0040, 0x4607, 0x2168,
+       0x6800, 0xa005, 0x00c0, 0x4603, 0x1078, 0x4749, 0x00c0, 0x4607,
+       0x200b, 0xffff, 0x6804, 0xa08a, 0x0002, 0x0048, 0x4603, 0x8001,
+       0x6806, 0x0078, 0x4607, 0x1078, 0x139a, 0x60a7, 0x0000, 0x0d7f,
+       0x127f, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x47af, 0x0078,
+       0x4613, 0x1078, 0x43c1, 0x1078, 0x46a7, 0x00c0, 0x4611, 0x1078,
+       0x4663, 0x127f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a8,
+       0xa06d, 0x0040, 0x463f, 0x6950, 0x81ff, 0x00c0, 0x4653, 0x6a54,
+       0xa282, 0x0010, 0x00c8, 0x4660, 0xad88, 0x0018, 0x20a9, 0x0010,
+       0x2104, 0xa086, 0xffff, 0x0040, 0x463a, 0x8108, 0x00f0, 0x4630,
+       0x1078, 0x1328, 0x260a, 0x8210, 0x6a56, 0x0078, 0x4653, 0x1078,
+       0x1381, 0x0040, 0x4660, 0x2d00, 0x60aa, 0x6853, 0x0000, 0xad88,
+       0x0018, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108, 0x00f0, 0x464b,
+       0x6857, 0x0001, 0x6e62, 0x0078, 0x4657, 0x1078, 0x441c, 0x1078,
+       0x466d, 0x00c0, 0x4655, 0xa085, 0x0001, 0x127f, 0x0d7f, 0x007c,
+       0xa006, 0x0078, 0x465d, 0x127e, 0x2091, 0x8000, 0x1078, 0x5c17,
+       0x127f, 0x007c, 0xa01e, 0x0078, 0x466f, 0x2019, 0x0001, 0xa00e,
+       0x127e, 0x2091, 0x8000, 0x604c, 0x2068, 0x6000, 0xd0dc, 0x00c0,
+       0x468d, 0x8dff, 0x0040, 0x46a2, 0x83ff, 0x0040, 0x4685, 0x6848,
+       0xa606, 0x0040, 0x4692, 0x0078, 0x468d, 0x683c, 0xa406, 0x00c0,
+       0x468d, 0x6840, 0xa506, 0x0040, 0x4692, 0x2d08, 0x6800, 0x2068,
+       0x0078, 0x4679, 0x6a00, 0x604c, 0xad06, 0x00c0, 0x469a, 0x624e,
+       0x0078, 0x469d, 0xa180, 0x0000, 0x2202, 0x82ff, 0x00c0, 0x46a2,
+       0x6152, 0x8dff, 0x127f, 0x007c, 0xa01e, 0x0078, 0x46a9, 0x2019,
+       0x0001, 0xa00e, 0x6080, 0x2068, 0x8dff, 0x0040, 0x46d5, 0x83ff,
+       0x0040, 0x46b8, 0x6848, 0xa606, 0x0040, 0x46c5, 0x0078, 0x46c0,
+       0x683c, 0xa406, 0x00c0, 0x46c0, 0x6840, 0xa506, 0x0040, 0x46c5,
+       0x2d08, 0x6800, 0x2068, 0x0078, 0x46ac, 0x6a00, 0x6080, 0xad06,
+       0x00c0, 0x46cd, 0x6282, 0x0078, 0x46d0, 0xa180, 0x0000, 0x2202,
+       0x82ff, 0x00c0, 0x46d5, 0x6186, 0x8dff, 0x007c, 0xa016, 0x1078,
+       0x4742, 0x00c0, 0x46dd, 0x2011, 0x0001, 0x1078, 0x4793, 0x00c0,
+       0x46e3, 0xa295, 0x0002, 0x007c, 0x1078, 0x47cb, 0x0040, 0x46ec,
+       0x1078, 0x8b12, 0x0078, 0x46ee, 0xa085, 0x0001, 0x007c, 0x1078,
+       0x47cb, 0x0040, 0x46f7, 0x1078, 0x8aaa, 0x0078, 0x46f9, 0xa085,
+       0x0001, 0x007c, 0x1078, 0x47cb, 0x0040, 0x4702, 0x1078, 0x8af4,
+       0x0078, 0x4704, 0xa085, 0x0001, 0x007c, 0x1078, 0x47cb, 0x0040,
+       0x470d, 0x1078, 0x8ac6, 0x0078, 0x470f, 0xa085, 0x0001, 0x007c,
+       0x1078, 0x47cb, 0x0040, 0x4718, 0x1078, 0x8b30, 0x0078, 0x471a,
+       0xa085, 0x0001, 0x007c, 0x127e, 0x007e, 0x0d7e, 0x2091, 0x8000,
+       0x6080, 0xa06d, 0x0040, 0x473a, 0x6800, 0x007e, 0x6837, 0x0103,
+       0x6b4a, 0x6847, 0x0000, 0x1078, 0x8cb8, 0x007e, 0x6000, 0xd0fc,
+       0x0040, 0x4734, 0x1078, 0xa18c, 0x007f, 0x1078, 0x4982, 0x007f,
+       0x0078, 0x4721, 0x6083, 0x0000, 0x6087, 0x0000, 0x0d7f, 0x007f,
+       0x127f, 0x007c, 0x60a4, 0xa00d, 0x00c0, 0x4749, 0xa085, 0x0001,
+       0x007c, 0x0e7e, 0x2170, 0x7000, 0xa005, 0x00c0, 0x475c, 0x20a9,
+       0x0010, 0xae88, 0x0004, 0x2104, 0xa606, 0x0040, 0x475c, 0x8108,
+       0x00f0, 0x4753, 0xa085, 0x0001, 0xa006, 0x0e7f, 0x007c, 0x0d7e,
+       0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x00c0, 0x476d, 0x1078,
+       0x1381, 0x0040, 0x477f, 0x2d00, 0x60a6, 0x6803, 0x0001, 0x6807,
+       0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108,
+       0x00f0, 0x4775, 0xa085, 0x0001, 0x127f, 0x0d7f, 0x007c, 0xa006,
+       0x0078, 0x477c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d,
+       0x0040, 0x4790, 0x60a7, 0x0000, 0x1078, 0x139a, 0xa085, 0x0001,
+       0x127f, 0x0d7f, 0x007c, 0x60a8, 0xa00d, 0x00c0, 0x479a, 0xa085,
+       0x0001, 0x007c, 0x0e7e, 0x2170, 0x7050, 0xa005, 0x00c0, 0x47ad,
+       0x20a9, 0x0010, 0xae88, 0x0018, 0x2104, 0xa606, 0x0040, 0x47ad,
+       0x8108, 0x00f0, 0x47a4, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x127e,
+       0x2091, 0x8000, 0x1078, 0x4793, 0x00c0, 0x47c9, 0x200b, 0xffff,
+       0x0d7e, 0x60a8, 0x2068, 0x6854, 0xa08a, 0x0002, 0x0048, 0x47c4,
+       0x8001, 0x6856, 0x0078, 0x47c8, 0x1078, 0x139a, 0x60ab, 0x0000,
+       0x0d7f, 0x127f, 0x007c, 0x609c, 0xd0a4, 0x007c, 0x0f7e, 0x71ac,
+       0x81ff, 0x00c0, 0x47e9, 0x71c8, 0xd19c, 0x0040, 0x47e9, 0x2001,
+       0x007e, 0xa080, 0xa434, 0x2004, 0xa07d, 0x0040, 0x47e9, 0x7804,
+       0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x47e9, 0x7800, 0xc0ed,
+       0x7802, 0x2079, 0xa351, 0x7804, 0xd0a4, 0x0040, 0x480f, 0x157e,
+       0x0c7e, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x4501,
+       0x00c0, 0x4809, 0x6004, 0xa084, 0xff00, 0x8007, 0xa096, 0x0004,
+       0x0040, 0x4806, 0xa086, 0x0006, 0x00c0, 0x4809, 0x6000, 0xc0ed,
+       0x6002, 0x017f, 0x8108, 0x00f0, 0x47f5, 0x0c7f, 0x157f, 0x1078,
+       0x4897, 0x0040, 0x4818, 0x2001, 0xa59f, 0x200c, 0x0078, 0x4820,
+       0x2079, 0xa351, 0x7804, 0xd0a4, 0x0040, 0x4824, 0x2009, 0x07d0,
+       0x2011, 0x4826, 0x1078, 0x596c, 0x0f7f, 0x007c, 0x2011, 0x4826,
+       0x1078, 0x58d4, 0x1078, 0x4897, 0x0040, 0x484e, 0x2001, 0xa4b2,
+       0x2004, 0xa080, 0x0000, 0x200c, 0xc1ec, 0x2102, 0x2001, 0xa352,
+       0x2004, 0xd0a4, 0x0040, 0x4842, 0x2009, 0x07d0, 0x2011, 0x4826,
+       0x1078, 0x596c, 0x0e7e, 0x2071, 0xa300, 0x706b, 0x0000, 0x706f,
+       0x0000, 0x1078, 0x260d, 0x0e7f, 0x0078, 0x4886, 0x157e, 0x0c7e,
+       0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x4501, 0x00c0,
+       0x4880, 0x6000, 0xd0ec, 0x0040, 0x4880, 0x047e, 0x62a0, 0xa294,
+       0x00ff, 0x8227, 0xa006, 0x2009, 0x0029, 0x1078, 0x9ec0, 0x6000,
+       0xc0e5, 0xc0ec, 0x6002, 0x6004, 0xa084, 0x00ff, 0xa085, 0x0700,
+       0x6006, 0x2019, 0x0029, 0x1078, 0x5d53, 0x077e, 0x2039, 0x0000,
+       0x1078, 0x5c78, 0x2009, 0x0000, 0x1078, 0x9c38, 0x077f, 0x047f,
+       0x017f, 0x8108, 0x00f0, 0x4854, 0x0c7f, 0x157f, 0x007c, 0x0c7e,
+       0x6018, 0x2060, 0x6000, 0xc0ec, 0x6002, 0x0c7f, 0x007c, 0x7818,
+       0x2004, 0xd0ac, 0x007c, 0x7818, 0x2004, 0xd0bc, 0x007c, 0x0f7e,
+       0x2001, 0xa4b2, 0x2004, 0xa07d, 0x0040, 0x48a0, 0x7800, 0xd0ec,
+       0x0f7f, 0x007c, 0x127e, 0x027e, 0x2091, 0x8000, 0x6200, 0xa005,
+       0x0040, 0x48ad, 0xc2fd, 0x0078, 0x48ae, 0xc2fc, 0x6202, 0x027f,
+       0x127f, 0x007c, 0x2071, 0xa413, 0x7003, 0x0001, 0x7007, 0x0000,
+       0x7013, 0x0000, 0x7017, 0x0000, 0x701b, 0x0000, 0x701f, 0x0000,
+       0x700b, 0x0000, 0x704b, 0x0001, 0x704f, 0x0000, 0x705b, 0x0020,
+       0x705f, 0x0040, 0x707f, 0x0000, 0x2071, 0xa57c, 0x7003, 0xa413,
+       0x7007, 0x0000, 0x700b, 0x0000, 0x700f, 0xa55c, 0x7013, 0x0020,
+       0x7017, 0x0040, 0x7037, 0x0000, 0x007c, 0x017e, 0x0e7e, 0x2071,
+       0xa534, 0xa00e, 0x7186, 0x718a, 0x7097, 0x0001, 0x2001, 0xa352,
+       0x2004, 0xd0fc, 0x00c0, 0x48f7, 0x2001, 0xa352, 0x2004, 0xa00e,
+       0xd09c, 0x0040, 0x48f4, 0x8108, 0x7102, 0x0078, 0x494a, 0x2001,
+       0xa371, 0x200c, 0xa184, 0x000f, 0x2009, 0xa372, 0x210c, 0x0079,
+       0x4901, 0x48ec, 0x4922, 0x492a, 0x4935, 0x493b, 0x48ec, 0x48ec,
+       0x48ec, 0x4911, 0x48ec, 0x48ec, 0x48ec, 0x48ec, 0x48ec, 0x48ec,
+       0x48ec, 0x7003, 0x0004, 0x137e, 0x147e, 0x157e, 0x2099, 0xa375,
+       0x20a1, 0xa585, 0x20a9, 0x0004, 0x53a3, 0x157f, 0x147f, 0x137f,
+       0x0078, 0x494a, 0x708f, 0x0005, 0x7007, 0x0122, 0x2001, 0x0002,
+       0x0078, 0x4930, 0x708f, 0x0002, 0x7007, 0x0121, 0x2001, 0x0003,
+       0x7002, 0x7097, 0x0001, 0x0078, 0x4947, 0x7007, 0x0122, 0x2001,
+       0x0002, 0x0078, 0x493f, 0x7007, 0x0121, 0x2001, 0x0003, 0x7002,
+       0xa006, 0x7096, 0x708e, 0xa184, 0xff00, 0x8007, 0x709a, 0xa184,
+       0x00ff, 0x7092, 0x0e7f, 0x017f, 0x007c, 0x0e7e, 0x2071, 0xa413,
+       0x684c, 0xa005, 0x00c0, 0x495b, 0x7028, 0xc085, 0x702a, 0xa085,
+       0x0001, 0x0078, 0x4980, 0x6a60, 0x7236, 0x6b64, 0x733a, 0x6868,
+       0x703e, 0x7076, 0x686c, 0x7042, 0x707a, 0x684c, 0x702e, 0x6844,
+       0x7032, 0x2009, 0x000d, 0x200a, 0x700b, 0x0000, 0x8007, 0x8006,
+       0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, 0xa319,
+       0x726e, 0x7372, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0xa006,
+       0x0e7f, 0x007c, 0x0e7e, 0x027e, 0x6838, 0xd0fc, 0x00c0, 0x49d8,
+       0x6804, 0xa00d, 0x0040, 0x499e, 0x0d7e, 0x2071, 0xa300, 0xa016,
+       0x702c, 0x2168, 0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff, 0x00c0,
+       0x4991, 0x702e, 0x70a8, 0xa200, 0x70aa, 0x0d7f, 0x2071, 0xa413,
+       0x701c, 0xa005, 0x00c0, 0x49ea, 0x0068, 0x49e8, 0x2071, 0xa534,
+       0x7200, 0x82ff, 0x0040, 0x49e8, 0x6934, 0xa186, 0x0103, 0x00c0,
+       0x49fb, 0x6948, 0x6844, 0xa105, 0x00c0, 0x49db, 0x2009, 0x8020,
+       0x2200, 0x0079, 0x49bb, 0x49e8, 0x49c0, 0x4a18, 0x4a26, 0x49e8,
+       0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x49e8, 0x7122, 0x683c,
+       0x7026, 0x6840, 0x702a, 0x701b, 0x0001, 0x2091, 0x4080, 0x2071,
+       0xa300, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70a8, 0x8000, 0x70aa,
+       0x027f, 0x0e7f, 0x007c, 0x6844, 0xa086, 0x0100, 0x00c0, 0x49e8,
+       0x6868, 0xa005, 0x00c0, 0x49e8, 0x2009, 0x8020, 0x0078, 0x49b8,
+       0x2071, 0xa413, 0x2d08, 0x206b, 0x0000, 0x7010, 0x8000, 0x7012,
+       0x7018, 0xa06d, 0x711a, 0x0040, 0x49f8, 0x6902, 0x0078, 0x49f9,
+       0x711e, 0x0078, 0x49d8, 0xa18c, 0x00ff, 0xa186, 0x0017, 0x0040,
+       0x4a09, 0xa186, 0x001e, 0x0040, 0x4a09, 0xa18e, 0x001f, 0x00c0,
+       0x49e8, 0x684c, 0xd0cc, 0x0040, 0x49e8, 0x6850, 0xa084, 0x00ff,
+       0xa086, 0x0001, 0x00c0, 0x49e8, 0x2009, 0x8021, 0x0078, 0x49b8,
+       0x7084, 0x8008, 0xa092, 0x001e, 0x00c8, 0x49e8, 0x7186, 0xae90,
+       0x0003, 0xa210, 0x683c, 0x2012, 0x0078, 0x4a36, 0x7084, 0x8008,
+       0xa092, 0x000f, 0x00c8, 0x49e8, 0x7186, 0xae90, 0x0003, 0x8003,
+       0xa210, 0x683c, 0x2012, 0x8210, 0x6840, 0x2012, 0x7088, 0xa10a,
+       0x0048, 0x49cf, 0x718c, 0x7084, 0xa10a, 0x0048, 0x49cf, 0x2071,
+       0x0000, 0x7018, 0xd084, 0x00c0, 0x49cf, 0x2071, 0xa534, 0x7000,
+       0xa086, 0x0002, 0x00c0, 0x4a56, 0x1078, 0x4cd2, 0x2071, 0x0000,
+       0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x49cf, 0x1078, 0x4cfd,
+       0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x49cf,
+       0x007e, 0x684c, 0x007e, 0x6837, 0x0103, 0x20a9, 0x001c, 0xad80,
+       0x0011, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x007f, 0xa084, 0x00ff,
+       0x684e, 0x007f, 0x684a, 0x6952, 0x007c, 0x2071, 0xa413, 0x7004,
+       0x0079, 0x4a7a, 0x4a84, 0x4a95, 0x4ca3, 0x4ca4, 0x4ccb, 0x4cd1,
+       0x4a85, 0x4c91, 0x4c32, 0x4cb4, 0x007c, 0x127e, 0x2091, 0x8000,
+       0x0068, 0x4a94, 0x2009, 0x000d, 0x7030, 0x200a, 0x2091, 0x4080,
+       0x7007, 0x0001, 0x700b, 0x0000, 0x127f, 0x2069, 0xa5be, 0x6844,
+       0xa005, 0x0050, 0x4abd, 0x00c0, 0x4abd, 0x127e, 0x2091, 0x8000,
+       0x2069, 0x0000, 0x6934, 0x2001, 0xa41f, 0x2004, 0xa10a, 0x0040,
+       0x4ab8, 0x0068, 0x4abc, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0,
+       0x4abc, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091, 0x4080,
+       0x2069, 0xa5be, 0x6847, 0xffff, 0x127f, 0x2069, 0xa300, 0x6844,
+       0x6960, 0xa102, 0x2069, 0xa534, 0x688a, 0x6984, 0x701c, 0xa06d,
+       0x0040, 0x4acf, 0x81ff, 0x0040, 0x4b17, 0x0078, 0x4ae5, 0x81ff,
+       0x0040, 0x4be9, 0x2071, 0xa534, 0x7184, 0x7088, 0xa10a, 0x00c8,
+       0x4ae5, 0x7190, 0x2071, 0xa5be, 0x7040, 0xa005, 0x0040, 0x4ae5,
+       0x00d0, 0x4be9, 0x7142, 0x0078, 0x4be9, 0x2071, 0xa534, 0x718c,
+       0x127e, 0x2091, 0x8000, 0x7084, 0xa10a, 0x0048, 0x4c06, 0x0068,
+       0x4b9b, 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x4b9b, 0x2001,
+       0xffff, 0x2071, 0xa5be, 0x7042, 0x2071, 0xa534, 0x7000, 0xa086,
+       0x0002, 0x00c0, 0x4b0d, 0x1078, 0x4cd2, 0x2071, 0x0000, 0x701b,
+       0x0001, 0x2091, 0x4080, 0x0078, 0x4b9b, 0x1078, 0x4cfd, 0x2071,
+       0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x4b9b, 0x2071,
+       0xa534, 0x7000, 0xa005, 0x0040, 0x4bc8, 0x6934, 0xa186, 0x0103,
+       0x00c0, 0x4b9e, 0x684c, 0xd0bc, 0x00c0, 0x4bc8, 0x6948, 0x6844,
+       0xa105, 0x00c0, 0x4bbb, 0x2009, 0x8020, 0x2071, 0xa534, 0x7000,
+       0x0079, 0x4b32, 0x4bc8, 0x4b80, 0x4b58, 0x4b6a, 0x4b37, 0x137e,
+       0x147e, 0x157e, 0x2099, 0xa375, 0x20a1, 0xa585, 0x20a9, 0x0004,
+       0x53a3, 0x157f, 0x147f, 0x137f, 0x2071, 0xa57c, 0xad80, 0x000f,
+       0x700e, 0x7013, 0x0002, 0x7007, 0x0002, 0x700b, 0x0000, 0x2e10,
+       0x1078, 0x13d1, 0x2071, 0xa413, 0x7007, 0x0009, 0x0078, 0x4be9,
+       0x7084, 0x8008, 0xa092, 0x001e, 0x00c8, 0x4be9, 0xae90, 0x0003,
+       0xa210, 0x683c, 0x2012, 0x7186, 0x2071, 0xa413, 0x1078, 0x4d5b,
+       0x0078, 0x4be9, 0x7084, 0x8008, 0xa092, 0x000f, 0x00c8, 0x4be9,
+       0xae90, 0x0003, 0x8003, 0xa210, 0x683c, 0x2012, 0x8210, 0x6840,
+       0x2012, 0x7186, 0x2071, 0xa413, 0x1078, 0x4d5b, 0x0078, 0x4be9,
+       0x127e, 0x2091, 0x8000, 0x0068, 0x4b9b, 0x2071, 0x0000, 0x7018,
+       0xd084, 0x00c0, 0x4b9b, 0x7122, 0x683c, 0x7026, 0x6840, 0x702a,
+       0x701b, 0x0001, 0x2091, 0x4080, 0x127f, 0x2071, 0xa413, 0x1078,
+       0x4d5b, 0x0078, 0x4be9, 0x127f, 0x0078, 0x4be9, 0xa18c, 0x00ff,
+       0xa186, 0x0017, 0x0040, 0x4bac, 0xa186, 0x001e, 0x0040, 0x4bac,
+       0xa18e, 0x001f, 0x00c0, 0x4bc8, 0x684c, 0xd0cc, 0x0040, 0x4bc8,
+       0x6850, 0xa084, 0x00ff, 0xa086, 0x0001, 0x00c0, 0x4bc8, 0x2009,
+       0x8021, 0x0078, 0x4b2d, 0x6844, 0xa086, 0x0100, 0x00c0, 0x4bc8,
+       0x6868, 0xa005, 0x00c0, 0x4bc8, 0x2009, 0x8020, 0x0078, 0x4b2d,
+       0x2071, 0xa413, 0x1078, 0x4d6f, 0x0040, 0x4be9, 0x2071, 0xa413,
+       0x700f, 0x0001, 0x6934, 0xa184, 0x00ff, 0xa086, 0x0003, 0x00c0,
+       0x4be0, 0x810f, 0xa18c, 0x00ff, 0x8101, 0x0040, 0x4be0, 0x710e,
+       0x7007, 0x0003, 0x1078, 0x4d8f, 0x7050, 0xa086, 0x0100, 0x0040,
+       0x4ca4, 0x127e, 0x2091, 0x8000, 0x2071, 0xa413, 0x7008, 0xa086,
+       0x0001, 0x00c0, 0x4c04, 0x0068, 0x4c04, 0x2009, 0x000d, 0x7030,
+       0x200a, 0x2091, 0x4080, 0x700b, 0x0000, 0x7004, 0xa086, 0x0006,
+       0x00c0, 0x4c04, 0x7007, 0x0001, 0x127f, 0x007c, 0x2071, 0xa413,
+       0x1078, 0x4d6f, 0x0040, 0x4c2f, 0x2071, 0xa534, 0x7084, 0x700a,
+       0x20a9, 0x0020, 0x2099, 0xa535, 0x20a1, 0xa55c, 0x53a3, 0x7087,
+       0x0000, 0x2071, 0xa413, 0x2069, 0xa57c, 0x706c, 0x6826, 0x7070,
+       0x682a, 0x7074, 0x682e, 0x7078, 0x6832, 0x2d10, 0x1078, 0x13d1,
+       0x7007, 0x0008, 0x2001, 0xffff, 0x2071, 0xa5be, 0x7042, 0x127f,
+       0x0078, 0x4be9, 0x2069, 0xa57c, 0x6808, 0xa08e, 0x0000, 0x0040,
+       0x4c90, 0xa08e, 0x0200, 0x0040, 0x4c8e, 0xa08e, 0x0100, 0x00c0,
+       0x4c90, 0x127e, 0x2091, 0x8000, 0x0068, 0x4c8b, 0x2069, 0x0000,
+       0x6818, 0xd084, 0x00c0, 0x4c8b, 0x702c, 0x7130, 0x8108, 0xa102,
+       0x0048, 0x4c59, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072, 0x0078,
+       0x4c63, 0x706c, 0xa080, 0x0040, 0x706e, 0x00c8, 0x4c63, 0x7070,
+       0xa081, 0x0000, 0x7072, 0x7132, 0x6936, 0x700b, 0x0000, 0x2001,
+       0xa559, 0x2004, 0xa005, 0x00c0, 0x4c82, 0x6934, 0x2069, 0xa534,
+       0x689c, 0x699e, 0x2069, 0xa5be, 0xa102, 0x00c0, 0x4c7b, 0x6844,
+       0xa005, 0x00d0, 0x4c89, 0x2001, 0xa55a, 0x200c, 0x810d, 0x6946,
+       0x0078, 0x4c89, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091,
+       0x4080, 0x7007, 0x0001, 0x127f, 0x0078, 0x4c90, 0x7007, 0x0005,
+       0x007c, 0x701c, 0xa06d, 0x0040, 0x4ca2, 0x1078, 0x4d6f, 0x0040,
+       0x4ca2, 0x7007, 0x0003, 0x1078, 0x4d8f, 0x7050, 0xa086, 0x0100,
+       0x0040, 0x4ca4, 0x007c, 0x007c, 0x7050, 0xa09e, 0x0100, 0x00c0,
+       0x4cad, 0x7007, 0x0004, 0x0078, 0x4ccb, 0xa086, 0x0200, 0x00c0,
+       0x4cb3, 0x7007, 0x0005, 0x007c, 0x2001, 0xa57e, 0x2004, 0xa08e,
+       0x0100, 0x00c0, 0x4cc0, 0x7007, 0x0001, 0x1078, 0x4d5b, 0x007c,
+       0xa08e, 0x0000, 0x0040, 0x4cbf, 0xa08e, 0x0200, 0x00c0, 0x4cbf,
+       0x7007, 0x0005, 0x007c, 0x1078, 0x4d25, 0x7006, 0x1078, 0x4d5b,
+       0x007c, 0x007c, 0x0e7e, 0x157e, 0x2071, 0xa534, 0x7184, 0x81ff,
+       0x0040, 0x4cfa, 0xa006, 0x7086, 0xae80, 0x0003, 0x2071, 0x0000,
+       0x21a8, 0x2014, 0x7226, 0x8000, 0x0070, 0x4cf7, 0x2014, 0x722a,
+       0x8000, 0x0070, 0x4cf7, 0x2014, 0x722e, 0x8000, 0x0070, 0x4cf7,
+       0x2014, 0x723a, 0x8000, 0x0070, 0x4cf7, 0x2014, 0x723e, 0xa180,
+       0x8030, 0x7022, 0x157f, 0x0e7f, 0x007c, 0x0e7e, 0x157e, 0x2071,
+       0xa534, 0x7184, 0x81ff, 0x0040, 0x4d22, 0xa006, 0x7086, 0xae80,
+       0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, 0x7226, 0x8000, 0x2014,
+       0x722a, 0x8000, 0x0070, 0x4d1b, 0x2014, 0x723a, 0x8000, 0x2014,
+       0x723e, 0x0078, 0x4d1f, 0x2001, 0x8020, 0x0078, 0x4d21, 0x2001,
+       0x8042, 0x7022, 0x157f, 0x0e7f, 0x007c, 0x702c, 0x7130, 0x8108,
+       0xa102, 0x0048, 0x4d32, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072,
+       0x0078, 0x4d3c, 0x706c, 0xa080, 0x0040, 0x706e, 0x00c8, 0x4d3c,
+       0x7070, 0xa081, 0x0000, 0x7072, 0x7132, 0x700c, 0x8001, 0x700e,
+       0x00c0, 0x4d52, 0x127e, 0x2091, 0x8000, 0x0068, 0x4d55, 0x2001,
+       0x000d, 0x2102, 0x2091, 0x4080, 0x2001, 0x0001, 0x700b, 0x0000,
+       0x127f, 0x007c, 0x2001, 0x0007, 0x007c, 0x2001, 0x0006, 0x700b,
+       0x0001, 0x127f, 0x007c, 0x701c, 0xa06d, 0x0040, 0x4d6e, 0x127e,
+       0x2091, 0x8000, 0x7010, 0x8001, 0x7012, 0x2d04, 0x701e, 0xa005,
+       0x00c0, 0x4d6b, 0x701a, 0x127f, 0x1078, 0x139a, 0x007c, 0x2019,
+       0x000d, 0x2304, 0x230c, 0xa10e, 0x0040, 0x4d7e, 0x2304, 0x230c,
+       0xa10e, 0x0040, 0x4d7e, 0xa006, 0x0078, 0x4d8e, 0x732c, 0x8319,
+       0x7130, 0xa102, 0x00c0, 0x4d88, 0x2300, 0xa005, 0x0078, 0x4d8e,
+       0x0048, 0x4d8d, 0xa302, 0x0078, 0x4d8e, 0x8002, 0x007c, 0x2d00,
+       0x7026, 0xa080, 0x000d, 0x7056, 0x7053, 0x0000, 0x127e, 0x2091,
+       0x8000, 0x2009, 0xa5d0, 0x2104, 0xc08d, 0x200a, 0x127f, 0x1078,
+       0x13eb, 0x007c, 0x2071, 0xa3e1, 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, 0xa3e1,
+       0x6848, 0xa005, 0x00c0, 0x4dcb, 0x7028, 0xc085, 0x702a, 0xa085,
+       0x0001, 0x0078, 0x4df0, 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, 0xa3e1, 0x7004, 0x1079, 0x4e50,
+       0x700c, 0x0079, 0x4dfb, 0x4e00, 0x4df5, 0x4df5, 0x4df5, 0x4df5,
+       0x007c, 0x700c, 0x0079, 0x4e04, 0x4e09, 0x4e4e, 0x4e4e, 0x4e4f,
+       0x4e4f, 0x7830, 0x7930, 0xa106, 0x0040, 0x4e13, 0x7830, 0x7930,
+       0xa106, 0x00c0, 0x4e39, 0x7030, 0xa10a, 0x0040, 0x4e39, 0x00c8,
+       0x4e1b, 0x712c, 0xa10a, 0xa18a, 0x0002, 0x00c8, 0x4e3a, 0x1078,
+       0x1366, 0x0040, 0x4e39, 0x2d00, 0x705a, 0x7063, 0x0040, 0x2001,
+       0x0003, 0x7057, 0x0000, 0x127e, 0x007e, 0x2091, 0x8000, 0x2009,
+       0xa5d0, 0x2104, 0xc085, 0x200a, 0x007f, 0x700e, 0x127f, 0x1078,
+       0x13eb, 0x007c, 0x1078, 0x1366, 0x0040, 0x4e39, 0x2d00, 0x705a,
+       0x1078, 0x1366, 0x00c0, 0x4e46, 0x0078, 0x4e25, 0x2d00, 0x7086,
+       0x7063, 0x0080, 0x2001, 0x0004, 0x0078, 0x4e29, 0x007c, 0x007c,
+       0x4e61, 0x4e62, 0x4e99, 0x4e9a, 0x4e4e, 0x4ed0, 0x4ed5, 0x4f0c,
+       0x4f0d, 0x4f28, 0x4f29, 0x4f2a, 0x4f2b, 0x4f2c, 0x4f2d, 0x4fad,
+       0x4fd7, 0x007c, 0x700c, 0x0079, 0x4e65, 0x4e6a, 0x4e6d, 0x4e7d,
+       0x4e98, 0x4e98, 0x1078, 0x4e01, 0x007c, 0x127e, 0x8001, 0x700e,
+       0x7058, 0x007e, 0x1078, 0x5348, 0x0040, 0x4e7a, 0x2091, 0x8000,
+       0x1078, 0x4e01, 0x0d7f, 0x0078, 0x4e86, 0x127e, 0x8001, 0x700e,
+       0x1078, 0x5348, 0x7058, 0x2068, 0x7084, 0x705a, 0x6803, 0x0000,
+       0x6807, 0x0000, 0x6834, 0xa084, 0x00ff, 0xa08a, 0x0020, 0x00c8,
+       0x4e95, 0x1079, 0x4eb0, 0x127f, 0x007c, 0x127f, 0x1078, 0x4f2e,
+       0x007c, 0x007c, 0x007c, 0x0e7e, 0x2071, 0xa3e1, 0x700c, 0x0079,
+       0x4ea1, 0x4ea6, 0x4ea6, 0x4ea6, 0x4ea8, 0x4eac, 0x0e7f, 0x007c,
+       0x700f, 0x0001, 0x0078, 0x4eae, 0x700f, 0x0002, 0x0e7f, 0x007c,
+       0x4f2e, 0x4f2e, 0x4f4a, 0x4f2e, 0x5080, 0x4f2e, 0x4f2e, 0x4f2e,
+       0x4f2e, 0x4f2e, 0x4f4a, 0x50ca, 0x5117, 0x5170, 0x5186, 0x4f2e,
+       0x4f2e, 0x4f66, 0x4f4a, 0x4f2e, 0x4f2e, 0x4f87, 0x5245, 0x5263,
+       0x4f2e, 0x4f66, 0x4f2e, 0x4f2e, 0x4f2e, 0x4f2e, 0x4f7c, 0x5263,
+       0x7020, 0x2068, 0x1078, 0x139a, 0x007c, 0x700c, 0x0079, 0x4ed8,
+       0x4edd, 0x4ee0, 0x4ef0, 0x4f0b, 0x4f0b, 0x1078, 0x4e01, 0x007c,
+       0x127e, 0x8001, 0x700e, 0x7058, 0x007e, 0x1078, 0x5348, 0x0040,
+       0x4eed, 0x2091, 0x8000, 0x1078, 0x4e01, 0x0d7f, 0x0078, 0x4ef9,
+       0x127e, 0x8001, 0x700e, 0x1078, 0x5348, 0x7058, 0x2068, 0x7084,
+       0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834, 0xa084, 0x00ff,
+       0xa08a, 0x001a, 0x00c8, 0x4f08, 0x1079, 0x4f0e, 0x127f, 0x007c,
+       0x127f, 0x1078, 0x4f2e, 0x007c, 0x007c, 0x007c, 0x4f2e, 0x4f4a,
+       0x506a, 0x4f2e, 0x4f4a, 0x4f2e, 0x4f4a, 0x4f4a, 0x4f2e, 0x4f4a,
+       0x506a, 0x4f4a, 0x4f4a, 0x4f4a, 0x4f4a, 0x4f4a, 0x4f2e, 0x4f4a,
+       0x506a, 0x4f2e, 0x4f2e, 0x4f4a, 0x4f2e, 0x4f2e, 0x4f2e, 0x4f4a,
+       0x007c, 0x007c, 0x007c, 0x007c, 0x007c, 0x007c, 0x7007, 0x0001,
+       0x6838, 0xa084, 0x00ff, 0xc0d5, 0x683a, 0x127e, 0x2091, 0x8000,
+       0x1078, 0x4982, 0x127f, 0x007c, 0x7007, 0x0001, 0x6838, 0xa084,
+       0x00ff, 0xc0e5, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x4982,
+       0x127f, 0x007c, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0ed,
+       0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x4982, 0x127f, 0x007c,
+       0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0dd, 0x683a, 0x127e,
+       0x2091, 0x8000, 0x1078, 0x4982, 0x127f, 0x007c, 0x6834, 0x8007,
+       0xa084, 0x00ff, 0x0040, 0x4f3c, 0x8001, 0x00c0, 0x4f73, 0x7007,
+       0x0001, 0x0078, 0x5049, 0x7007, 0x0006, 0x7012, 0x2d00, 0x7016,
+       0x701a, 0x704b, 0x5049, 0x007c, 0x684c, 0xa084, 0x00c0, 0xa086,
+       0x00c0, 0x00c0, 0x4f87, 0x7007, 0x0001, 0x0078, 0x5280, 0x2d00,
+       0x7016, 0x701a, 0x20a9, 0x0004, 0xa080, 0x0024, 0x2098, 0x20a1,
+       0xa40c, 0x53a3, 0x6858, 0x7012, 0xa082, 0x0401, 0x00c8, 0x4f58,
+       0x6884, 0xa08a, 0x0002, 0x00c8, 0x4f58, 0x82ff, 0x00c0, 0x4fa9,
+       0x6888, 0x698c, 0xa105, 0x0040, 0x4fa9, 0x2001, 0x5019, 0x0078,
+       0x4fac, 0xa280, 0x500f, 0x2004, 0x70c6, 0x7010, 0xa015, 0x0040,
+       0x4ff7, 0x1078, 0x1366, 0x00c0, 0x4fb8, 0x7007, 0x000f, 0x007c,
+       0x2d00, 0x7022, 0x70c4, 0x2060, 0x6000, 0x6836, 0x6004, 0xad00,
+       0x7096, 0x6008, 0xa20a, 0x00c8, 0x4fc7, 0xa00e, 0x2200, 0x7112,
+       0x620c, 0x8003, 0x800b, 0xa296, 0x0004, 0x0040, 0x4fd0, 0xa108,
+       0x719a, 0x810b, 0x719e, 0xae90, 0x0022, 0x1078, 0x13d1, 0x7090,
+       0xa08e, 0x0100, 0x0040, 0x4feb, 0xa086, 0x0200, 0x0040, 0x4fe3,
+       0x7007, 0x0010, 0x007c, 0x7020, 0x2068, 0x1078, 0x139a, 0x7014,
+       0x2068, 0x0078, 0x4f58, 0x7020, 0x2068, 0x7018, 0x6802, 0x6807,
+       0x0000, 0x2d08, 0x2068, 0x6906, 0x711a, 0x0078, 0x4fad, 0x7014,
+       0x2068, 0x7007, 0x0001, 0x6884, 0xa005, 0x00c0, 0x5006, 0x6888,
+       0x698c, 0xa105, 0x0040, 0x5006, 0x1078, 0x501d, 0x6834, 0xa084,
+       0x00ff, 0xa086, 0x001e, 0x0040, 0x5280, 0x0078, 0x5049, 0x5011,
+       0x5015, 0x0002, 0x0011, 0x0007, 0x0004, 0x000a, 0x000f, 0x0005,
+       0x0006, 0x000a, 0x0011, 0x0005, 0x0004, 0x0f7e, 0x0e7e, 0x0c7e,
+       0x077e, 0x067e, 0x6f88, 0x6e8c, 0x6804, 0x2060, 0xacf0, 0x0021,
+       0xacf8, 0x0027, 0x2009, 0x0005, 0x700c, 0x7816, 0x7008, 0x7812,
+       0x7004, 0x7806, 0x7000, 0x7802, 0x7e0e, 0x7f0a, 0x8109, 0x0040,
+       0x503f, 0xaef2, 0x0004, 0xaffa, 0x0006, 0x0078, 0x502c, 0x6004,
+       0xa065, 0x00c0, 0x5026, 0x067f, 0x077f, 0x0c7f, 0x0e7f, 0x0f7f,
+       0x007c, 0x2009, 0xa32e, 0x210c, 0x81ff, 0x00c0, 0x5064, 0x6838,
+       0xa084, 0x00ff, 0x683a, 0x1078, 0x4290, 0x00c0, 0x5058, 0x007c,
+       0x1078, 0x4a60, 0x127e, 0x2091, 0x8000, 0x1078, 0x8cb8, 0x1078,
+       0x4982, 0x127f, 0x0078, 0x5057, 0x2001, 0x0028, 0x2009, 0x0000,
+       0x0078, 0x5058, 0x7018, 0x6802, 0x2d08, 0x2068, 0x6906, 0x711a,
+       0x7010, 0x8001, 0x7012, 0x0040, 0x5079, 0x7007, 0x0006, 0x0078,
+       0x507f, 0x7014, 0x2068, 0x7007, 0x0001, 0x7048, 0x107a, 0x007c,
+       0x7007, 0x0001, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x6848, 0xa084,
+       0x00ff, 0x20a9, 0x0001, 0xa096, 0x0001, 0x0040, 0x50a9, 0x2009,
+       0x0000, 0x20a9, 0x00ff, 0xa096, 0x0002, 0x0040, 0x50a9, 0xa005,
+       0x00c0, 0x50bc, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x1078, 0x4501,
+       0x00c0, 0x50bc, 0x067e, 0x6e50, 0x1078, 0x45e7, 0x067f, 0x0078,
+       0x50bc, 0x047e, 0x2011, 0xa30c, 0x2224, 0xc484, 0xc48c, 0x2412,
+       0x047f, 0x0c7e, 0x1078, 0x4501, 0x00c0, 0x50b8, 0x1078, 0x4782,
+       0x8108, 0x00f0, 0x50b2, 0x0c7f, 0x684c, 0xd084, 0x00c0, 0x50c3,
+       0x1078, 0x139a, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x4982,
+       0x127f, 0x007c, 0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001,
+       0xa352, 0x2004, 0xd0a4, 0x0040, 0x510e, 0x2061, 0xa62d, 0x6100,
+       0xd184, 0x0040, 0x50ee, 0x6858, 0xa084, 0x00ff, 0x00c0, 0x5111,
+       0x6000, 0xd084, 0x0040, 0x510e, 0x6004, 0xa005, 0x00c0, 0x5114,
+       0x6003, 0x0000, 0x600b, 0x0000, 0x0078, 0x510b, 0x2011, 0x0001,
+       0x6860, 0xa005, 0x00c0, 0x50f6, 0x2001, 0x001e, 0x8000, 0x6016,
+       0x6858, 0xa084, 0x00ff, 0x0040, 0x510e, 0x6006, 0x6858, 0x8007,
+       0xa084, 0x00ff, 0x0040, 0x510e, 0x600a, 0x6858, 0x8000, 0x00c0,
+       0x510a, 0xc28d, 0x6202, 0x127f, 0x0078, 0x5337, 0x127f, 0x0078,
+       0x532f, 0x127f, 0x0078, 0x5327, 0x127f, 0x0078, 0x532b, 0x127e,
+       0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0xa352, 0x2004, 0xd0a4,
+       0x0040, 0x516d, 0x2061, 0xa62d, 0x6000, 0xd084, 0x0040, 0x516d,
+       0x6204, 0x6308, 0xd08c, 0x00c0, 0x515f, 0x6c48, 0xa484, 0x0003,
+       0x0040, 0x5145, 0x6958, 0xa18c, 0x00ff, 0x8001, 0x00c0, 0x513e,
+       0x2100, 0xa210, 0x0048, 0x516a, 0x0078, 0x5145, 0x8001, 0x00c0,
+       0x516a, 0x2100, 0xa212, 0x0048, 0x516a, 0xa484, 0x000c, 0x0040,
+       0x515f, 0x6958, 0x810f, 0xa18c, 0x00ff, 0xa082, 0x0004, 0x00c0,
+       0x5157, 0x2100, 0xa318, 0x0048, 0x516a, 0x0078, 0x515f, 0xa082,
+       0x0004, 0x00c0, 0x516a, 0x2100, 0xa31a, 0x0048, 0x516a, 0x6860,
+       0xa005, 0x0040, 0x5165, 0x8000, 0x6016, 0x6206, 0x630a, 0x127f,
+       0x0078, 0x5337, 0x127f, 0x0078, 0x5333, 0x127f, 0x0078, 0x532f,
+       0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061, 0xa62d, 0x6300,
+       0xd38c, 0x00c0, 0x5180, 0x6308, 0x8318, 0x0048, 0x5183, 0x630a,
+       0x127f, 0x0078, 0x5345, 0x127f, 0x0078, 0x5333, 0x127e, 0x0c7e,
+       0x2091, 0x8000, 0x7007, 0x0001, 0x684c, 0xd0ac, 0x0040, 0x519a,
+       0x0c7e, 0x2061, 0xa62d, 0x6000, 0xa084, 0xfcff, 0x6002, 0x0c7f,
+       0x0078, 0x51c9, 0x6858, 0xa005, 0x0040, 0x51e0, 0x685c, 0xa065,
+       0x0040, 0x51dc, 0x2001, 0xa32e, 0x2004, 0xa005, 0x0040, 0x51ac,
+       0x1078, 0x8c01, 0x0078, 0x51ba, 0x6013, 0x0400, 0x6037, 0x0000,
+       0x694c, 0xd1a4, 0x0040, 0x51b6, 0x6950, 0x6136, 0x2009, 0x0041,
+       0x1078, 0x756c, 0x6958, 0xa18c, 0xff00, 0xa186, 0x2000, 0x00c0,
+       0x51c9, 0x027e, 0x2009, 0x0000, 0x2011, 0xfdff, 0x1078, 0x5a6d,
+       0x027f, 0x684c, 0xd0c4, 0x0040, 0x51d8, 0x2061, 0xa62d, 0x6000,
+       0xd08c, 0x00c0, 0x51d8, 0x6008, 0x8000, 0x0048, 0x51dc, 0x600a,
+       0x0c7f, 0x127f, 0x0078, 0x5337, 0x0c7f, 0x127f, 0x0078, 0x532f,
+       0x6954, 0xa186, 0x0045, 0x0040, 0x5213, 0xa186, 0x002a, 0x00c0,
+       0x51f0, 0x2001, 0xa30c, 0x200c, 0xc194, 0x2102, 0x0078, 0x51c9,
+       0xa186, 0x0020, 0x0040, 0x5209, 0xa186, 0x0029, 0x0040, 0x51fc,
+       0xa186, 0x002d, 0x00c0, 0x51dc, 0x6944, 0xa18c, 0xff00, 0x810f,
+       0x1078, 0x4501, 0x00c0, 0x51c9, 0x6000, 0xc0e4, 0x6002, 0x0078,
+       0x51c9, 0x685c, 0xa065, 0x0040, 0x51dc, 0x2001, 0xa5a1, 0x2004,
+       0x6016, 0x0078, 0x51c9, 0x685c, 0xa065, 0x0040, 0x51dc, 0x0e7e,
+       0x6860, 0xa075, 0x2001, 0xa32e, 0x2004, 0xa005, 0x0040, 0x522b,
+       0x1078, 0x8c01, 0x8eff, 0x0040, 0x5228, 0x2e60, 0x1078, 0x8c01,
+       0x0e7f, 0x0078, 0x51c9, 0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60,
+       0x6007, 0x003a, 0x6870, 0xa005, 0x0040, 0x523c, 0x6007, 0x003b,
+       0x6874, 0x602a, 0x6878, 0x6012, 0x6003, 0x0001, 0x1078, 0x5bf8,
+       0x1078, 0x6109, 0x0e7f, 0x0078, 0x51c9, 0x2061, 0xa62d, 0x6000,
+       0xd084, 0x0040, 0x525f, 0xd08c, 0x00c0, 0x5345, 0x2091, 0x8000,
+       0x6204, 0x8210, 0x0048, 0x5259, 0x6206, 0x2091, 0x8001, 0x0078,
+       0x5345, 0x2091, 0x8001, 0x6853, 0x0016, 0x0078, 0x533e, 0x6853,
+       0x0007, 0x0078, 0x533e, 0x6834, 0x8007, 0xa084, 0x00ff, 0x00c0,
+       0x526d, 0x1078, 0x4f3c, 0x0078, 0x527f, 0x2030, 0x8001, 0x00c0,
+       0x5277, 0x7007, 0x0001, 0x1078, 0x5280, 0x0078, 0x527f, 0x7007,
+       0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x5280, 0x007c,
+       0x0e7e, 0x127e, 0x2091, 0x8000, 0x2009, 0xa32e, 0x210c, 0x81ff,
+       0x00c0, 0x530b, 0x2009, 0xa30c, 0x210c, 0xd194, 0x00c0, 0x5315,
+       0x6848, 0x2070, 0xae82, 0xaa00, 0x0048, 0x52fb, 0x2001, 0xa315,
+       0x2004, 0xae02, 0x00c8, 0x52fb, 0x2061, 0xa62d, 0x6100, 0xa184,
+       0x0301, 0xa086, 0x0001, 0x00c0, 0x52de, 0x711c, 0xa186, 0x0006,
+       0x00c0, 0x52e6, 0x7018, 0xa005, 0x0040, 0x530b, 0x2004, 0xd0e4,
+       0x00c0, 0x530f, 0x7024, 0xd0dc, 0x00c0, 0x5319, 0x6853, 0x0000,
+       0x6803, 0x0000, 0x2d08, 0x7010, 0xa005, 0x00c0, 0x52ca, 0x7112,
+       0x684c, 0xd0f4, 0x00c0, 0x531d, 0x2e60, 0x1078, 0x59b6, 0x127f,
+       0x0e7f, 0x007c, 0x2068, 0x6800, 0xa005, 0x00c0, 0x52ca, 0x6902,
+       0x2168, 0x684c, 0xd0f4, 0x00c0, 0x531d, 0x127f, 0x0e7f, 0x007c,
+       0x127f, 0x0e7f, 0x6853, 0x0006, 0x0078, 0x533e, 0xd184, 0x0040,
+       0x52d8, 0xd1c4, 0x00c0, 0x52ff, 0x0078, 0x5303, 0x6944, 0xa18c,
+       0xff00, 0x810f, 0x1078, 0x4501, 0x00c0, 0x530f, 0x6000, 0xd0e4,
+       0x00c0, 0x530f, 0x711c, 0xa186, 0x0007, 0x00c0, 0x52fb, 0x6853,
+       0x0002, 0x0078, 0x5311, 0x6853, 0x0008, 0x0078, 0x5311, 0x6853,
+       0x000e, 0x0078, 0x5311, 0x6853, 0x0017, 0x0078, 0x5311, 0x6853,
+       0x0035, 0x0078, 0x5311, 0x6853, 0x0028, 0x0078, 0x5311, 0x6853,
+       0x0029, 0x127f, 0x0e7f, 0x0078, 0x533e, 0x6853, 0x002a, 0x0078,
+       0x5311, 0x6853, 0x0045, 0x0078, 0x5311, 0x2e60, 0x2019, 0x0002,
+       0x6017, 0x0014, 0x1078, 0x9a6a, 0x127f, 0x0e7f, 0x007c, 0x2009,
+       0x003e, 0x0078, 0x5339, 0x2009, 0x0004, 0x0078, 0x5339, 0x2009,
+       0x0006, 0x0078, 0x5339, 0x2009, 0x0016, 0x0078, 0x5339, 0x2009,
+       0x0001, 0x6854, 0xa084, 0xff00, 0xa105, 0x6856, 0x2091, 0x8000,
+       0x1078, 0x4982, 0x2091, 0x8001, 0x007c, 0x1078, 0x139a, 0x007c,
+       0x702c, 0x7130, 0x8108, 0xa102, 0x0048, 0x5355, 0xa00e, 0x7034,
+       0x7072, 0x7038, 0x7076, 0x0078, 0x5361, 0x7070, 0xa080, 0x0040,
+       0x7072, 0x00c8, 0x5361, 0x7074, 0xa081, 0x0000, 0x7076, 0xa085,
+       0x0001, 0x7932, 0x7132, 0x007c, 0x0d7e, 0x1078, 0x59ad, 0x0d7f,
+       0x007c, 0x0d7e, 0x2011, 0x0004, 0x2204, 0xa085, 0x8002, 0x2012,
+       0x0d7f, 0x007c, 0x20e1, 0x0002, 0x3d08, 0x20e1, 0x2000, 0x3d00,
+       0xa084, 0x7000, 0x0040, 0x5380, 0xa086, 0x1000, 0x00c0, 0x53ac,
+       0x20e1, 0x0000, 0x3d00, 0xa094, 0xff00, 0x8217, 0xa084, 0xf000,
+       0xa086, 0x3000, 0x00c0, 0x5390, 0x1078, 0x5570, 0x0078, 0x53a7,
+       0x20e1, 0x0004, 0x3d60, 0xd1bc, 0x00c0, 0x5397, 0x3e60, 0xac84,
+       0x000f, 0x00c0, 0x53ac, 0xac82, 0xaa00, 0x0048, 0x53ac, 0x6854,
+       0xac02, 0x00c8, 0x53ac, 0x2009, 0x0047, 0x1078, 0x756c, 0x7a1c,
+       0xd284, 0x00c0, 0x5372, 0x007c, 0xa016, 0x1078, 0x15ec, 0x0078,
+       0x53a7, 0x0078, 0x53ac, 0x781c, 0xd08c, 0x0040, 0x53db, 0x157e,
+       0x137e, 0x147e, 0x20e1, 0x3000, 0x3d20, 0x3e28, 0xa584, 0x0076,
+       0x00c0, 0x53f1, 0xa484, 0x7000, 0xa086, 0x1000, 0x00c0, 0x53e0,
+       0x1078, 0x540c, 0x0040, 0x53f1, 0x20e1, 0x3000, 0x7828, 0x7828,
+       0x1078, 0x542a, 0x147f, 0x137f, 0x157f, 0x2009, 0xa5b3, 0x2104,
+       0xa005, 0x00c0, 0x53dc, 0x007c, 0x1078, 0x6109, 0x0078, 0x53db,
+       0xa484, 0x7000, 0x00c0, 0x53f1, 0x1078, 0x540c, 0x0040, 0x5403,
+       0x7000, 0xa084, 0xff00, 0xa086, 0x8100, 0x0040, 0x53cc, 0x0078,
+       0x5403, 0x1078, 0xa1ee, 0xd5a4, 0x0040, 0x53ff, 0x1078, 0x1af7,
+       0x20e1, 0x9010, 0x2001, 0x0138, 0x2202, 0x0078, 0x5407, 0x1078,
+       0x540c, 0x687f, 0x0000, 0x20e1, 0x3000, 0x7828, 0x7828, 0x147f,
+       0x137f, 0x157f, 0x0078, 0x53db, 0xa484, 0x01ff, 0x687e, 0xa005,
+       0x0040, 0x541e, 0xa080, 0x001f, 0xa084, 0x03f8, 0x80ac, 0x20e1,
+       0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0x007c, 0x20a9, 0x000c,
+       0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0xa085, 0x0001,
+       0x0078, 0x541d, 0x7000, 0xa084, 0xff00, 0xa08c, 0xf000, 0x8007,
+       0xa196, 0x0000, 0x00c0, 0x5437, 0x0078, 0x567c, 0x007c, 0xa196,
+       0x2000, 0x00c0, 0x5448, 0x6900, 0xa18e, 0x0001, 0x00c0, 0x5444,
+       0x1078, 0x3a43, 0x0078, 0x5436, 0x1078, 0x5450, 0x0078, 0x5436,
+       0xa196, 0x8000, 0x00c0, 0x5436, 0x1078, 0x570c, 0x0078, 0x5436,
+       0x0c7e, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa196, 0x0001, 0x0040,
+       0x545d, 0xa196, 0x0023, 0x00c0, 0x5568, 0xa08e, 0x0023, 0x00c0,
+       0x5492, 0x1078, 0x57b2, 0x0040, 0x5568, 0x7124, 0x610a, 0x7030,
+       0xa08e, 0x0200, 0x00c0, 0x5476, 0x7034, 0xa005, 0x00c0, 0x5568,
+       0x2009, 0x0015, 0x1078, 0x756c, 0x0078, 0x5568, 0xa08e, 0x0214,
+       0x0040, 0x547e, 0xa08e, 0x0210, 0x00c0, 0x5484, 0x2009, 0x0015,
+       0x1078, 0x756c, 0x0078, 0x5568, 0xa08e, 0x0100, 0x00c0, 0x5568,
+       0x7034, 0xa005, 0x00c0, 0x5568, 0x2009, 0x0016, 0x1078, 0x756c,
+       0x0078, 0x5568, 0xa08e, 0x0022, 0x00c0, 0x5568, 0x7030, 0xa08e,
+       0x0300, 0x00c0, 0x54a3, 0x7034, 0xa005, 0x00c0, 0x5568, 0x2009,
+       0x0017, 0x0078, 0x5534, 0xa08e, 0x0500, 0x00c0, 0x54af, 0x7034,
+       0xa005, 0x00c0, 0x5568, 0x2009, 0x0018, 0x0078, 0x5534, 0xa08e,
+       0x2010, 0x00c0, 0x54b7, 0x2009, 0x0019, 0x0078, 0x5534, 0xa08e,
+       0x2110, 0x00c0, 0x54bf, 0x2009, 0x001a, 0x0078, 0x5534, 0xa08e,
+       0x5200, 0x00c0, 0x54cb, 0x7034, 0xa005, 0x00c0, 0x5568, 0x2009,
+       0x001b, 0x0078, 0x5534, 0xa08e, 0x5000, 0x00c0, 0x54d7, 0x7034,
+       0xa005, 0x00c0, 0x5568, 0x2009, 0x001c, 0x0078, 0x5534, 0xa08e,
+       0x1300, 0x00c0, 0x54df, 0x2009, 0x0034, 0x0078, 0x5534, 0xa08e,
+       0x1200, 0x00c0, 0x54eb, 0x7034, 0xa005, 0x00c0, 0x5568, 0x2009,
+       0x0024, 0x0078, 0x5534, 0xa08c, 0xff00, 0xa18e, 0x2400, 0x00c0,
+       0x54f5, 0x2009, 0x002d, 0x0078, 0x5534, 0xa08c, 0xff00, 0xa18e,
+       0x5300, 0x00c0, 0x54ff, 0x2009, 0x002a, 0x0078, 0x5534, 0xa08e,
+       0x0f00, 0x00c0, 0x5507, 0x2009, 0x0020, 0x0078, 0x5534, 0xa08e,
+       0x5300, 0x00c0, 0x550d, 0x0078, 0x552a, 0xa08e, 0x6104, 0x00c0,
+       0x552a, 0x2011, 0xa88d, 0x8208, 0x2204, 0xa082, 0x0004, 0x20a8,
+       0x95ac, 0x95ac, 0x2011, 0x8015, 0x211c, 0x8108, 0x047e, 0x2124,
+       0x1078, 0x3579, 0x047f, 0x8108, 0x00f0, 0x551a, 0x2009, 0x0023,
+       0x0078, 0x5534, 0xa08e, 0x6000, 0x00c0, 0x5532, 0x2009, 0x003f,
+       0x0078, 0x5534, 0x2009, 0x001d, 0x017e, 0x2011, 0xa883, 0x2204,
+       0x8211, 0x220c, 0x1078, 0x24e3, 0x00c0, 0x556a, 0x1078, 0x4499,
+       0x00c0, 0x556a, 0x6612, 0x6516, 0x86ff, 0x0040, 0x555a, 0x017f,
+       0x017e, 0xa186, 0x0017, 0x00c0, 0x555a, 0x6868, 0xa606, 0x00c0,
+       0x555a, 0x686c, 0xa506, 0xa084, 0xff00, 0x00c0, 0x555a, 0x6000,
+       0xc0f5, 0x6002, 0x0c7e, 0x1078, 0x74d7, 0x0040, 0x556d, 0x017f,
+       0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0x017f, 0x1078, 0x756c,
+       0x0c7f, 0x007c, 0x017f, 0x0078, 0x5568, 0x0c7f, 0x0078, 0x556a,
+       0x0c7e, 0x1078, 0x55d4, 0x00c0, 0x55d2, 0xa184, 0xff00, 0x8007,
+       0xa086, 0x0008, 0x00c0, 0x55d2, 0xa28e, 0x0033, 0x00c0, 0x55a3,
+       0x1078, 0x57b2, 0x0040, 0x55d2, 0x7124, 0x610a, 0x7030, 0xa08e,
+       0x0200, 0x00c0, 0x5595, 0x7034, 0xa005, 0x00c0, 0x55d2, 0x2009,
+       0x0015, 0x1078, 0x756c, 0x0078, 0x55d2, 0xa08e, 0x0100, 0x00c0,
+       0x55d2, 0x7034, 0xa005, 0x00c0, 0x55d2, 0x2009, 0x0016, 0x1078,
+       0x756c, 0x0078, 0x55d2, 0xa28e, 0x0032, 0x00c0, 0x55d2, 0x7030,
+       0xa08e, 0x1400, 0x00c0, 0x55d2, 0x2009, 0x0038, 0x017e, 0x2011,
+       0xa883, 0x2204, 0x8211, 0x220c, 0x1078, 0x24e3, 0x00c0, 0x55d1,
+       0x1078, 0x4499, 0x00c0, 0x55d1, 0x6612, 0x6516, 0x0c7e, 0x1078,
+       0x74d7, 0x0040, 0x55d0, 0x017f, 0x611a, 0x601f, 0x0004, 0x7120,
+       0x610a, 0x017f, 0x1078, 0x756c, 0x1078, 0x6109, 0x0078, 0x55d2,
+       0x0c7f, 0x017f, 0x0c7f, 0x007c, 0x0f7e, 0x0d7e, 0x027e, 0x017e,
+       0x137e, 0x147e, 0x157e, 0x3c00, 0x007e, 0x2079, 0x0030, 0x2069,
+       0x0200, 0x1078, 0x1c25, 0x00c0, 0x5615, 0x1078, 0x1b15, 0x0040,
+       0x561f, 0x7908, 0xa18c, 0x1fff, 0xa182, 0x0011, 0x00c8, 0x561f,
+       0x20a9, 0x000c, 0x20e1, 0x0000, 0x2ea0, 0x2099, 0x020a, 0x53a5,
+       0x20e1, 0x2000, 0x2001, 0x020a, 0x2004, 0x7a0c, 0x7808, 0xa080,
+       0x0007, 0xa084, 0x1ff8, 0xa08a, 0x0140, 0x10c8, 0x1328, 0x80ac,
+       0x20e1, 0x6000, 0x2099, 0x020a, 0x53a5, 0x20e1, 0x7000, 0x6828,
+       0x6828, 0x7803, 0x0004, 0xa294, 0x0070, 0x007f, 0x20e0, 0x157f,
+       0x147f, 0x137f, 0x017f, 0x027f, 0x0d7f, 0x0f7f, 0x007c, 0xa085,
+       0x0001, 0x0078, 0x5615, 0x047e, 0x0e7e, 0x0d7e, 0x2028, 0x2130,
+       0xa696, 0x00ff, 0x00c0, 0x5644, 0xa596, 0xfffd, 0x00c0, 0x5634,
+       0x2009, 0x007f, 0x0078, 0x5677, 0xa596, 0xfffe, 0x00c0, 0x563c,
+       0x2009, 0x007e, 0x0078, 0x5677, 0xa596, 0xfffc, 0x00c0, 0x5644,
+       0x2009, 0x0080, 0x0078, 0x5677, 0x2011, 0x0000, 0x2021, 0x0081,
+       0x20a9, 0x007e, 0x2071, 0xa4b5, 0x2e1c, 0x83ff, 0x00c0, 0x5656,
+       0x82ff, 0x00c0, 0x566b, 0x2410, 0x0078, 0x566b, 0x2368, 0x6f10,
+       0x007e, 0x2100, 0xa706, 0x007f, 0x6b14, 0x00c0, 0x5665, 0xa346,
+       0x00c0, 0x5665, 0x2408, 0x0078, 0x5677, 0x87ff, 0x00c0, 0x566b,
+       0x83ff, 0x0040, 0x5650, 0x8420, 0x8e70, 0x00f0, 0x564c, 0x82ff,
+       0x00c0, 0x5676, 0xa085, 0x0001, 0x0078, 0x5678, 0x2208, 0xa006,
+       0x0d7f, 0x0e7f, 0x047f, 0x007c, 0xa084, 0x0007, 0x0079, 0x5681,
+       0x007c, 0x5689, 0x5689, 0x5689, 0x57c8, 0x5689, 0x568a, 0x56a3,
+       0x56f3, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x56a2, 0x7120, 0x2160,
+       0xac8c, 0x000f, 0x00c0, 0x56a2, 0xac8a, 0xaa00, 0x0048, 0x56a2,
+       0x6854, 0xac02, 0x00c8, 0x56a2, 0x7124, 0x610a, 0x2009, 0x0046,
+       0x1078, 0x756c, 0x007c, 0x0c7e, 0x7110, 0xd1bc, 0x00c0, 0x56f1,
+       0x2011, 0xa883, 0x2204, 0x8211, 0x220c, 0x1078, 0x24e3, 0x00c0,
+       0x56f1, 0x1078, 0x4499, 0x00c0, 0x56f1, 0x6612, 0x6516, 0x6000,
+       0xd0ec, 0x00c0, 0x56f1, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286,
+       0x0006, 0x00c0, 0x56d6, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040,
+       0x56f1, 0x611a, 0x601f, 0x0006, 0x7120, 0x610a, 0x7130, 0x6122,
+       0x2009, 0x0044, 0x1078, 0x756c, 0x0078, 0x56f1, 0x0c7e, 0x1078,
+       0x74d7, 0x017f, 0x0040, 0x56f1, 0x611a, 0x601f, 0x0004, 0x7120,
+       0x610a, 0xa286, 0x0004, 0x00c0, 0x56e9, 0x6007, 0x0005, 0x0078,
+       0x56eb, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078, 0x5c45, 0x1078,
+       0x6109, 0x0c7f, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x570b, 0x7020,
+       0x2060, 0xac84, 0x000f, 0x00c0, 0x570b, 0xac82, 0xaa00, 0x0048,
+       0x570b, 0x6854, 0xac02, 0x00c8, 0x570b, 0x7124, 0x610a, 0x2009,
+       0x0045, 0x1078, 0x756c, 0x007c, 0x7110, 0xa18c, 0xff00, 0x810f,
+       0xa18e, 0x0000, 0x00c0, 0x571c, 0xa084, 0x000f, 0xa08a, 0x0006,
+       0x00c8, 0x571c, 0x1079, 0x571d, 0x007c, 0x5723, 0x5724, 0x5723,
+       0x5723, 0x5794, 0x57a3, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x572c,
+       0x702c, 0xd084, 0x0040, 0x5793, 0x700c, 0x7108, 0x1078, 0x24e3,
+       0x00c0, 0x5793, 0x1078, 0x4499, 0x00c0, 0x5793, 0x6612, 0x6516,
+       0x6204, 0x7110, 0xd1bc, 0x0040, 0x575e, 0xa28c, 0x00ff, 0xa186,
+       0x0004, 0x0040, 0x5747, 0xa186, 0x0006, 0x00c0, 0x5784, 0x0c7e,
+       0x1078, 0x57b2, 0x0c7f, 0x0040, 0x5793, 0x0c7e, 0x1078, 0x74d7,
+       0x017f, 0x0040, 0x5793, 0x611a, 0x601f, 0x0002, 0x7120, 0x610a,
+       0x2009, 0x0088, 0x1078, 0x756c, 0x0078, 0x5793, 0xa28c, 0x00ff,
+       0xa186, 0x0006, 0x0040, 0x5773, 0xa186, 0x0004, 0x0040, 0x5773,
+       0xa294, 0xff00, 0x8217, 0xa286, 0x0004, 0x0040, 0x5773, 0xa286,
+       0x0006, 0x00c0, 0x5784, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040,
+       0x5793, 0x611a, 0x601f, 0x0005, 0x7120, 0x610a, 0x2009, 0x0088,
+       0x1078, 0x756c, 0x0078, 0x5793, 0x0c7e, 0x1078, 0x74d7, 0x017f,
+       0x0040, 0x5793, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0x2009,
+       0x0001, 0x1078, 0x756c, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x57a2,
+       0x1078, 0x57b2, 0x0040, 0x57a2, 0x7124, 0x610a, 0x2009, 0x0089,
+       0x1078, 0x756c, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x57b1, 0x1078,
+       0x57b2, 0x0040, 0x57b1, 0x7124, 0x610a, 0x2009, 0x008a, 0x1078,
+       0x756c, 0x007c, 0x7020, 0x2060, 0xac84, 0x000f, 0x00c0, 0x57c5,
+       0xac82, 0xaa00, 0x0048, 0x57c5, 0x2001, 0xa315, 0x2004, 0xac02,
+       0x00c8, 0x57c5, 0xa085, 0x0001, 0x007c, 0xa006, 0x0078, 0x57c4,
+       0x7110, 0xd1bc, 0x00c0, 0x57de, 0x7024, 0x2060, 0xac84, 0x000f,
+       0x00c0, 0x57de, 0xac82, 0xaa00, 0x0048, 0x57de, 0x6854, 0xac02,
+       0x00c8, 0x57de, 0x2009, 0x0051, 0x1078, 0x756c, 0x007c, 0x2071,
+       0xa5be, 0x7003, 0x0003, 0x700f, 0x0361, 0xa006, 0x701a, 0x7012,
+       0x7017, 0xaa00, 0x7007, 0x0000, 0x7026, 0x702b, 0x6c4e, 0x7032,
+       0x7037, 0x6ca0, 0x703b, 0x0002, 0x703f, 0x0000, 0x7043, 0xffff,
+       0x7047, 0xffff, 0x007c, 0x2071, 0xa5be, 0x00e0, 0x58c1, 0x2091,
+       0x6000, 0x700c, 0x8001, 0x700e, 0x00c0, 0x5873, 0x700f, 0x0361,
+       0x7007, 0x0001, 0x127e, 0x2091, 0x8000, 0x7138, 0x8109, 0x713a,
+       0x00c0, 0x5871, 0x703b, 0x0002, 0x2009, 0x0100, 0x2104, 0xa082,
+       0x0003, 0x00c8, 0x5871, 0x703c, 0xa086, 0x0001, 0x00c0, 0x584e,
+       0x0d7e, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000, 0x0040, 0x582c,
+       0x6803, 0x1000, 0x0078, 0x5833, 0x6804, 0xa084, 0x1000, 0x0040,
+       0x5833, 0x6803, 0x0100, 0x6803, 0x0000, 0x703f, 0x0000, 0x2069,
+       0xa5ab, 0x6804, 0xa082, 0x0006, 0x00c0, 0x5840, 0x6807, 0x0000,
+       0x6830, 0xa082, 0x0003, 0x00c0, 0x5847, 0x6833, 0x0000, 0x1078,
+       0x6109, 0x1078, 0x61d3, 0x0d7f, 0x0078, 0x5871, 0x0d7e, 0x2069,
+       0xa300, 0x6944, 0x6860, 0xa102, 0x00c8, 0x5870, 0x2069, 0xa5ab,
+       0x6804, 0xa086, 0x0000, 0x00c0, 0x5870, 0x6830, 0xa086, 0x0000,
+       0x00c0, 0x5870, 0x703f, 0x0001, 0x6807, 0x0006, 0x6833, 0x0003,
+       0x2069, 0x0100, 0x6830, 0x689e, 0x2069, 0x0140, 0x6803, 0x0600,
+       0x0d7f, 0x0078, 0x5876, 0x127e, 0x2091, 0x8000, 0x7024, 0xa00d,
+       0x0040, 0x588e, 0x7020, 0x8001, 0x7022, 0x00c0, 0x588e, 0x7023,
+       0x0009, 0x8109, 0x7126, 0xa186, 0x03e8, 0x00c0, 0x5889, 0x7028,
+       0x107a, 0x81ff, 0x00c0, 0x588e, 0x7028, 0x107a, 0x7030, 0xa00d,
+       0x0040, 0x589f, 0x702c, 0x8001, 0x702e, 0x00c0, 0x589f, 0x702f,
+       0x0009, 0x8109, 0x7132, 0x00c0, 0x589f, 0x7034, 0x107a, 0x7040,
+       0xa005, 0x0040, 0x58a7, 0x0050, 0x58a7, 0x8001, 0x7042, 0x7044,
+       0xa005, 0x0040, 0x58af, 0x0050, 0x58af, 0x8001, 0x7046, 0x7018,
+       0xa00d, 0x0040, 0x58c0, 0x7008, 0x8001, 0x700a, 0x00c0, 0x58c0,
+       0x700b, 0x0009, 0x8109, 0x711a, 0x00c0, 0x58c0, 0x701c, 0x107a,
+       0x127f, 0x7004, 0x0079, 0x58c4, 0x58eb, 0x58ec, 0x5908, 0x0e7e,
+       0x2071, 0xa5be, 0x7018, 0xa005, 0x00c0, 0x58d2, 0x711a, 0x721e,
+       0x700b, 0x0009, 0x0e7f, 0x007c, 0x0e7e, 0x007e, 0x2071, 0xa5be,
+       0x701c, 0xa206, 0x00c0, 0x58de, 0x701a, 0x701e, 0x007f, 0x0e7f,
+       0x007c, 0x0e7e, 0x2071, 0xa5be, 0x6088, 0xa102, 0x0048, 0x58e9,
+       0x618a, 0x0e7f, 0x007c, 0x007c, 0x7110, 0x1078, 0x4501, 0x00c0,
+       0x58fe, 0x6088, 0x8001, 0x0048, 0x58fe, 0x608a, 0x00c0, 0x58fe,
+       0x127e, 0x2091, 0x8000, 0x1078, 0x6109, 0x127f, 0x8108, 0xa182,
+       0x00ff, 0x0048, 0x5906, 0xa00e, 0x7007, 0x0002, 0x7112, 0x007c,
+       0x7014, 0x2060, 0x127e, 0x2091, 0x8000, 0x603c, 0xa005, 0x0040,
+       0x5917, 0x8001, 0x603e, 0x00c0, 0x5917, 0x1078, 0x8cd7, 0x6014,
+       0xa005, 0x0040, 0x5941, 0x8001, 0x6016, 0x00c0, 0x5941, 0x611c,
+       0xa186, 0x0003, 0x0040, 0x5928, 0xa186, 0x0006, 0x00c0, 0x593f,
+       0x6010, 0x2068, 0x6854, 0xa08a, 0x199a, 0x0048, 0x593f, 0xa082,
+       0x1999, 0x6856, 0xa08a, 0x199a, 0x0048, 0x5938, 0x2001, 0x1999,
+       0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x0078, 0x5941, 0x1078,
+       0x8810, 0x127f, 0xac88, 0x0010, 0x7116, 0x2001, 0xca00, 0xa102,
+       0x0048, 0x594e, 0x7017, 0xaa00, 0x7007, 0x0000, 0x007c, 0x0e7e,
+       0x2071, 0xa5be, 0x7027, 0x07d0, 0x7023, 0x0009, 0x703b, 0x0002,
+       0x0e7f, 0x007c, 0x2001, 0xa5c7, 0x2003, 0x0000, 0x007c, 0x0e7e,
+       0x2071, 0xa5be, 0x7132, 0x702f, 0x0009, 0x0e7f, 0x007c, 0x2011,
+       0xa5ca, 0x2013, 0x0000, 0x007c, 0x0e7e, 0x2071, 0xa5be, 0x711a,
+       0x721e, 0x700b, 0x0009, 0x0e7f, 0x007c, 0x027e, 0x0e7e, 0x0f7e,
+       0x2079, 0xa300, 0x7a34, 0xd294, 0x0040, 0x59a4, 0x2071, 0xa5aa,
+       0x2e14, 0xa0fe, 0x0000, 0x0040, 0x5991, 0xa0fe, 0x0001, 0x0040,
+       0x5995, 0xa0fe, 0x0002, 0x00c0, 0x59a0, 0xa292, 0x0085, 0x0078,
+       0x5997, 0xa292, 0x0005, 0x0078, 0x5997, 0xa292, 0x0002, 0x2272,
+       0x0040, 0x599c, 0x00c8, 0x59a4, 0x2011, 0x8037, 0x1078, 0x3579,
+       0x2011, 0xa5a9, 0x2204, 0x2072, 0x0f7f, 0x0e7f, 0x027f, 0x007c,
+       0x0c7e, 0x2061, 0xa62d, 0x0c7f, 0x007c, 0xa184, 0x000f, 0x8003,
+       0x8003, 0x8003, 0xa080, 0xa62d, 0x2060, 0x007c, 0x6854, 0xa08a,
+       0x199a, 0x0048, 0x59bd, 0x2001, 0x1999, 0xa005, 0x00c0, 0x59cc,
+       0x0c7e, 0x2061, 0xa62d, 0x6014, 0x0c7f, 0xa005, 0x00c0, 0x59d1,
+       0x2001, 0x001e, 0x0078, 0x59d1, 0xa08e, 0xffff, 0x00c0, 0x59d1,
+       0xa006, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x684c, 0xa08c,
+       0x00c0, 0xa18e, 0x00c0, 0x0040, 0x5a24, 0xd0b4, 0x00c0, 0x59e8,
+       0xd0bc, 0x00c0, 0x5a14, 0x2009, 0x0006, 0x1078, 0x5a43, 0x007c,
+       0xd0fc, 0x0040, 0x59f3, 0xa084, 0x0003, 0x0040, 0x59f3, 0xa086,
+       0x0003, 0x00c0, 0x5a3c, 0x6024, 0xd0d4, 0x0040, 0x59fd, 0xc0d4,
+       0x6026, 0x6860, 0x602a, 0x685c, 0x602e, 0x2009, 0xa373, 0x2104,
+       0xd084, 0x0040, 0x5a0f, 0x6118, 0xa188, 0x0027, 0x2104, 0xd08c,
+       0x00c0, 0x5a0f, 0x2009, 0x0042, 0x1078, 0x756c, 0x007c, 0x2009,
+       0x0043, 0x1078, 0x756c, 0x007c, 0xd0fc, 0x0040, 0x5a1f, 0xa084,
+       0x0003, 0x0040, 0x5a1f, 0xa086, 0x0003, 0x00c0, 0x5a3c, 0x2009,
+       0x0042, 0x1078, 0x756c, 0x007c, 0xd0fc, 0x0040, 0x5a32, 0xa084,
+       0x0003, 0xa08e, 0x0002, 0x0040, 0x5a36, 0x2009, 0x0041, 0x1078,
+       0x756c, 0x007c, 0x1078, 0x5a41, 0x0078, 0x5a31, 0x2009, 0x0043,
+       0x1078, 0x756c, 0x0078, 0x5a31, 0x2009, 0x0004, 0x1078, 0x5a43,
+       0x007c, 0x2009, 0x0001, 0x0d7e, 0x6010, 0xa0ec, 0xf000, 0x0040,
+       0x5a6b, 0x2068, 0x6952, 0x6800, 0x6012, 0xa186, 0x0001, 0x00c0,
+       0x5a65, 0x694c, 0xa18c, 0x8100, 0xa18e, 0x8100, 0x00c0, 0x5a65,
+       0x0c7e, 0x2061, 0xa62d, 0x6200, 0xd28c, 0x00c0, 0x5a64, 0x6204,
+       0x8210, 0x0048, 0x5a64, 0x6206, 0x0c7f, 0x1078, 0x4982, 0x6010,
+       0xa06d, 0x10c0, 0x59b6, 0x0d7f, 0x007c, 0x157e, 0x0c7e, 0x2061,
+       0xa62d, 0x6000, 0x81ff, 0x0040, 0x5a78, 0xa205, 0x0078, 0x5a79,
+       0xa204, 0x6002, 0x0c7f, 0x157f, 0x007c, 0x6800, 0xd08c, 0x00c0,
+       0x5a89, 0x6808, 0xa005, 0x0040, 0x5a89, 0x8001, 0x680a, 0xa085,
+       0x0001, 0x007c, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e,
+       0x00c8, 0x5a93, 0xa200, 0x00f0, 0x5a8e, 0x8086, 0x818e, 0x007c,
+       0x157e, 0x20a9, 0x0010, 0xa005, 0x0040, 0x5ab9, 0xa11a, 0x00c8,
+       0x5ab9, 0x8213, 0x818d, 0x0048, 0x5aac, 0xa11a, 0x00c8, 0x5aad,
+       0x00f0, 0x5aa1, 0x0078, 0x5ab1, 0xa11a, 0x2308, 0x8210, 0x00f0,
+       0x5aa1, 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080, 0x007f, 0x157f,
+       0x007c, 0x007e, 0x3200, 0xa085, 0x0800, 0x0078, 0x5ab5, 0x127e,
+       0x2091, 0x2200, 0x2079, 0xa5ab, 0x127f, 0x0d7e, 0x2069, 0xa5ab,
+       0x6803, 0x0005, 0x2069, 0x0004, 0x2d04, 0xa085, 0x8001, 0x206a,
+       0x0d7f, 0x007c, 0x0c7e, 0x6027, 0x0001, 0x7804, 0xa084, 0x0007,
+       0x0079, 0x5ada, 0x5ae4, 0x5b09, 0x5b64, 0x5aea, 0x5b09, 0x5ae4,
+       0x5ae2, 0x5ae2, 0x1078, 0x1328, 0x1078, 0x595a, 0x1078, 0x6109,
+       0x0c7f, 0x007c, 0x62c0, 0x82ff, 0x00c0, 0x5af0, 0x0c7f, 0x007c,
+       0x2011, 0x4129, 0x1078, 0x58d4, 0x7828, 0xa092, 0x00c8, 0x00c8,
+       0x5aff, 0x8000, 0x782a, 0x1078, 0x4168, 0x0078, 0x5aee, 0x1078,
+       0x4129, 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000, 0x0078,
+       0x5aee, 0x1078, 0x595a, 0x3c00, 0x007e, 0x2011, 0x0209, 0x20e1,
+       0x4000, 0x2214, 0x007f, 0x20e0, 0x82ff, 0x0040, 0x5b27, 0x62c0,
+       0x82ff, 0x00c0, 0x5b27, 0x782b, 0x0000, 0x7824, 0xa065, 0x1040,
+       0x1328, 0x2009, 0x0013, 0x1078, 0x756c, 0x0c7f, 0x007c, 0x3900,
+       0xa082, 0xa6cd, 0x00c8, 0x5b2e, 0x1078, 0x728a, 0x0c7e, 0x7824,
+       0xa065, 0x1040, 0x1328, 0x7804, 0xa086, 0x0004, 0x0040, 0x5ba9,
+       0x7828, 0xa092, 0x2710, 0x00c8, 0x5b44, 0x8000, 0x782a, 0x0c7f,
+       0x1078, 0x6c33, 0x0078, 0x5b25, 0x6104, 0xa186, 0x0003, 0x00c0,
+       0x5b5b, 0x0e7e, 0x2071, 0xa300, 0x70d4, 0x0e7f, 0xd08c, 0x0040,
+       0x5b5b, 0x0c7e, 0x0e7e, 0x2061, 0x0100, 0x2071, 0xa300, 0x1078,
+       0x4171, 0x0e7f, 0x0c7f, 0x1078, 0xa241, 0x2009, 0x0014, 0x1078,
+       0x756c, 0x0c7f, 0x0078, 0x5b25, 0x2001, 0xa5c7, 0x2003, 0x0000,
+       0x62c0, 0x82ff, 0x00c0, 0x5b78, 0x782b, 0x0000, 0x7824, 0xa065,
+       0x1040, 0x1328, 0x2009, 0x0013, 0x1078, 0x75c3, 0x0c7f, 0x007c,
+       0x0c7e, 0x0d7e, 0x3900, 0xa082, 0xa6cd, 0x00c8, 0x5b81, 0x1078,
+       0x728a, 0x7824, 0xa005, 0x1040, 0x1328, 0x781c, 0xa06d, 0x1040,
+       0x1328, 0x6800, 0xc0dc, 0x6802, 0x7924, 0x2160, 0x1078, 0x753d,
+       0x693c, 0x81ff, 0x1040, 0x1328, 0x8109, 0x693e, 0x6854, 0xa015,
+       0x0040, 0x5b9d, 0x7a1e, 0x0078, 0x5b9f, 0x7918, 0x791e, 0x7807,
+       0x0000, 0x7827, 0x0000, 0x0d7f, 0x0c7f, 0x1078, 0x6109, 0x0078,
+       0x5b76, 0x6104, 0xa186, 0x0002, 0x0040, 0x5bb4, 0xa186, 0x0004,
+       0x0040, 0x5bb4, 0x0078, 0x5b38, 0x7808, 0xac06, 0x0040, 0x5b38,
+       0x1078, 0x6010, 0x1078, 0x5c45, 0x0c7f, 0x1078, 0x6109, 0x0078,
+       0x5b25, 0x0c7e, 0x6027, 0x0002, 0x62c8, 0x82ff, 0x00c0, 0x5bdb,
+       0x62c4, 0x82ff, 0x00c0, 0x5bdb, 0x793c, 0xa1e5, 0x0000, 0x0040,
+       0x5bd5, 0x2009, 0x0049, 0x1078, 0x756c, 0x2011, 0xa5ca, 0x2013,
+       0x0000, 0x0c7f, 0x007c, 0x3908, 0xa192, 0xa6cd, 0x00c8, 0x5be2,
+       0x1078, 0x728a, 0x6017, 0x0010, 0x793c, 0x81ff, 0x0040, 0x5bd5,
+       0x793c, 0xa188, 0x0007, 0x210c, 0xa18e, 0x0006, 0x00c0, 0x5bf4,
+       0x6017, 0x0012, 0x0078, 0x5bd9, 0x6017, 0x0016, 0x0078, 0x5bd9,
+       0x007e, 0x017e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x600f, 0x0000,
+       0x2c08, 0x2061, 0xa5ab, 0x6020, 0x8000, 0x6022, 0x6010, 0xa005,
+       0x0040, 0x5c13, 0xa080, 0x0003, 0x2102, 0x6112, 0x127f, 0x0c7f,
+       0x017f, 0x007f, 0x007c, 0x6116, 0x6112, 0x0078, 0x5c0e, 0x0d7e,
+       0x2069, 0xa5ab, 0x6000, 0xd0d4, 0x0040, 0x5c2c, 0x6820, 0x8000,
+       0x6822, 0xa086, 0x0001, 0x00c0, 0x5c27, 0x2c00, 0x681e, 0x6804,
+       0xa084, 0x0007, 0x0079, 0x6111, 0xc0d5, 0x6002, 0x6818, 0xa005,
+       0x0040, 0x5c3e, 0x6056, 0x605b, 0x0000, 0x007e, 0x2c00, 0x681a,
+       0x0d7f, 0x685a, 0x2069, 0xa5ab, 0x0078, 0x5c1e, 0x6056, 0x605a,
+       0x2c00, 0x681a, 0x681e, 0x0078, 0x5c1e, 0x007e, 0x017e, 0x0c7e,
+       0x127e, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, 0xa5ab,
+       0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0040, 0x5c60, 0xa080,
+       0x0003, 0x2102, 0x610a, 0x127f, 0x0c7f, 0x017f, 0x007f, 0x007c,
+       0x610e, 0x610a, 0x0078, 0x5c5b, 0x0c7e, 0x600f, 0x0000, 0x2c08,
+       0x2061, 0xa5ab, 0x6034, 0xa005, 0x0040, 0x5c74, 0xa080, 0x0003,
+       0x2102, 0x6136, 0x0c7f, 0x007c, 0x613a, 0x6136, 0x0078, 0x5c72,
+       0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x027e, 0x017e, 0x007e,
+       0x127e, 0x2071, 0xa5ab, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000,
+       0x8cff, 0x0040, 0x5ced, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206,
+       0x00c0, 0x5ce8, 0x87ff, 0x0040, 0x5c99, 0x6020, 0xa106, 0x00c0,
+       0x5ce8, 0x703c, 0xac06, 0x00c0, 0x5cab, 0x037e, 0x2019, 0x0001,
+       0x1078, 0x6e6c, 0x7033, 0x0000, 0x703f, 0x0000, 0x7043, 0x0000,
+       0x7047, 0x0000, 0x037f, 0x7038, 0xac36, 0x00c0, 0x5cb1, 0x660c,
+       0x763a, 0x7034, 0xac36, 0x00c0, 0x5cbf, 0x2c00, 0xaf36, 0x0040,
+       0x5cbd, 0x2f00, 0x7036, 0x0078, 0x5cbf, 0x7037, 0x0000, 0x660c,
+       0x067e, 0x2c00, 0xaf06, 0x0040, 0x5cc8, 0x7e0e, 0x0078, 0x5cc9,
+       0x2678, 0x600f, 0x0000, 0x1078, 0x8a44, 0x0040, 0x5ce3, 0x6010,
+       0x2068, 0x601c, 0xa086, 0x0003, 0x00c0, 0x5cf7, 0x6837, 0x0103,
+       0x6b4a, 0x6847, 0x0000, 0x1078, 0x8cb8, 0x1078, 0xa181, 0x1078,
+       0x4982, 0x1078, 0x8bf4, 0x1078, 0x8c01, 0x0c7f, 0x0078, 0x5c88,
+       0x2c78, 0x600c, 0x2060, 0x0078, 0x5c88, 0x127f, 0x007f, 0x017f,
+       0x027f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x601c,
+       0xa086, 0x0006, 0x00c0, 0x5cd6, 0x1078, 0xa181, 0x1078, 0x9e70,
+       0x0078, 0x5ce3, 0x007e, 0x067e, 0x0c7e, 0x0d7e, 0x0f7e, 0x2031,
+       0x0000, 0x127e, 0x2091, 0x8000, 0x2079, 0xa5ab, 0x7838, 0xa065,
+       0x0040, 0x5d41, 0x600c, 0x007e, 0x600f, 0x0000, 0x783c, 0xac06,
+       0x00c0, 0x5d28, 0x037e, 0x2019, 0x0001, 0x1078, 0x6e6c, 0x7833,
+       0x0000, 0x783f, 0x0000, 0x7843, 0x0000, 0x7847, 0x0000, 0x037f,
+       0x1078, 0x8a44, 0x0040, 0x5d3c, 0x6010, 0x2068, 0x601c, 0xa086,
+       0x0003, 0x00c0, 0x5d4a, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
+       0x1078, 0x4982, 0x1078, 0x8bf4, 0x1078, 0x8c01, 0x007f, 0x0078,
+       0x5d0f, 0x7e3a, 0x7e36, 0x127f, 0x0f7f, 0x0d7f, 0x0c7f, 0x067f,
+       0x007f, 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x5d33, 0x1078,
+       0x9e70, 0x0078, 0x5d3c, 0x017e, 0x027e, 0x087e, 0x2041, 0x0000,
+       0x1078, 0x5d6d, 0x1078, 0x5e21, 0x087f, 0x027f, 0x017f, 0x007c,
+       0x0f7e, 0x127e, 0x2079, 0xa5ab, 0x2091, 0x8000, 0x1078, 0x5ebc,
+       0x1078, 0x5f32, 0x127f, 0x0f7f, 0x007c, 0x0f7e, 0x0e7e, 0x0d7e,
+       0x0c7e, 0x067e, 0x017e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071,
+       0xa5ab, 0x7614, 0x2660, 0x2678, 0x8cff, 0x0040, 0x5e01, 0x6018,
+       0xa080, 0x0028, 0x2004, 0xa206, 0x00c0, 0x5dfc, 0x88ff, 0x0040,
+       0x5d8d, 0x6020, 0xa106, 0x00c0, 0x5dfc, 0x7024, 0xac06, 0x00c0,
+       0x5dbd, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040, 0x5db8, 0x1078,
+       0x595a, 0x1078, 0x6c41, 0x68c3, 0x0000, 0x1078, 0x7188, 0x7027,
+       0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040,
+       0x5dad, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824,
+       0xd084, 0x0040, 0x5db5, 0x6827, 0x0001, 0x037f, 0x0078, 0x5dbd,
+       0x6003, 0x0009, 0x630a, 0x0078, 0x5dfc, 0x7014, 0xac36, 0x00c0,
+       0x5dc3, 0x660c, 0x7616, 0x7010, 0xac36, 0x00c0, 0x5dd1, 0x2c00,
+       0xaf36, 0x0040, 0x5dcf, 0x2f00, 0x7012, 0x0078, 0x5dd1, 0x7013,
+       0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, 0x5dda, 0x7e0e,
+       0x0078, 0x5ddb, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x1078,
+       0x8a44, 0x0040, 0x5df5, 0x601c, 0xa086, 0x0003, 0x00c0, 0x5e0a,
+       0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x8cb8, 0x1078,
+       0xa181, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x1078, 0x8c01, 0x1078,
+       0x7045, 0x0c7f, 0x0078, 0x5d7c, 0x2c78, 0x600c, 0x2060, 0x0078,
+       0x5d7c, 0x127f, 0x007f, 0x017f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f,
+       0x0f7f, 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x5e15, 0x1078,
+       0xa181, 0x1078, 0x9e70, 0x0078, 0x5df5, 0x601c, 0xa086, 0x0002,
+       0x00c0, 0x5df5, 0x6004, 0xa086, 0x0085, 0x0040, 0x5de8, 0x0078,
+       0x5df5, 0x0c7e, 0x007e, 0x127e, 0x2091, 0x8000, 0xa280, 0xa434,
+       0x2004, 0xa065, 0x0040, 0x5eb8, 0x0f7e, 0x0e7e, 0x0d7e, 0x067e,
+       0x2071, 0xa5ab, 0x6654, 0x7018, 0xac06, 0x00c0, 0x5e38, 0x761a,
+       0x701c, 0xac06, 0x00c0, 0x5e44, 0x86ff, 0x00c0, 0x5e43, 0x7018,
+       0x701e, 0x0078, 0x5e44, 0x761e, 0x6058, 0xa07d, 0x0040, 0x5e49,
+       0x7e56, 0xa6ed, 0x0000, 0x0040, 0x5e4f, 0x2f00, 0x685a, 0x6057,
+       0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x1078,
+       0x4410, 0x0040, 0x5eb4, 0x7624, 0x86ff, 0x0040, 0x5ea2, 0xa680,
+       0x0004, 0x2004, 0xad06, 0x00c0, 0x5ea2, 0x0d7e, 0x2069, 0x0100,
+       0x68c0, 0xa005, 0x0040, 0x5e99, 0x1078, 0x595a, 0x1078, 0x6c41,
+       0x68c3, 0x0000, 0x1078, 0x7188, 0x7027, 0x0000, 0x037e, 0x2069,
+       0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x5e82, 0x6803, 0x0100,
+       0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x5e8a,
+       0x6827, 0x0001, 0x037f, 0x0d7f, 0x0c7e, 0x603c, 0xa005, 0x0040,
+       0x5e93, 0x8001, 0x603e, 0x2660, 0x1078, 0x8c01, 0x0c7f, 0x0078,
+       0x5ea2, 0x0d7f, 0x0c7e, 0x2660, 0x6003, 0x0009, 0x630a, 0x0c7f,
+       0x0078, 0x5e57, 0x8dff, 0x0040, 0x5eb0, 0x6837, 0x0103, 0x6b4a,
+       0x6847, 0x0000, 0x1078, 0x8cb8, 0x1078, 0xa181, 0x1078, 0x4982,
+       0x1078, 0x7045, 0x0078, 0x5e57, 0x067f, 0x0d7f, 0x0e7f, 0x0f7f,
+       0x127f, 0x007f, 0x0c7f, 0x007c, 0x007e, 0x067e, 0x0c7e, 0x0d7e,
+       0x2031, 0x0000, 0x7814, 0xa065, 0x0040, 0x5f16, 0x600c, 0x007e,
+       0x600f, 0x0000, 0x7824, 0xac06, 0x00c0, 0x5efb, 0x2069, 0x0100,
+       0x68c0, 0xa005, 0x0040, 0x5ef5, 0x1078, 0x595a, 0x1078, 0x6c41,
+       0x68c3, 0x0000, 0x1078, 0x7188, 0x7827, 0x0000, 0x037e, 0x2069,
+       0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x5eea, 0x6803, 0x0100,
+       0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x5ef2,
+       0x6827, 0x0001, 0x037f, 0x0078, 0x5efb, 0x6003, 0x0009, 0x630a,
+       0x2c30, 0x0078, 0x5f13, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040,
+       0x5f0f, 0x601c, 0xa086, 0x0003, 0x00c0, 0x5f1d, 0x6837, 0x0103,
+       0x6b4a, 0x6847, 0x0000, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x1078,
+       0x8c01, 0x1078, 0x7045, 0x007f, 0x0078, 0x5ec3, 0x7e16, 0x7e12,
+       0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, 0x601c, 0xa086, 0x0006,
+       0x00c0, 0x5f26, 0x1078, 0x9e70, 0x0078, 0x5f0f, 0x601c, 0xa086,
+       0x0002, 0x00c0, 0x5f0f, 0x6004, 0xa086, 0x0085, 0x0040, 0x5f06,
+       0x0078, 0x5f0f, 0x007e, 0x067e, 0x0c7e, 0x0d7e, 0x7818, 0xa065,
+       0x0040, 0x5fa0, 0x6054, 0x007e, 0x6057, 0x0000, 0x605b, 0x0000,
+       0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x1078, 0x4410, 0x0040, 0x5f9d,
+       0x7e24, 0x86ff, 0x0040, 0x5f8f, 0xa680, 0x0004, 0x2004, 0xad06,
+       0x00c0, 0x5f8f, 0x0d7e, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040,
+       0x5f86, 0x1078, 0x595a, 0x1078, 0x6c41, 0x68c3, 0x0000, 0x1078,
+       0x7188, 0x7827, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384,
+       0x1000, 0x0040, 0x5f6f, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069,
+       0x0100, 0x6824, 0xd084, 0x0040, 0x5f77, 0x6827, 0x0001, 0x037f,
+       0x0d7f, 0x0c7e, 0x603c, 0xa005, 0x0040, 0x5f80, 0x8001, 0x603e,
+       0x2660, 0x1078, 0x8c01, 0x0c7f, 0x0078, 0x5f8f, 0x0d7f, 0x0c7e,
+       0x2660, 0x6003, 0x0009, 0x630a, 0x0c7f, 0x0078, 0x5f44, 0x8dff,
+       0x0040, 0x5f99, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078,
+       0x4982, 0x1078, 0x7045, 0x0078, 0x5f44, 0x007f, 0x0078, 0x5f37,
+       0x781e, 0x781a, 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, 0x0e7e,
+       0x0d7e, 0x067e, 0x6000, 0xd0dc, 0x0040, 0x5fc4, 0x604c, 0xa06d,
+       0x0040, 0x5fc4, 0x6848, 0xa606, 0x00c0, 0x5fc4, 0x2071, 0xa5ab,
+       0x7024, 0xa035, 0x0040, 0x5fc4, 0xa080, 0x0004, 0x2004, 0xad06,
+       0x00c0, 0x5fc4, 0x1078, 0x5fc8, 0x067f, 0x0d7f, 0x0e7f, 0x007c,
+       0x0f7e, 0x2079, 0x0100, 0x78c0, 0xa005, 0x00c0, 0x5fd7, 0x0c7e,
+       0x2660, 0x6003, 0x0009, 0x630a, 0x0c7f, 0x0078, 0x600e, 0x1078,
+       0x6c41, 0x78c3, 0x0000, 0x1078, 0x7188, 0x7027, 0x0000, 0x037e,
+       0x2079, 0x0140, 0x7b04, 0xa384, 0x1000, 0x0040, 0x5feb, 0x7803,
+       0x0100, 0x7803, 0x0000, 0x2079, 0x0100, 0x7824, 0xd084, 0x0040,
+       0x5ff3, 0x7827, 0x0001, 0x1078, 0x7188, 0x037f, 0x1078, 0x4410,
+       0x0c7e, 0x603c, 0xa005, 0x0040, 0x5fff, 0x8001, 0x603e, 0x2660,
+       0x1078, 0x753d, 0x0c7f, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
+       0x1078, 0x8cb8, 0x1078, 0x4982, 0x1078, 0x7045, 0x0f7f, 0x007c,
+       0x0e7e, 0x0c7e, 0x2071, 0xa5ab, 0x7004, 0xa084, 0x0007, 0x0079,
+       0x6019, 0x6023, 0x6026, 0x603f, 0x605b, 0x60a0, 0x6023, 0x6023,
+       0x6021, 0x1078, 0x1328, 0x0c7f, 0x0e7f, 0x007c, 0x7024, 0xa065,
+       0x0040, 0x6034, 0x7020, 0x8001, 0x7022, 0x600c, 0xa015, 0x0040,
+       0x603b, 0x7216, 0x600f, 0x0000, 0x7007, 0x0000, 0x7027, 0x0000,
+       0x0c7f, 0x0e7f, 0x007c, 0x7216, 0x7212, 0x0078, 0x6034, 0x6018,
+       0x2060, 0x1078, 0x4410, 0x6000, 0xc0dc, 0x6002, 0x7020, 0x8001,
+       0x7022, 0x0040, 0x6050, 0x6054, 0xa015, 0x0040, 0x6057, 0x721e,
+       0x7007, 0x0000, 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x7218,
+       0x721e, 0x0078, 0x6050, 0x7024, 0xa065, 0x0040, 0x609d, 0x700c,
+       0xac06, 0x00c0, 0x6072, 0x1078, 0x7045, 0x600c, 0xa015, 0x0040,
+       0x606e, 0x720e, 0x600f, 0x0000, 0x0078, 0x609b, 0x720e, 0x720a,
+       0x0078, 0x609b, 0x7014, 0xac06, 0x00c0, 0x6085, 0x1078, 0x7045,
+       0x600c, 0xa015, 0x0040, 0x6081, 0x7216, 0x600f, 0x0000, 0x0078,
+       0x609b, 0x7216, 0x7212, 0x0078, 0x609b, 0x6018, 0x2060, 0x1078,
+       0x4410, 0x6000, 0xc0dc, 0x6002, 0x1078, 0x7045, 0x701c, 0xa065,
+       0x0040, 0x609b, 0x6054, 0xa015, 0x0040, 0x6099, 0x721e, 0x0078,
+       0x609b, 0x7218, 0x721e, 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c,
+       0x7024, 0xa065, 0x0040, 0x60ad, 0x1078, 0x7045, 0x600c, 0xa015,
+       0x0040, 0x60b4, 0x720e, 0x600f, 0x0000, 0x1078, 0x7188, 0x7027,
+       0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x720e, 0x720a, 0x0078, 0x60ad,
+       0x0d7e, 0x2069, 0xa5ab, 0x6830, 0xa084, 0x0003, 0x0079, 0x60c0,
+       0x60c6, 0x60c8, 0x60ee, 0x60c6, 0x1078, 0x1328, 0x0d7f, 0x007c,
+       0x0c7e, 0x6840, 0xa086, 0x0001, 0x0040, 0x60e4, 0x683c, 0xa065,
+       0x0040, 0x60d9, 0x600c, 0xa015, 0x0040, 0x60e0, 0x6a3a, 0x600f,
+       0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x0c7f, 0x0d7f, 0x007c,
+       0x683a, 0x6836, 0x0078, 0x60d9, 0x6843, 0x0000, 0x6838, 0xa065,
+       0x0040, 0x60d9, 0x6003, 0x0003, 0x0078, 0x60d9, 0x0c7e, 0x6843,
+       0x0000, 0x6847, 0x0000, 0x683c, 0xa065, 0x0040, 0x6106, 0x600c,
+       0xa015, 0x0040, 0x6102, 0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000,
+       0x0078, 0x6106, 0x683f, 0x0000, 0x683a, 0x6836, 0x0c7f, 0x0d7f,
+       0x007c, 0x0d7e, 0x2069, 0xa5ab, 0x6804, 0xa084, 0x0007, 0x0079,
+       0x6111, 0x611b, 0x61c2, 0x61c2, 0x61c2, 0x61c2, 0x61c4, 0x61c2,
+       0x6119, 0x1078, 0x1328, 0x6820, 0xa005, 0x00c0, 0x6121, 0x0d7f,
+       0x007c, 0x0c7e, 0x680c, 0xa065, 0x0040, 0x6130, 0x6807, 0x0004,
+       0x6826, 0x682b, 0x0000, 0x1078, 0x620a, 0x0c7f, 0x0d7f, 0x007c,
+       0x6814, 0xa065, 0x0040, 0x613e, 0x6807, 0x0001, 0x6826, 0x682b,
+       0x0000, 0x1078, 0x620a, 0x0c7f, 0x0d7f, 0x007c, 0x0e7e, 0x037e,
+       0x6a1c, 0xa2f5, 0x0000, 0x0040, 0x61bd, 0x704c, 0xa00d, 0x0040,
+       0x614d, 0x7088, 0xa005, 0x0040, 0x6165, 0x7054, 0xa075, 0x0040,
+       0x6156, 0xa20e, 0x0040, 0x61bd, 0x0078, 0x615b, 0x6818, 0xa20e,
+       0x0040, 0x61bd, 0x2070, 0x704c, 0xa00d, 0x0040, 0x614d, 0x7088,
+       0xa005, 0x00c0, 0x614d, 0x2e00, 0x681e, 0x733c, 0x7038, 0xa302,
+       0x00c8, 0x614d, 0x1078, 0x750c, 0x0040, 0x61bd, 0x8318, 0x733e,
+       0x6112, 0x2e10, 0x621a, 0xa180, 0x0014, 0x2004, 0xa084, 0x00ff,
+       0x6032, 0xa180, 0x0014, 0x2003, 0x0000, 0xa180, 0x0015, 0x2004,
+       0xa08a, 0x199a, 0x0048, 0x6186, 0x2001, 0x1999, 0x8003, 0x801b,
+       0x831b, 0xa318, 0x6316, 0x037f, 0x0f7e, 0x2c78, 0x71a0, 0xd1bc,
+       0x0040, 0x619f, 0x7100, 0xd1f4, 0x0040, 0x619b, 0x7114, 0xa18c,
+       0x00ff, 0x0078, 0x61a4, 0x2009, 0x0000, 0x0078, 0x61a4, 0xa1e0,
+       0x293f, 0x2c0c, 0xa18c, 0x00ff, 0x2061, 0x0100, 0x619a, 0x1078,
+       0x679b, 0x7300, 0xc3dd, 0x7302, 0x6807, 0x0002, 0x2f18, 0x6b26,
+       0x682b, 0x0000, 0x781f, 0x0003, 0x7803, 0x0001, 0x7807, 0x0040,
+       0x0f7f, 0x0e7f, 0x0c7f, 0x0d7f, 0x007c, 0x037f, 0x0e7f, 0x0c7f,
+       0x0078, 0x61bb, 0x0d7f, 0x007c, 0x0c7e, 0x680c, 0xa065, 0x0040,
+       0x61d0, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x1078, 0x620a,
+       0x0c7f, 0x0d7f, 0x007c, 0x0f7e, 0x0d7e, 0x2069, 0xa5ab, 0x6830,
+       0xa086, 0x0000, 0x00c0, 0x61f1, 0x6838, 0xa07d, 0x0040, 0x61f1,
+       0x6833, 0x0001, 0x683e, 0x6847, 0x0000, 0x127e, 0x0f7e, 0x2091,
+       0x2200, 0x027f, 0x1078, 0x1d28, 0x00c0, 0x61f4, 0x127f, 0x1078,
+       0x6ae5, 0x0d7f, 0x0f7f, 0x007c, 0x127f, 0x6843, 0x0000, 0x7803,
+       0x0002, 0x780c, 0xa015, 0x0040, 0x6206, 0x6a3a, 0x780f, 0x0000,
+       0x6833, 0x0000, 0x683f, 0x0000, 0x0078, 0x61f1, 0x683a, 0x6836,
+       0x0078, 0x6200, 0x601c, 0xa084, 0x000f, 0x1079, 0x6210, 0x007c,
+       0x6219, 0x621e, 0x663f, 0x6758, 0x621e, 0x663f, 0x6758, 0x6219,
+       0x621e, 0x1078, 0x6010, 0x1078, 0x6109, 0x007c, 0x157e, 0x137e,
+       0x147e, 0x0c7e, 0x0f7e, 0x6004, 0xa08a, 0x0044, 0x10c8, 0x1328,
+       0x6118, 0x2178, 0x79a0, 0xd1bc, 0x0040, 0x623b, 0x7900, 0xd1f4,
+       0x0040, 0x6237, 0x7914, 0xa18c, 0x00ff, 0x0078, 0x6240, 0x2009,
+       0x0000, 0x0078, 0x6240, 0xa1f8, 0x293f, 0x2f0c, 0xa18c, 0x00ff,
+       0x2c78, 0x2061, 0x0100, 0x619a, 0xa08a, 0x0040, 0x00c8, 0x6292,
+       0x1079, 0x6250, 0x0f7f, 0x0c7f, 0x147f, 0x137f, 0x157f, 0x007c,
+       0x62f8, 0x6340, 0x6368, 0x6403, 0x6433, 0x643b, 0x6462, 0x6473,
+       0x6484, 0x648c, 0x64a4, 0x648c, 0x650f, 0x6473, 0x6530, 0x6538,
+       0x6484, 0x6538, 0x6549, 0x6290, 0x6290, 0x6290, 0x6290, 0x6290,
+       0x6290, 0x6290, 0x6290, 0x6290, 0x6290, 0x6290, 0x6d05, 0x6d2a,
+       0x6d3f, 0x6d62, 0x6d83, 0x6462, 0x6290, 0x6462, 0x648c, 0x6290,
+       0x6368, 0x6403, 0x6290, 0x72ac, 0x648c, 0x6290, 0x72cc, 0x648c,
+       0x6290, 0x6290, 0x62f3, 0x62a1, 0x6290, 0x72f1, 0x7368, 0x7450,
+       0x6290, 0x7461, 0x645c, 0x747d, 0x6290, 0x6d98, 0x6290, 0x6290,
+       0x1078, 0x1328, 0x2100, 0x1079, 0x629b, 0x0f7f, 0x0c7f, 0x147f,
+       0x137f, 0x157f, 0x007c, 0x629f, 0x629f, 0x629f, 0x62d5, 0x1078,
+       0x1328, 0x0d7e, 0x20a1, 0x020b, 0x1078, 0x6567, 0x7810, 0x2068,
+       0x20a3, 0x2414, 0x20a3, 0x0018, 0x20a3, 0x0800, 0x683c, 0x20a2,
+       0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
+       0x6850, 0x20a2, 0x6854, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000,
+       0x60c3, 0x0018, 0x1078, 0x6c2d, 0x0d7f, 0x007c, 0x0d7e, 0x7818,
+       0x2068, 0x68a0, 0xa082, 0x007e, 0x0048, 0x62d2, 0xa085, 0x0001,
+       0x0d7f, 0x007c, 0xa006, 0x0078, 0x62d0, 0x0d7e, 0x20a1, 0x020b,
+       0x1078, 0x6567, 0x20a3, 0x0500, 0x20a3, 0x0000, 0x7810, 0xa0e8,
+       0x000f, 0x6808, 0x20a2, 0x680c, 0x20a2, 0x6810, 0x20a2, 0x6814,
+       0x20a2, 0x6818, 0x20a2, 0x681c, 0x20a2, 0x60c3, 0x0010, 0x1078,
+       0x6c2d, 0x0d7f, 0x007c, 0x6030, 0x609a, 0x1078, 0x6c2d, 0x007c,
+       0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3, 0x5200, 0x20a3, 0x0000,
+       0x0d7e, 0x2069, 0xa351, 0x6804, 0xd084, 0x0040, 0x6312, 0x6828,
+       0x20a3, 0x0000, 0x017e, 0x1078, 0x24fa, 0x21a2, 0x017f, 0x0d7f,
+       0x0078, 0x6317, 0x0d7f, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9,
+       0x0004, 0x2099, 0xa305, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xa301,
+       0x53a6, 0x7818, 0xa080, 0x0028, 0x2004, 0xa082, 0x007f, 0x0048,
+       0x6331, 0x2001, 0xa31a, 0x20a6, 0x2001, 0xa31b, 0x20a6, 0x0078,
+       0x6337, 0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff, 0x20a2, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x1078, 0x6c2d, 0x007c,
+       0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3, 0x0500, 0x20a3, 0x0000,
+       0x7818, 0xa080, 0x0028, 0x2004, 0xa082, 0x007f, 0x0048, 0x6358,
+       0x2001, 0xa31a, 0x20a6, 0x2001, 0xa31b, 0x20a6, 0x0078, 0x635e,
+       0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff, 0x20a2, 0x20a9, 0x0004,
+       0x2099, 0xa305, 0x53a6, 0x60c3, 0x0010, 0x1078, 0x6c2d, 0x007c,
+       0x20a1, 0x020b, 0x1078, 0x6567, 0x0c7e, 0x7818, 0x2060, 0x2001,
+       0x0000, 0x1078, 0x48a2, 0x0c7f, 0x7818, 0xa080, 0x0028, 0x2004,
+       0xa086, 0x007e, 0x00c0, 0x6383, 0x20a3, 0x0400, 0x620c, 0xc2b4,
+       0x620e, 0x0078, 0x6385, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x7818,
+       0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x00c0, 0x63d2, 0x2099,
+       0xa58c, 0x33a6, 0x9398, 0x33a6, 0x9398, 0x3304, 0xa084, 0x3fff,
+       0x20a2, 0x9398, 0x33a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099, 0xa305, 0x53a6,
+       0x20a9, 0x0004, 0x2099, 0xa301, 0x53a6, 0x20a9, 0x0010, 0x20a3,
+       0x0000, 0x00f0, 0x63af, 0x2099, 0xa594, 0x3304, 0xc0dd, 0x20a2,
+       0x2001, 0xa371, 0x2004, 0xd0e4, 0x0040, 0x63ca, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x9398, 0x9398, 0x9398, 0x33a6, 0x20a9, 0x0004,
+       0x0078, 0x63cc, 0x20a9, 0x0007, 0x20a3, 0x0000, 0x00f0, 0x63cc,
+       0x0078, 0x63f2, 0x2099, 0xa58c, 0x20a9, 0x0008, 0x53a6, 0x20a9,
+       0x0004, 0x2099, 0xa305, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xa301,
+       0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0, 0x63e3, 0x20a9,
+       0x0008, 0x20a3, 0x0000, 0x00f0, 0x63e9, 0x2099, 0xa594, 0x20a9,
+       0x0008, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0, 0x63f4,
+       0x20a9, 0x000a, 0x20a3, 0x0000, 0x00f0, 0x63fa, 0x60c3, 0x0074,
+       0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3,
+       0x2010, 0x20a3, 0x0014, 0x20a3, 0x0800, 0x20a3, 0x2000, 0xa006,
+       0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x0f7e, 0x2079, 0xa351,
+       0x7904, 0x0f7f, 0xd1ac, 0x00c0, 0x641f, 0xa085, 0x0020, 0xd1a4,
+       0x0040, 0x6424, 0xa085, 0x0010, 0xa085, 0x0002, 0x0d7e, 0x0078,
+       0x64ed, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014,
+       0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3,
+       0x5000, 0x0078, 0x6385, 0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3,
+       0x2110, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
+       0x0014, 0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x65ef,
+       0x0078, 0x6466, 0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0200,
+       0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0004,
+       0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3,
+       0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3,
+       0x0008, 0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x65f8,
+       0x20a3, 0x0200, 0x0078, 0x6385, 0x20a1, 0x020b, 0x1078, 0x65f8,
+       0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828, 0xa005, 0x0040, 0x649b,
+       0x20a2, 0x0078, 0x649d, 0x20a3, 0x0003, 0x7810, 0x20a2, 0x60c3,
+       0x0008, 0x1078, 0x6c2d, 0x007c, 0x0d7e, 0x20a1, 0x020b, 0x1078,
+       0x65f8, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, 0x0800, 0x7818,
+       0x2068, 0x6894, 0xa086, 0x0014, 0x00c0, 0x64ca, 0x6998, 0xa184,
+       0xc000, 0x00c0, 0x64c6, 0xd1ec, 0x0040, 0x64c2, 0x20a3, 0x2100,
+       0x0078, 0x64cc, 0x20a3, 0x0100, 0x0078, 0x64cc, 0x20a3, 0x0400,
+       0x0078, 0x64cc, 0x20a3, 0x0700, 0xa006, 0x20a2, 0x20a2, 0x20a2,
+       0x20a2, 0x20a2, 0x0f7e, 0x2079, 0xa351, 0x7904, 0x0f7f, 0xd1ac,
+       0x00c0, 0x64dc, 0xa085, 0x0020, 0xd1a4, 0x0040, 0x64e1, 0xa085,
+       0x0010, 0x2009, 0xa373, 0x210c, 0xd184, 0x0040, 0x64eb, 0x699c,
+       0xd18c, 0x0040, 0x64ed, 0xa085, 0x0002, 0x027e, 0x2009, 0xa371,
+       0x210c, 0xd1e4, 0x0040, 0x64fb, 0xc0c5, 0xa094, 0x0030, 0xa296,
+       0x0010, 0x0040, 0x6505, 0xd1ec, 0x0040, 0x6505, 0xa094, 0x0030,
+       0xa296, 0x0010, 0x0040, 0x6505, 0xc0bd, 0x027f, 0x20a2, 0x20a2,
+       0x20a2, 0x60c3, 0x0014, 0x1078, 0x6c2d, 0x0d7f, 0x007c, 0x20a1,
+       0x020b, 0x1078, 0x65f8, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3,
+       0x0000, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x6c2d, 0x007c,
+       0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0200, 0x0078, 0x62fe,
+       0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0100, 0x20a3, 0x0000,
+       0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x1078, 0x6c2d,
+       0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a1, 0x020b, 0x1078,
+       0x65f8, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x000b, 0x20a3,
+       0x0000, 0x60c3, 0x0008, 0x1078, 0x6c2d, 0x007c, 0x027e, 0x037e,
+       0x047e, 0x2019, 0x3200, 0x2021, 0x0800, 0x0078, 0x656e, 0x027e,
+       0x037e, 0x047e, 0x2019, 0x2200, 0x2021, 0x0100, 0x20e1, 0x9080,
+       0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2014, 0xa286, 0x007e,
+       0x00c0, 0x6581, 0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffe, 0x0078,
+       0x65b6, 0xa286, 0x007f, 0x00c0, 0x658d, 0x0d7e, 0xa385, 0x00ff,
+       0x20a2, 0x20a3, 0xfffd, 0x0078, 0x65a4, 0xd2bc, 0x0040, 0x65ac,
+       0xa286, 0x0080, 0x0d7e, 0x00c0, 0x659c, 0xa385, 0x00ff, 0x20a2,
+       0x20a3, 0xfffc, 0x0078, 0x65a4, 0xa2e8, 0xa434, 0x2d6c, 0x6810,
+       0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68,
+       0x2da6, 0x0d7f, 0x0078, 0x65ba, 0x0d7e, 0xa2e8, 0xa434, 0x2d6c,
+       0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000,
+       0x6230, 0x22a2, 0xa485, 0x0029, 0x20a2, 0x047f, 0x037f, 0x20a3,
+       0x0000, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3,
+       0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x027e,
+       0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a3, 0x02ff, 0x2011, 0xfffc,
+       0x22a2, 0x0d7e, 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f,
+       0x20a3, 0x2029, 0x20a3, 0x0000, 0x0078, 0x65c1, 0x20a3, 0x0100,
+       0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3, 0x0000, 0x007c, 0x027e,
+       0x037e, 0x047e, 0x2019, 0x3300, 0x2021, 0x0800, 0x0078, 0x65ff,
+       0x027e, 0x037e, 0x047e, 0x2019, 0x2300, 0x2021, 0x0100, 0x20e1,
+       0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa092,
+       0x007e, 0x0048, 0x661c, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810,
+       0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68,
+       0x2da6, 0x0d7f, 0x0078, 0x662a, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c,
+       0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000,
+       0x6230, 0x22a2, 0xa485, 0x0098, 0x20a2, 0x20a3, 0x0000, 0x047f,
+       0x037f, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2,
+       0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x0c7e,
+       0x0f7e, 0x6004, 0xa08a, 0x0085, 0x1048, 0x1328, 0xa08a, 0x008c,
+       0x10c8, 0x1328, 0x6118, 0x2178, 0x79a0, 0xd1bc, 0x0040, 0x665d,
+       0x7900, 0xd1f4, 0x0040, 0x6659, 0x7914, 0xa18c, 0x00ff, 0x0078,
+       0x6662, 0x2009, 0x0000, 0x0078, 0x6662, 0xa1f8, 0x293f, 0x2f0c,
+       0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0xa082, 0x0085,
+       0x1079, 0x666d, 0x0f7f, 0x0c7f, 0x007c, 0x6676, 0x6681, 0x669c,
+       0x6674, 0x6674, 0x6674, 0x6676, 0x1078, 0x1328, 0x147e, 0x20a1,
+       0x020b, 0x1078, 0x66af, 0x60c3, 0x0000, 0x1078, 0x6c2d, 0x147f,
+       0x007c, 0x147e, 0x20a1, 0x020b, 0x1078, 0x66e3, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x7808, 0x20a2, 0x7810, 0x20a2, 0x20a3, 0x0000,
+       0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c,
+       0x1078, 0x6c2d, 0x147f, 0x007c, 0x147e, 0x20a1, 0x020b, 0x1078,
+       0x6724, 0x20a3, 0x0003, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x60c3, 0x0004, 0x1078, 0x6c2d, 0x147f, 0x007c, 0x027e,
+       0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004,
+       0xa092, 0x007e, 0x0048, 0x66ce, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c,
+       0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a,
+       0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x66dd, 0x0d7e, 0xa0e8,
+       0xa434, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2,
+       0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0009, 0x20a3,
+       0x0000, 0x0078, 0x65c1, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000,
+       0x7818, 0xa080, 0x0028, 0x2004, 0xa092, 0x007e, 0x0048, 0x6702,
+       0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x8400, 0x20a2,
+       0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f,
+       0x0078, 0x6711, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085,
+       0x8400, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230,
+       0x22a2, 0x20a3, 0x0099, 0x20a3, 0x0000, 0x1078, 0x6c1c, 0x22a2,
+       0x20a3, 0x0000, 0x7a08, 0x22a2, 0x7a10, 0x22a2, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x027f, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1,
+       0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa092, 0x007e, 0x0048,
+       0x6743, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x8500,
+       0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6,
+       0x0d7f, 0x0078, 0x6752, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810,
+       0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000,
+       0x6230, 0x22a2, 0x20a3, 0x0099, 0x20a3, 0x0000, 0x0078, 0x6715,
+       0x0c7e, 0x0f7e, 0x2c78, 0x7804, 0xa08a, 0x0040, 0x1048, 0x1328,
+       0xa08a, 0x0053, 0x10c8, 0x1328, 0x7918, 0x2160, 0x61a0, 0xd1bc,
+       0x0040, 0x6777, 0x6100, 0xd1f4, 0x0040, 0x6773, 0x6114, 0xa18c,
+       0x00ff, 0x0078, 0x677c, 0x2009, 0x0000, 0x0078, 0x677c, 0xa1e0,
+       0x293f, 0x2c0c, 0xa18c, 0x00ff, 0x2061, 0x0100, 0x619a, 0xa082,
+       0x0040, 0x1079, 0x6786, 0x0f7f, 0x0c7f, 0x007c, 0x679b, 0x68a9,
+       0x684a, 0x6a59, 0x6799, 0x6799, 0x6799, 0x6799, 0x6799, 0x6799,
+       0x6799, 0x6f5e, 0x6f6f, 0x6f80, 0x6f91, 0x6799, 0x748e, 0x6799,
+       0x6f4d, 0x1078, 0x1328, 0x0d7e, 0x157e, 0x147e, 0x780b, 0xffff,
+       0x20a1, 0x020b, 0x1078, 0x6806, 0x7910, 0x2168, 0x6948, 0x7922,
+       0x21a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x694c, 0xa184, 0x000f,
+       0x00c0, 0x67b6, 0x2001, 0x0005, 0x0078, 0x67c0, 0xd184, 0x0040,
+       0x67bd, 0x2001, 0x0004, 0x0078, 0x67c0, 0xa084, 0x0006, 0x8004,
+       0x017e, 0x2008, 0x7830, 0xa084, 0x00ff, 0x8007, 0xa105, 0x017f,
+       0x20a2, 0xd1ac, 0x0040, 0x67d0, 0x20a3, 0x0002, 0x0078, 0x67dc,
+       0xd1b4, 0x0040, 0x67d7, 0x20a3, 0x0001, 0x0078, 0x67dc, 0x20a3,
+       0x0000, 0x2230, 0x0078, 0x67de, 0x6a80, 0x6e7c, 0x20a9, 0x0008,
+       0xad80, 0x0017, 0x200c, 0x810f, 0x21a2, 0x8000, 0x00f0, 0x67e2,
+       0x22a2, 0x26a2, 0x60c3, 0x0020, 0x20e1, 0x9080, 0x6014, 0xa084,
+       0x0004, 0xa085, 0x0009, 0x6016, 0x2001, 0xa5c7, 0x2003, 0x07d0,
+       0x2001, 0xa5c6, 0x2003, 0x0009, 0x2001, 0xa5cc, 0x2003, 0x0002,
+       0x1078, 0x157e, 0x147f, 0x157f, 0x0d7f, 0x007c, 0x20e1, 0x9080,
+       0x20e1, 0x4000, 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, 0xa294,
+       0x00ff, 0x2202, 0x8217, 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc,
+       0x0040, 0x682c, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085,
+       0x0600, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68,
+       0x2da6, 0x0d7f, 0x0078, 0x683b, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c,
+       0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3,
+       0x0000, 0x6130, 0x21a2, 0x20a3, 0x0829, 0x20a3, 0x0000, 0x22a2,
+       0x20a3, 0x0000, 0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x20a1, 0x020b,
+       0x1078, 0x686a, 0x7810, 0x2068, 0x6860, 0x20a2, 0x685c, 0x20a2,
+       0x6880, 0x20a2, 0x687c, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2,
+       0x20a2, 0x60c3, 0x000c, 0x1078, 0x6c2d, 0x147f, 0x137f, 0x157f,
+       0x0d7f, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818,
+       0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x6888, 0x0d7e, 0xa0e8,
+       0xa434, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2, 0x6814, 0x20a2,
+       0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6897,
+       0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2,
+       0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3,
+       0x0889, 0x20a3, 0x0000, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000,
+       0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f,
+       0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x7810, 0xa06d, 0x1078,
+       0x488f, 0x0040, 0x68bd, 0x684c, 0xa084, 0x2020, 0xa086, 0x2020,
+       0x00c0, 0x68bd, 0x7824, 0xc0cd, 0x7826, 0x20a1, 0x020b, 0x1078,
+       0x6a12, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x7810,
+       0xa084, 0xf000, 0x00c0, 0x68d4, 0x7810, 0xa084, 0x0700, 0x8007,
+       0x1079, 0x68dc, 0x0078, 0x68d7, 0xa006, 0x1079, 0x68dc, 0x147f,
+       0x137f, 0x157f, 0x0d7f, 0x007c, 0x68e6, 0x697e, 0x6989, 0x69b3,
+       0x69c7, 0x69e3, 0x69ee, 0x68e4, 0x1078, 0x1328, 0x017e, 0x037e,
+       0x694c, 0xa18c, 0x0003, 0x0040, 0x68f1, 0xa186, 0x0003, 0x00c0,
+       0x6900, 0x6b78, 0x7824, 0xd0cc, 0x0040, 0x68f7, 0xc3e5, 0x23a2,
+       0x6868, 0x20a2, 0x6864, 0x20a2, 0x037f, 0x017f, 0x0078, 0x69be,
+       0xa186, 0x0001, 0x10c0, 0x1328, 0x6b78, 0x7824, 0xd0cc, 0x0040,
+       0x690a, 0xc3e5, 0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x22a2,
+       0x6874, 0x20a2, 0x22a2, 0x687c, 0x20a2, 0x2009, 0x0018, 0xa384,
+       0x0300, 0x0040, 0x6978, 0xd3c4, 0x0040, 0x6920, 0x687c, 0xa108,
+       0xd3cc, 0x0040, 0x6925, 0x6874, 0xa108, 0x157e, 0x20a9, 0x000d,
+       0xad80, 0x0020, 0x201c, 0x831f, 0x23a2, 0x8000, 0x00f0, 0x692a,
+       0x157f, 0x22a2, 0x22a2, 0x22a2, 0xa184, 0x0003, 0x0040, 0x6978,
+       0x20a1, 0x020b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x007e, 0x7818,
+       0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x6958, 0x0d7e, 0xa0e8,
+       0xa434, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2,
+       0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6967,
+       0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2,
+       0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x007f,
+       0x7b24, 0xd3cc, 0x0040, 0x6970, 0x20a3, 0x0889, 0x0078, 0x6972,
+       0x20a3, 0x0898, 0x20a2, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000,
+       0x61c2, 0x037f, 0x017f, 0x1078, 0x6c2d, 0x007c, 0x2011, 0x0008,
+       0x7824, 0xd0cc, 0x0040, 0x6985, 0xc2e5, 0x22a2, 0xa016, 0x0078,
+       0x69bc, 0x2011, 0x0302, 0x7824, 0xd0cc, 0x0040, 0x6990, 0xc2e5,
+       0x22a2, 0xa016, 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, 0x6c2d, 0x007c, 0x2011, 0x0028, 0x7824, 0xd0cc, 0x0040,
+       0x69ba, 0xc2e5, 0x22a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2,
+       0x22a2, 0x22a2, 0x60c3, 0x0018, 0x1078, 0x6c2d, 0x007c, 0x2011,
+       0x0100, 0x7824, 0xd0cc, 0x0040, 0x69ce, 0xc2e5, 0x22a2, 0xa016,
+       0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x0008, 0x22a2,
+       0x7834, 0xa084, 0x00ff, 0x20a2, 0x22a2, 0x22a2, 0x60c3, 0x0020,
+       0x1078, 0x6c2d, 0x007c, 0x2011, 0x0008, 0x7824, 0xd0cc, 0x0040,
+       0x69ea, 0xc2e5, 0x22a2, 0xa016, 0x0078, 0x69bc, 0x037e, 0x7b10,
+       0xa384, 0xff00, 0x7812, 0xa384, 0x00ff, 0x8001, 0x00c0, 0x6a01,
+       0x7824, 0xd0cc, 0x0040, 0x69fd, 0xc2e5, 0x22a2, 0x037f, 0x0078,
+       0x69bc, 0x047e, 0x2021, 0x0800, 0x007e, 0x7824, 0xd0cc, 0x007f,
+       0x0040, 0x6a0b, 0xc4e5, 0x24a2, 0x047f, 0x22a2, 0x20a2, 0x037f,
+       0x0078, 0x69be, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818,
+       0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x6a30, 0x0d7e, 0xa0e8,
+       0xa434, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2,
+       0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6a3f,
+       0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2,
+       0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x7824,
+       0xd0cc, 0x0040, 0x6a47, 0x20a3, 0x0889, 0x0078, 0x6a49, 0x20a3,
+       0x0898, 0x20a3, 0x0000, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000,
+       0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f,
+       0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x017e, 0x037e, 0x7810,
+       0xa084, 0x0700, 0x8007, 0x1079, 0x6a6c, 0x037f, 0x017f, 0x147f,
+       0x137f, 0x157f, 0x0d7f, 0x007c, 0x6a74, 0x6a74, 0x6a76, 0x6a74,
+       0x6a74, 0x6a74, 0x6a9b, 0x6a74, 0x1078, 0x1328, 0x7910, 0xa18c,
+       0xf8ff, 0xa18d, 0x0600, 0x7912, 0x20a1, 0x020b, 0x2009, 0x0003,
+       0x1078, 0x6aa5, 0x0d7e, 0x2069, 0xa351, 0x6804, 0xd0bc, 0x0040,
+       0x6a90, 0x682c, 0xa084, 0x00ff, 0x8007, 0x20a2, 0x0078, 0x6a92,
+       0x20a3, 0x3f00, 0x0d7f, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0001,
+       0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x2009, 0x0003, 0x1078,
+       0x6aa5, 0x20a3, 0x7f00, 0x0078, 0x6a93, 0x027e, 0x20e1, 0x9080,
+       0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040,
+       0x6ac3, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0100,
+       0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6,
+       0x0d7f, 0x0078, 0x6ad2, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810,
+       0xa085, 0x0100, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000,
+       0x6230, 0x22a2, 0x20a3, 0x0888, 0xa18d, 0x0008, 0x21a2, 0x1078,
+       0x6c1c, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x0e7e, 0x0d7e, 0x0c7e,
+       0x057e, 0x047e, 0x037e, 0x2061, 0x0100, 0x2071, 0xa300, 0x6130,
+       0x7818, 0x2068, 0x68a0, 0x2028, 0xd0bc, 0x00c0, 0x6afc, 0x6910,
+       0x6a14, 0x6430, 0x0078, 0x6b00, 0x6910, 0x6a14, 0x7368, 0x746c,
+       0x781c, 0xa086, 0x0006, 0x0040, 0x6b5f, 0xd5bc, 0x0040, 0x6b10,
+       0xa185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x0078, 0x6b17,
+       0xa185, 0x0100, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, 0x6073,
+       0x0809, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e,
+       0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086,
+       0x7810, 0x2070, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6,
+       0x7008, 0x60ca, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5,
+       0x60d7, 0x0000, 0xa582, 0x0080, 0x0048, 0x6b49, 0x6a00, 0xd2f4,
+       0x0040, 0x6b47, 0x6a14, 0xa294, 0x00ff, 0x0078, 0x6b49, 0x2011,
+       0x0000, 0x629e, 0x6017, 0x0016, 0x2009, 0x07d0, 0x60c4, 0xa084,
+       0xfff0, 0xa005, 0x0040, 0x6b56, 0x2009, 0x1b58, 0x1078, 0x595f,
+       0x037f, 0x047f, 0x057f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x7810,
+       0x2070, 0x704c, 0xa084, 0x0003, 0xa086, 0x0002, 0x0040, 0x6bb7,
+       0xd5bc, 0x0040, 0x6b73, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a,
+       0x646e, 0x0078, 0x6b7a, 0xa185, 0x0100, 0x6062, 0x6266, 0x606b,
+       0x0000, 0x646e, 0x6073, 0x0880, 0x6077, 0x0008, 0x688c, 0x8000,
+       0xa084, 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00,
+       0x6086, 0x7808, 0x6082, 0x7060, 0x608a, 0x705c, 0x608e, 0x7080,
+       0x60c6, 0x707c, 0x60ca, 0x707c, 0x792c, 0xa108, 0x792e, 0x7080,
+       0x7928, 0xa109, 0x792a, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af,
+       0x95d5, 0x60d7, 0x0000, 0xa582, 0x0080, 0x0048, 0x6bb2, 0x6a00,
+       0xd2f4, 0x0040, 0x6bb0, 0x6a14, 0xa294, 0x00ff, 0x0078, 0x6bb2,
+       0x2011, 0x0000, 0x629e, 0x6017, 0x0012, 0x0078, 0x6b4c, 0xd5bc,
+       0x0040, 0x6bc2, 0xa185, 0x0700, 0x6062, 0x6266, 0x636a, 0x646e,
+       0x0078, 0x6bc9, 0xa185, 0x0700, 0x6062, 0x6266, 0x606b, 0x0000,
+       0x646e, 0x1078, 0x488f, 0x0040, 0x6bdf, 0x0d7e, 0x7810, 0xa06d,
+       0x684c, 0x0d7f, 0xa084, 0x2020, 0xa086, 0x2020, 0x00c0, 0x6bdf,
+       0x7824, 0xc0cd, 0x7826, 0x6073, 0x0889, 0x0078, 0x6be1, 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, 0x6c0f, 0x6a00, 0xd2f4, 0x0040, 0x6c0d,
+       0x6a14, 0xa294, 0x00ff, 0x0078, 0x6c0f, 0x2011, 0x0000, 0x629e,
+       0x7824, 0xd0cc, 0x0040, 0x6c18, 0x6017, 0x0016, 0x0078, 0x6b4c,
+       0x6017, 0x0012, 0x0078, 0x6b4c, 0x7a18, 0xa280, 0x0023, 0x2014,
+       0x8210, 0xa294, 0x00ff, 0x2202, 0x8217, 0x007c, 0x0d7e, 0x2069,
+       0xa5ab, 0x6843, 0x0001, 0x0d7f, 0x007c, 0x20e1, 0x9080, 0x60a3,
+       0x0056, 0x60a7, 0x9575, 0x1078, 0x6c38, 0x1078, 0x594f, 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, 0x2061, 0x0100, 0x2069, 0x0140, 0x6904, 0xa194,
+       0x4000, 0x0040, 0x6c89, 0x1078, 0x6c41, 0x6803, 0x1000, 0x6803,
+       0x0000, 0x0c7e, 0x2061, 0xa5ab, 0x6128, 0xa192, 0x00c8, 0x00c8,
+       0x6c76, 0x8108, 0x612a, 0x6124, 0x0c7f, 0x81ff, 0x0040, 0x6c84,
+       0x1078, 0x594f, 0x1078, 0x6c38, 0x0078, 0x6c84, 0x6124, 0xa1e5,
+       0x0000, 0x0040, 0x6c81, 0x1078, 0xa241, 0x2009, 0x0014, 0x1078,
+       0x756c, 0x0c7f, 0x0078, 0x6c84, 0x027f, 0x017f, 0x0d7f, 0x0c7f,
+       0x007c, 0x2001, 0xa5c7, 0x2004, 0xa005, 0x00c0, 0x6c84, 0x0c7e,
+       0x2061, 0xa5ab, 0x6128, 0xa192, 0x0003, 0x00c8, 0x6c76, 0x8108,
+       0x612a, 0x0c7f, 0x1078, 0x594f, 0x1078, 0x4171, 0x0078, 0x6c84,
+       0x0c7e, 0x0d7e, 0x0e7e, 0x017e, 0x027e, 0x1078, 0x5967, 0x2071,
+       0xa5ab, 0x713c, 0x81ff, 0x0040, 0x6cca, 0x2061, 0x0100, 0x2069,
+       0x0140, 0x6904, 0xa194, 0x4000, 0x0040, 0x6cd0, 0x6803, 0x1000,
+       0x6803, 0x0000, 0x037e, 0x2019, 0x0001, 0x1078, 0x6e6c, 0x037f,
+       0x713c, 0x2160, 0x1078, 0xa241, 0x2009, 0x004a, 0x1078, 0x756c,
+       0x0078, 0x6cca, 0x027f, 0x017f, 0x0e7f, 0x0d7f, 0x0c7f, 0x007c,
+       0x0078, 0x6cba, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x057e, 0x047e,
+       0x007e, 0x127e, 0x2091, 0x8000, 0x6018, 0x2068, 0x6ca0, 0x2071,
+       0xa5ab, 0x7018, 0x2068, 0x8dff, 0x0040, 0x6cfc, 0x68a0, 0xa406,
+       0x0040, 0x6cee, 0x6854, 0x2068, 0x0078, 0x6ce3, 0x6010, 0x2060,
+       0x643c, 0x6540, 0x6e48, 0x2d60, 0x1078, 0x466a, 0x0040, 0x6cfc,
+       0x1078, 0x7045, 0xa085, 0x0001, 0x127f, 0x007f, 0x047f, 0x057f,
+       0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x20a1, 0x020b, 0x1078,
+       0x6567, 0x20a3, 0x1200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x781c,
+       0xa086, 0x0004, 0x00c0, 0x6d17, 0x6098, 0x0078, 0x6d18, 0x6030,
+       0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a9, 0x0010, 0xa006,
+       0x20a2, 0x00f0, 0x6d20, 0x20a2, 0x20a2, 0x60c3, 0x002c, 0x1078,
+       0x6c2d, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x6567,
+       0x20a3, 0x0f00, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2,
+       0x60c3, 0x0008, 0x1078, 0x6c2d, 0x147f, 0x157f, 0x007c, 0x157e,
+       0x147e, 0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0200, 0x20a3,
+       0x0000, 0x20a9, 0x0006, 0x2011, 0xa340, 0x2019, 0xa341, 0x23a6,
+       0x22a6, 0xa398, 0x0002, 0xa290, 0x0002, 0x00f0, 0x6d4f, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x1078, 0x6c2d, 0x147f,
+       0x157f, 0x007c, 0x157e, 0x147e, 0x017e, 0x027e, 0x20a1, 0x020b,
+       0x1078, 0x65cf, 0x1078, 0x65e6, 0x7810, 0xa080, 0x0000, 0x2004,
+       0xa080, 0x0015, 0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6,
+       0xa080, 0x0004, 0x8003, 0x60c2, 0x1078, 0x6c2d, 0x027f, 0x017f,
+       0x147f, 0x157f, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078,
+       0x6567, 0x20a3, 0x6200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808,
+       0x20a2, 0x60c3, 0x0008, 0x1078, 0x6c2d, 0x147f, 0x157f, 0x007c,
+       0x157e, 0x147e, 0x017e, 0x027e, 0x20a1, 0x020b, 0x1078, 0x6567,
+       0x7810, 0xa080, 0x0000, 0x2004, 0xa080, 0x0017, 0x2098, 0x7808,
+       0xa088, 0x0002, 0x21a8, 0x53a6, 0x8003, 0x60c2, 0x1078, 0x6c2d,
+       0x027f, 0x017f, 0x147f, 0x157f, 0x007c, 0x0e7e, 0x0c7e, 0x007e,
+       0x127e, 0x2091, 0x8000, 0x2071, 0xa5ab, 0x700c, 0x2060, 0x8cff,
+       0x0040, 0x6dd1, 0x1078, 0x8c3b, 0x00c0, 0x6dc8, 0x1078, 0x7a05,
+       0x600c, 0x007e, 0x1078, 0x753d, 0x1078, 0x7045, 0x0c7f, 0x0078,
+       0x6dbf, 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, 0xa5ab, 0x7024, 0x2060, 0x8cff, 0x0040, 0x6e2a,
+       0x1078, 0x6c41, 0x68c3, 0x0000, 0x1078, 0x595a, 0x2009, 0x0013,
+       0x1078, 0x756c, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0040, 0x6e0d,
+       0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x0040, 0x6e1f, 0x7803,
+       0x1000, 0x7803, 0x0000, 0x0078, 0x6e1f, 0xd084, 0x0040, 0x6e14,
+       0x6827, 0x0001, 0x0078, 0x6e16, 0x00f0, 0x6dfc, 0x7804, 0xa084,
+       0x1000, 0x0040, 0x6e1f, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824,
+       0x007f, 0x017f, 0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f,
+       0x127f, 0x007c, 0x2001, 0xa300, 0x2004, 0xa096, 0x0001, 0x0040,
+       0x6e62, 0xa096, 0x0004, 0x0040, 0x6e62, 0x6817, 0x0008, 0x68c3,
+       0x0000, 0x2011, 0x4129, 0x1078, 0x58d4, 0x20a9, 0x01f4, 0x6824,
+       0xd094, 0x0040, 0x6e50, 0x6827, 0x0004, 0x7804, 0xa084, 0x4000,
+       0x0040, 0x6e62, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0x6e62,
+       0xd084, 0x0040, 0x6e57, 0x6827, 0x0001, 0x0078, 0x6e59, 0x00f0,
+       0x6e3f, 0x7804, 0xa084, 0x1000, 0x0040, 0x6e62, 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, 0xa5ab, 0x703c, 0x2060, 0x8cff,
+       0x0040, 0x6ee8, 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x00c0,
+       0x6e86, 0x68c7, 0x0000, 0x68cb, 0x0008, 0x1078, 0x5967, 0x1078,
+       0x1f31, 0x047e, 0x057e, 0x2009, 0x017f, 0x212c, 0x200b, 0x00a5,
+       0x2021, 0x0169, 0x2404, 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0,
+       0x6eb7, 0x68c7, 0x0000, 0x68cb, 0x0008, 0x0e7e, 0x0f7e, 0x2079,
+       0x0020, 0x2071, 0xa602, 0x6814, 0xa084, 0x0004, 0xa085, 0x0012,
+       0x6816, 0x7803, 0x0008, 0x7003, 0x0000, 0x0f7f, 0x0e7f, 0x250a,
+       0x057f, 0x047f, 0xa39d, 0x0000, 0x00c0, 0x6ec2, 0x2009, 0x0049,
+       0x1078, 0x756c, 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0040, 0x6ed5,
+       0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x0040, 0x6ee7, 0x7803,
+       0x1000, 0x7803, 0x0000, 0x0078, 0x6ee7, 0xd08c, 0x0040, 0x6edc,
+       0x6827, 0x0002, 0x0078, 0x6ede, 0x00f0, 0x6ec4, 0x7804, 0xa084,
+       0x1000, 0x0040, 0x6ee7, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824,
+       0x007f, 0x017f, 0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f,
+       0x127f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2069, 0xa5ab,
+       0x6a06, 0x127f, 0x0d7f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000,
+       0x2069, 0xa5ab, 0x6a32, 0x127f, 0x0d7f, 0x007c, 0x0f7e, 0x0e7e,
+       0x0c7e, 0x067e, 0x007e, 0x127e, 0x2071, 0xa5ab, 0x7614, 0x2660,
+       0x2678, 0x2091, 0x8000, 0x8cff, 0x0040, 0x6f46, 0x601c, 0xa206,
+       0x00c0, 0x6f41, 0x7014, 0xac36, 0x00c0, 0x6f20, 0x660c, 0x7616,
+       0x7010, 0xac36, 0x00c0, 0x6f2e, 0x2c00, 0xaf36, 0x0040, 0x6f2c,
+       0x2f00, 0x7012, 0x0078, 0x6f2e, 0x7013, 0x0000, 0x660c, 0x067e,
+       0x2c00, 0xaf06, 0x0040, 0x6f37, 0x7e0e, 0x0078, 0x6f38, 0x2678,
+       0x600f, 0x0000, 0x1078, 0x8c01, 0x1078, 0x7045, 0x0c7f, 0x0078,
+       0x6f13, 0x2c78, 0x600c, 0x2060, 0x0078, 0x6f13, 0x127f, 0x007f,
+       0x067f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0x157e, 0x147e, 0x20a1,
+       0x020b, 0x1078, 0x6806, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2,
+       0x20a2, 0x20a2, 0x20a3, 0x1000, 0x0078, 0x6fa0, 0x157e, 0x147e,
+       0x20a1, 0x020b, 0x1078, 0x6806, 0x7810, 0x20a2, 0xa006, 0x20a2,
+       0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x4000, 0x0078, 0x6fa0, 0x157e,
+       0x147e, 0x20a1, 0x020b, 0x1078, 0x6806, 0x7810, 0x20a2, 0xa006,
+       0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x2000, 0x0078, 0x6fa0,
+       0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x6806, 0x7810, 0x20a2,
+       0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0400, 0x0078,
+       0x6fa0, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x6806, 0x7810,
+       0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200,
+       0x1078, 0x7050, 0x60c3, 0x0020, 0x1078, 0x6c2d, 0x147f, 0x157f,
+       0x007c, 0x127e, 0x0c7e, 0x2091, 0x8000, 0x2061, 0x0100, 0x6120,
+       0xd1b4, 0x00c0, 0x6fb8, 0xd1bc, 0x00c0, 0x7002, 0x0078, 0x7042,
+       0x2009, 0x017f, 0x200b, 0x00a1, 0x157e, 0x007e, 0x0d7e, 0x2069,
+       0x0140, 0x20a9, 0x001e, 0x2009, 0x0169, 0x6804, 0xa084, 0x4000,
+       0x0040, 0x6ff9, 0x6020, 0xd0b4, 0x0040, 0x6ff9, 0x6024, 0xd094,
+       0x00c0, 0x6ff9, 0x2104, 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0,
+       0x6ff9, 0x00f0, 0x6fc5, 0x027e, 0x6198, 0xa18c, 0x00ff, 0x8107,
+       0x6130, 0xa18c, 0x00ff, 0xa10d, 0x6088, 0x628c, 0x618e, 0x608b,
+       0xbc91, 0x6043, 0x0001, 0x6043, 0x0000, 0x608a, 0x628e, 0x6024,
+       0xd094, 0x00c0, 0x6ff8, 0x6a04, 0xa294, 0x4000, 0x00c0, 0x6fef,
+       0x027f, 0x0d7f, 0x007f, 0x157f, 0x2009, 0x017f, 0x200b, 0x0000,
+       0x0078, 0x7042, 0x2009, 0x017f, 0x200b, 0x00a1, 0x157e, 0x007e,
+       0x0d7e, 0x2069, 0x0140, 0x20a9, 0x001e, 0x2009, 0x0169, 0x6804,
+       0xa084, 0x4000, 0x0040, 0x703b, 0x6020, 0xd0bc, 0x0040, 0x703b,
+       0x2104, 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0, 0x703b, 0x00f0,
+       0x700f, 0x027e, 0x6164, 0xa18c, 0x00ff, 0x8107, 0x6130, 0xa18c,
+       0x00ff, 0xa10d, 0x6088, 0x628c, 0x608b, 0xbc91, 0x618e, 0x6043,
+       0x0001, 0x6043, 0x0000, 0x608a, 0x628e, 0x6a04, 0xa294, 0x4000,
+       0x00c0, 0x7035, 0x027f, 0x0d7f, 0x007f, 0x157f, 0x2009, 0x017f,
+       0x200b, 0x0000, 0x0c7f, 0x127f, 0x007c, 0x0e7e, 0x2071, 0xa5ab,
+       0x7020, 0xa005, 0x0040, 0x704e, 0x8001, 0x7022, 0x0e7f, 0x007c,
+       0x20a9, 0x0008, 0x20a2, 0x00f0, 0x7052, 0x20a2, 0x20a2, 0x007c,
+       0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x077e, 0x067e, 0x007e, 0x127e,
+       0x2091, 0x8000, 0x2071, 0xa5ab, 0x7614, 0x2660, 0x2678, 0x2039,
+       0x0001, 0x87ff, 0x0040, 0x70f4, 0x8cff, 0x0040, 0x70f4, 0x601c,
+       0xa086, 0x0006, 0x00c0, 0x70ef, 0x88ff, 0x0040, 0x707f, 0x2800,
+       0xac06, 0x00c0, 0x70ef, 0x2039, 0x0000, 0x0078, 0x708a, 0x6018,
+       0xa206, 0x00c0, 0x70ef, 0x85ff, 0x0040, 0x708a, 0x6020, 0xa106,
+       0x00c0, 0x70ef, 0x7024, 0xac06, 0x00c0, 0x70ba, 0x2069, 0x0100,
+       0x68c0, 0xa005, 0x0040, 0x70b5, 0x1078, 0x595a, 0x6817, 0x0008,
+       0x68c3, 0x0000, 0x1078, 0x7188, 0x7027, 0x0000, 0x037e, 0x2069,
+       0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x70aa, 0x6803, 0x0100,
+       0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x70b2,
+       0x6827, 0x0001, 0x037f, 0x0078, 0x70ba, 0x6003, 0x0009, 0x630a,
+       0x0078, 0x70ef, 0x7014, 0xac36, 0x00c0, 0x70c0, 0x660c, 0x7616,
+       0x7010, 0xac36, 0x00c0, 0x70ce, 0x2c00, 0xaf36, 0x0040, 0x70cc,
+       0x2f00, 0x7012, 0x0078, 0x70ce, 0x7013, 0x0000, 0x660c, 0x067e,
+       0x2c00, 0xaf06, 0x0040, 0x70d7, 0x7e0e, 0x0078, 0x70d8, 0x2678,
+       0x89ff, 0x00c0, 0x70e7, 0x600f, 0x0000, 0x6010, 0x2068, 0x1078,
+       0x8a44, 0x0040, 0x70e5, 0x1078, 0x9e70, 0x1078, 0x8c01, 0x1078,
+       0x7045, 0x88ff, 0x00c0, 0x70fe, 0x0c7f, 0x0078, 0x7069, 0x2c78,
+       0x600c, 0x2060, 0x0078, 0x7069, 0xa006, 0x127f, 0x007f, 0x067f,
+       0x077f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x6017, 0x0000,
+       0x0c7f, 0xa8c5, 0x0001, 0x0078, 0x70f5, 0x0f7e, 0x0e7e, 0x0d7e,
+       0x0c7e, 0x067e, 0x027e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071,
+       0xa5ab, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0040, 0x7177, 0x601c,
+       0xa086, 0x0006, 0x00c0, 0x7172, 0x87ff, 0x0040, 0x7125, 0x2700,
+       0xac06, 0x00c0, 0x7172, 0x0078, 0x7130, 0x6018, 0xa206, 0x00c0,
+       0x7172, 0x85ff, 0x0040, 0x7130, 0x6020, 0xa106, 0x00c0, 0x7172,
+       0x703c, 0xac06, 0x00c0, 0x7142, 0x037e, 0x2019, 0x0001, 0x1078,
+       0x6e6c, 0x7033, 0x0000, 0x703f, 0x0000, 0x7043, 0x0000, 0x7047,
+       0x0000, 0x037f, 0x7038, 0xac36, 0x00c0, 0x7148, 0x660c, 0x763a,
+       0x7034, 0xac36, 0x00c0, 0x7156, 0x2c00, 0xaf36, 0x0040, 0x7154,
+       0x2f00, 0x7036, 0x0078, 0x7156, 0x7037, 0x0000, 0x660c, 0x067e,
+       0x2c00, 0xaf06, 0x0040, 0x715f, 0x7e0e, 0x0078, 0x7160, 0x2678,
+       0x600f, 0x0000, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x716a,
+       0x1078, 0x9e70, 0x1078, 0x8c01, 0x87ff, 0x00c0, 0x7181, 0x0c7f,
+       0x0078, 0x7114, 0x2c78, 0x600c, 0x2060, 0x0078, 0x7114, 0xa006,
+       0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f,
+       0x007c, 0x6017, 0x0000, 0x0c7f, 0xa7bd, 0x0001, 0x0078, 0x7178,
+       0x0e7e, 0x2071, 0xa5ab, 0x2001, 0xa300, 0x2004, 0xa086, 0x0002,
+       0x00c0, 0x7196, 0x7007, 0x0005, 0x0078, 0x7198, 0x7007, 0x0000,
+       0x0e7f, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x067e, 0x027e, 0x007e,
+       0x127e, 0x2091, 0x8000, 0x2071, 0xa5ab, 0x2c10, 0x7638, 0x2660,
+       0x2678, 0x8cff, 0x0040, 0x71d8, 0x2200, 0xac06, 0x00c0, 0x71d3,
+       0x7038, 0xac36, 0x00c0, 0x71b6, 0x660c, 0x763a, 0x7034, 0xac36,
+       0x00c0, 0x71c4, 0x2c00, 0xaf36, 0x0040, 0x71c2, 0x2f00, 0x7036,
+       0x0078, 0x71c4, 0x7037, 0x0000, 0x660c, 0x2c00, 0xaf06, 0x0040,
+       0x71cc, 0x7e0e, 0x0078, 0x71cd, 0x2678, 0x600f, 0x0000, 0xa085,
+       0x0001, 0x0078, 0x71d8, 0x2c78, 0x600c, 0x2060, 0x0078, 0x71a9,
+       0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c,
+       0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x007e, 0x127e, 0x2091,
+       0x8000, 0x2071, 0xa5ab, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0040,
+       0x7279, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x00c0, 0x7274,
+       0x7024, 0xac06, 0x00c0, 0x721f, 0x2069, 0x0100, 0x68c0, 0xa005,
+       0x0040, 0x724d, 0x1078, 0x6c41, 0x68c3, 0x0000, 0x1078, 0x7188,
+       0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000,
+       0x0040, 0x7216, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100,
+       0x6824, 0xd084, 0x0040, 0x721e, 0x6827, 0x0001, 0x037f, 0x700c,
+       0xac36, 0x00c0, 0x7225, 0x660c, 0x760e, 0x7008, 0xac36, 0x00c0,
+       0x7233, 0x2c00, 0xaf36, 0x0040, 0x7231, 0x2f00, 0x700a, 0x0078,
+       0x7233, 0x700b, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040,
+       0x723c, 0x7e0e, 0x0078, 0x723d, 0x2678, 0x600f, 0x0000, 0x1078,
+       0x8c27, 0x00c0, 0x7251, 0x1078, 0x2839, 0x1078, 0x8c3b, 0x00c0,
+       0x726d, 0x1078, 0x7a05, 0x0078, 0x726d, 0x1078, 0x7188, 0x0078,
+       0x721f, 0x1078, 0x8c3b, 0x00c0, 0x7259, 0x1078, 0x7a05, 0x0078,
+       0x726d, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x726d, 0x601c,
+       0xa086, 0x0003, 0x00c0, 0x7281, 0x6837, 0x0103, 0x6b4a, 0x6847,
+       0x0000, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x1078, 0x8c01, 0x1078,
+       0x7045, 0x0c7f, 0x0078, 0x71ee, 0x2c78, 0x600c, 0x2060, 0x0078,
+       0x71ee, 0x127f, 0x007f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f,
+       0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x726d, 0x1078, 0x9e70,
+       0x0078, 0x726d, 0x037e, 0x157e, 0x137e, 0x147e, 0x3908, 0xa006,
+       0xa190, 0x0020, 0x221c, 0xa39e, 0x260c, 0x00c0, 0x729b, 0x8210,
+       0x8000, 0x0078, 0x7292, 0xa005, 0x0040, 0x72a7, 0x20a9, 0x0020,
+       0x2198, 0x8211, 0xa282, 0x0020, 0x20c8, 0x20a0, 0x53a3, 0x147f,
+       0x137f, 0x157f, 0x037f, 0x007c, 0x0d7e, 0x20a1, 0x020b, 0x1078,
+       0x65f8, 0x20a3, 0x0200, 0x20a3, 0x0014, 0x60c3, 0x0014, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x2099, 0xa5a3, 0x20a9, 0x0004, 0x53a6,
+       0x20a3, 0x0004, 0x20a3, 0x7878, 0x20a3, 0x0000, 0x20a3, 0x0000,
+       0x1078, 0x6c2d, 0x0d7f, 0x007c, 0x20a1, 0x020b, 0x1078, 0x65f8,
+       0x20a3, 0x0214, 0x20a3, 0x0018, 0x20a3, 0x0800, 0x7810, 0xa084,
+       0xff00, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x7810, 0xa084, 0x00ff, 0x20a2, 0x7828, 0x20a2,
+       0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0018, 0x1078, 0x6c2d,
+       0x007c, 0x0d7e, 0x017e, 0x2f68, 0x2009, 0x0035, 0x1078, 0x8ef5,
+       0x00c0, 0x7361, 0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3, 0x1300,
+       0x20a3, 0x0000, 0x7828, 0x2068, 0x681c, 0xa086, 0x0003, 0x0040,
+       0x733d, 0x7818, 0xa080, 0x0028, 0x2014, 0xa286, 0x007e, 0x00c0,
+       0x7317, 0x20a3, 0x00ff, 0x20a3, 0xfffe, 0x0078, 0x7352, 0xa286,
+       0x007f, 0x00c0, 0x7321, 0x20a3, 0x00ff, 0x20a3, 0xfffd, 0x0078,
+       0x7352, 0xd2bc, 0x0040, 0x7337, 0xa286, 0x0080, 0x00c0, 0x732e,
+       0x20a3, 0x00ff, 0x20a3, 0xfffc, 0x0078, 0x7352, 0xa2e8, 0xa434,
+       0x2d6c, 0x6810, 0x20a2, 0x6814, 0x20a2, 0x0078, 0x7352, 0x20a3,
+       0x0000, 0x6098, 0x20a2, 0x0078, 0x7352, 0x7818, 0xa080, 0x0028,
+       0x2004, 0xa082, 0x007e, 0x0048, 0x734e, 0x0d7e, 0x2069, 0xa31a,
+       0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x7352, 0x20a3, 0x0000,
+       0x6030, 0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x60c3, 0x000c, 0x1078, 0x6c2d, 0x017f, 0x0d7f,
+       0x007c, 0x7817, 0x0001, 0x7803, 0x0006, 0x017f, 0x0d7f, 0x007c,
+       0x0d7e, 0x027e, 0x7928, 0x2168, 0x691c, 0xa186, 0x0006, 0x0040,
+       0x738a, 0xa186, 0x0003, 0x0040, 0x73e5, 0xa186, 0x0005, 0x0040,
+       0x73c8, 0xa186, 0x0004, 0x0040, 0x73b8, 0xa186, 0x0008, 0x0040,
+       0x73d2, 0x7807, 0x0037, 0x7813, 0x1700, 0x1078, 0x7450, 0x027f,
+       0x0d7f, 0x007c, 0x1078, 0x740d, 0x2009, 0x4000, 0x6800, 0x0079,
+       0x7391, 0x73a4, 0x73b2, 0x73a6, 0x73b2, 0x73ad, 0x73a4, 0x73a4,
+       0x73b2, 0x73b2, 0x73b2, 0x73b2, 0x73a4, 0x73a4, 0x73a4, 0x73a4,
+       0x73a4, 0x73b2, 0x73a4, 0x73b2, 0x1078, 0x1328, 0x6824, 0xd0e4,
+       0x0040, 0x73ad, 0xd0cc, 0x0040, 0x73b0, 0xa00e, 0x0078, 0x73b2,
+       0x2009, 0x2000, 0x6828, 0x20a2, 0x682c, 0x20a2, 0x0078, 0x7403,
+       0x1078, 0x740d, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000,
+       0x6a00, 0xa286, 0x0002, 0x00c0, 0x73c6, 0xa00e, 0x0078, 0x7403,
+       0x1078, 0x740d, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000,
+       0x0078, 0x7403, 0x1078, 0x740d, 0x20a3, 0x0000, 0x20a3, 0x0000,
+       0x2009, 0x4000, 0xa286, 0x0005, 0x0040, 0x73e2, 0xa286, 0x0002,
+       0x00c0, 0x73e3, 0xa00e, 0x0078, 0x7403, 0x1078, 0x740d, 0x6810,
+       0x2068, 0x697c, 0x6810, 0xa112, 0x6980, 0x6814, 0xa103, 0x20a2,
+       0x22a2, 0x7928, 0xa180, 0x0000, 0x2004, 0xa08e, 0x0002, 0x0040,
+       0x7401, 0xa08e, 0x0004, 0x0040, 0x7401, 0x2009, 0x4000, 0x0078,
+       0x7403, 0x2009, 0x0000, 0x21a2, 0x20a3, 0x0000, 0x60c3, 0x0018,
+       0x1078, 0x6c2d, 0x027f, 0x0d7f, 0x007c, 0x037e, 0x047e, 0x057e,
+       0x067e, 0x20a1, 0x020b, 0x1078, 0x65f8, 0xa006, 0x20a3, 0x0200,
+       0x20a2, 0x7934, 0x21a2, 0x7938, 0x21a2, 0x7818, 0xa080, 0x0028,
+       0x2004, 0xa092, 0x007e, 0x0048, 0x7433, 0x0d7e, 0x2069, 0xa31a,
+       0x2d2c, 0x8d68, 0x2d34, 0xa0e8, 0xa434, 0x2d6c, 0x6b10, 0x6c14,
+       0x0d7f, 0x0078, 0x7439, 0x2019, 0x0000, 0x6498, 0x2029, 0x0000,
+       0x6630, 0x7828, 0xa080, 0x0007, 0x2004, 0xa086, 0x0003, 0x00c0,
+       0x7447, 0x25a2, 0x26a2, 0x23a2, 0x24a2, 0x0078, 0x744b, 0x23a2,
+       0x24a2, 0x25a2, 0x26a2, 0x067f, 0x057f, 0x047f, 0x037f, 0x007c,
+       0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0100, 0x20a3, 0x0000,
+       0x20a3, 0x0009, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x1078, 0x6c2d,
+       0x007c, 0x20a1, 0x020b, 0x1078, 0x655e, 0x20a3, 0x1400, 0x20a3,
+       0x0000, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x7828, 0x20a2, 0x782c,
+       0x20a2, 0x7830, 0xa084, 0x00ff, 0x8007, 0x20a2, 0x20a3, 0x0000,
+       0x60c3, 0x0010, 0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078,
+       0x65ef, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828, 0x20a2, 0x7810,
+       0x20a2, 0x60c3, 0x0008, 0x1078, 0x6c2d, 0x007c, 0x147e, 0x20a1,
+       0x020b, 0x1078, 0x7499, 0x60c3, 0x0000, 0x1078, 0x6c2d, 0x147f,
+       0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+       0x2004, 0xd0bc, 0x0040, 0x74b6, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c,
+       0x6810, 0xa085, 0x0300, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a,
+       0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x74be, 0x20a3, 0x0300,
+       0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0819,
+       0x20a3, 0x0000, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000, 0x2fa2,
+       0x7a08, 0x22a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x007c, 0x2061,
+       0xaa00, 0x2a70, 0x7060, 0x7046, 0x704b, 0xaa00, 0x007c, 0x0e7e,
+       0x127e, 0x2071, 0xa300, 0x2091, 0x8000, 0x7544, 0xa582, 0x0010,
+       0x0048, 0x7509, 0x7048, 0x2060, 0x6000, 0xa086, 0x0000, 0x0040,
+       0x74f5, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8, 0x74f1, 0x0078,
+       0x74e4, 0x2061, 0xaa00, 0x0078, 0x74e4, 0x6003, 0x0008, 0x8529,
+       0x7546, 0xaca8, 0x0010, 0x7054, 0xa502, 0x00c8, 0x7505, 0x754a,
+       0xa085, 0x0001, 0x127f, 0x0e7f, 0x007c, 0x704b, 0xaa00, 0x0078,
+       0x7500, 0xa006, 0x0078, 0x7502, 0x0e7e, 0x2071, 0xa300, 0x7544,
+       0xa582, 0x0010, 0x0048, 0x753a, 0x7048, 0x2060, 0x6000, 0xa086,
+       0x0000, 0x0040, 0x7527, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8,
+       0x7523, 0x0078, 0x7516, 0x2061, 0xaa00, 0x0078, 0x7516, 0x6003,
+       0x0008, 0x8529, 0x7546, 0xaca8, 0x0010, 0x7054, 0xa502, 0x00c8,
+       0x7536, 0x754a, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x704b, 0xaa00,
+       0x0078, 0x7532, 0xa006, 0x0078, 0x7534, 0xac82, 0xaa00, 0x1048,
+       0x1328, 0x2001, 0xa315, 0x2004, 0xac02, 0x10c8, 0x1328, 0xa006,
+       0x6006, 0x600a, 0x600e, 0x6012, 0x6016, 0x601a, 0x601f, 0x0000,
+       0x6003, 0x0000, 0x6022, 0x6026, 0x602a, 0x602e, 0x6032, 0x6036,
+       0x603a, 0x603e, 0x2061, 0xa300, 0x6044, 0x8000, 0x6046, 0xa086,
+       0x0001, 0x0040, 0x7564, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078,
+       0x6109, 0x127f, 0x0078, 0x7563, 0x601c, 0xa084, 0x000f, 0x0079,
+       0x7571, 0x757a, 0x758b, 0x75a7, 0x75c3, 0x8f2d, 0x8f49, 0x8f65,
+       0x757a, 0x758b, 0xa186, 0x0013, 0x00c0, 0x7583, 0x1078, 0x6010,
+       0x1078, 0x6109, 0x007c, 0xa18e, 0x0047, 0x00c0, 0x758a, 0xa016,
+       0x1078, 0x15ec, 0x007c, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8,
+       0x1328, 0x1079, 0x7595, 0x067f, 0x007c, 0x75a5, 0x7891, 0x7a34,
+       0x75a5, 0x7ab8, 0x75df, 0x75a5, 0x75a5, 0x7823, 0x7e6d, 0x75a5,
+       0x75a5, 0x75a5, 0x75a5, 0x75a5, 0x75a5, 0x1078, 0x1328, 0x067e,
+       0x6000, 0xa0b2, 0x0010, 0x10c8, 0x1328, 0x1079, 0x75b1, 0x067f,
+       0x007c, 0x75c1, 0x8522, 0x75c1, 0x75c1, 0x75c1, 0x75c1, 0x75c1,
+       0x75c1, 0x84c5, 0x86a8, 0x75c1, 0x8552, 0x85d8, 0x8552, 0x85d8,
+       0x75c1, 0x1078, 0x1328, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8,
+       0x1328, 0x1079, 0x75cd, 0x067f, 0x007c, 0x75dd, 0x7eb4, 0x7f81,
+       0x80c6, 0x8242, 0x75dd, 0x75dd, 0x75dd, 0x7e8d, 0x846d, 0x8471,
+       0x75dd, 0x75dd, 0x75dd, 0x75dd, 0x84a1, 0x1078, 0x1328, 0xa1b6,
+       0x0015, 0x00c0, 0x75e7, 0x1078, 0x753d, 0x0078, 0x75ed, 0xa1b6,
+       0x0016, 0x10c0, 0x1328, 0x1078, 0x753d, 0x007c, 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, 0x75fc,
+       0x0e7e, 0x1078, 0x8a44, 0x0040, 0x7613, 0x6010, 0x2070, 0x7007,
+       0x0000, 0x7037, 0x0103, 0x0e7f, 0x1078, 0x753d, 0x007c, 0x0d7e,
+       0x037e, 0x7330, 0xa386, 0x0200, 0x00c0, 0x7624, 0x6018, 0x2068,
+       0x6813, 0x00ff, 0x6817, 0xfffd, 0x6010, 0xa005, 0x0040, 0x762e,
+       0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6b32, 0x1078, 0x753d,
+       0x037f, 0x0d7f, 0x007c, 0x017e, 0x20a9, 0x002a, 0xae80, 0x000c,
+       0x2098, 0x6010, 0xa080, 0x0002, 0x20a0, 0x53a3, 0x20a9, 0x002a,
+       0x6010, 0xa080, 0x0001, 0x2004, 0xa080, 0x0002, 0x20a0, 0x53a3,
+       0x0e7e, 0x6010, 0x2004, 0x2070, 0x7037, 0x0103, 0x0e7f, 0x1078,
+       0x753d, 0x017f, 0x007c, 0x0e7e, 0x0d7e, 0x603f, 0x0000, 0x2c68,
+       0x017e, 0x2009, 0x0035, 0x1078, 0x8ef5, 0x017f, 0x00c0, 0x766f,
+       0x027e, 0x6228, 0x2268, 0x027f, 0x2071, 0xa88c, 0x6b1c, 0xa386,
+       0x0003, 0x0040, 0x7673, 0xa386, 0x0006, 0x0040, 0x7677, 0x1078,
+       0x753d, 0x0078, 0x7679, 0x1078, 0x767c, 0x0078, 0x7679, 0x1078,
+       0x771e, 0x0d7f, 0x0e7f, 0x007c, 0x0f7e, 0x6810, 0x2078, 0xa186,
+       0x0015, 0x0040, 0x7705, 0xa18e, 0x0016, 0x00c0, 0x771c, 0x700c,
+       0xa084, 0xff00, 0xa086, 0x1700, 0x00c0, 0x76e0, 0x8fff, 0x0040,
+       0x771a, 0x6808, 0xa086, 0xffff, 0x00c0, 0x7709, 0x784c, 0xa084,
+       0x0060, 0xa086, 0x0020, 0x00c0, 0x76a7, 0x797c, 0x7810, 0xa106,
+       0x00c0, 0x7709, 0x7980, 0x7814, 0xa106, 0x00c0, 0x7709, 0x1078,
+       0x8bf4, 0x6830, 0x7852, 0x784c, 0xc0dc, 0xc0f4, 0xc0d4, 0x784e,
+       0x027e, 0xa00e, 0x6a14, 0x2001, 0x000a, 0x1078, 0x5a98, 0x7854,
+       0xa20a, 0x0048, 0x76bc, 0x8011, 0x7a56, 0x82ff, 0x027f, 0x00c0,
+       0x76c8, 0x0c7e, 0x2d60, 0x1078, 0x8832, 0x0c7f, 0x0078, 0x771a,
+       0x0c7e, 0x0d7e, 0x2f68, 0x6838, 0xd0fc, 0x00c0, 0x76d3, 0x1078,
+       0x4290, 0x0078, 0x76d5, 0x1078, 0x436e, 0x0d7f, 0x0c7f, 0x00c0,
+       0x7709, 0x0c7e, 0x2d60, 0x1078, 0x753d, 0x0c7f, 0x0078, 0x771a,
+       0x7008, 0xa086, 0x000b, 0x00c0, 0x76fa, 0x6018, 0x200c, 0xc1bc,
+       0x2102, 0x0c7e, 0x2d60, 0x7853, 0x0003, 0x6007, 0x0085, 0x6003,
+       0x000b, 0x601f, 0x0002, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0c7f,
+       0x0078, 0x771a, 0x700c, 0xa086, 0x2a00, 0x00c0, 0x7709, 0x2001,
+       0xa5a2, 0x2004, 0x683e, 0x0078, 0x771a, 0x1078, 0x7739, 0x0078,
+       0x771c, 0x8fff, 0x1040, 0x1328, 0x0c7e, 0x0d7e, 0x2d60, 0x2f68,
+       0x684b, 0x0003, 0x1078, 0x8726, 0x1078, 0x8bf4, 0x1078, 0x8c01,
+       0x0d7f, 0x0c7f, 0x1078, 0x753d, 0x0f7f, 0x007c, 0xa186, 0x0015,
+       0x00c0, 0x7728, 0x2001, 0xa5a2, 0x2004, 0x683e, 0x0078, 0x7736,
+       0xa18e, 0x0016, 0x00c0, 0x7738, 0x0c7e, 0x2d00, 0x2060, 0x1078,
+       0xa134, 0x1078, 0x5a41, 0x1078, 0x753d, 0x0c7f, 0x1078, 0x753d,
+       0x007c, 0x027e, 0x037e, 0x047e, 0x7228, 0x7c80, 0x7b7c, 0xd2f4,
+       0x0040, 0x7748, 0x2001, 0xa5a2, 0x2004, 0x683e, 0x0078, 0x77ac,
+       0x0c7e, 0x2d60, 0x1078, 0x874a, 0x0c7f, 0x6804, 0xa086, 0x0050,
+       0x00c0, 0x7760, 0x0c7e, 0x2d00, 0x2060, 0x6003, 0x0001, 0x6007,
+       0x0050, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0c7f, 0x0078, 0x77ac,
+       0x6800, 0xa086, 0x000f, 0x0040, 0x7782, 0x8fff, 0x1040, 0x1328,
+       0x6824, 0xd0dc, 0x00c0, 0x7782, 0x6800, 0xa086, 0x0004, 0x00c0,
+       0x7787, 0x784c, 0xd0ac, 0x0040, 0x7787, 0x784c, 0xc0dc, 0xc0f4,
+       0x784e, 0x7850, 0xc0f4, 0xc0fc, 0x7852, 0x2001, 0x0001, 0x682e,
+       0x0078, 0x77a6, 0x2001, 0x0007, 0x682e, 0x0078, 0x77a6, 0x784c,
+       0xd0b4, 0x00c0, 0x7794, 0xd0ac, 0x0040, 0x7782, 0x784c, 0xd0f4,
+       0x00c0, 0x7782, 0x0078, 0x7775, 0xd2ec, 0x00c0, 0x7782, 0x7024,
+       0xa306, 0x00c0, 0x779f, 0x7020, 0xa406, 0x0040, 0x7782, 0x7020,
+       0x6836, 0x7024, 0x683a, 0x2001, 0x0005, 0x682e, 0x1078, 0x8d2b,
+       0x1078, 0x6109, 0x0078, 0x77ae, 0x1078, 0x753d, 0x047f, 0x037f,
+       0x027f, 0x007c, 0x0e7e, 0x0d7e, 0x027e, 0x6034, 0x2068, 0x6a1c,
+       0xa286, 0x0007, 0x0040, 0x7806, 0xa286, 0x0002, 0x0040, 0x7806,
+       0xa286, 0x0000, 0x0040, 0x7806, 0x6808, 0x6338, 0xa306, 0x00c0,
+       0x7806, 0x2071, 0xa88c, 0xa186, 0x0015, 0x0040, 0x7800, 0xa18e,
+       0x0016, 0x00c0, 0x77e8, 0x6030, 0xa084, 0x00ff, 0xa086, 0x0001,
+       0x00c0, 0x77e8, 0x700c, 0xa086, 0x2a00, 0x00c0, 0x77e8, 0x6034,
+       0xa080, 0x0009, 0x200c, 0xc1dd, 0xc1f5, 0x2102, 0x0078, 0x7800,
+       0x0c7e, 0x6034, 0x2060, 0x6010, 0x2068, 0x1078, 0x8a44, 0x1040,
+       0x1328, 0x6853, 0x0003, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f,
+       0x0002, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0c7f, 0x0078, 0x7806,
+       0x6034, 0x2068, 0x2001, 0xa5a2, 0x2004, 0x683e, 0x1078, 0x753d,
+       0x027f, 0x0d7f, 0x0e7f, 0x007c, 0x0d7e, 0x20a9, 0x000e, 0x2e98,
+       0x6010, 0x20a0, 0x53a3, 0xa1b6, 0x0015, 0x00c0, 0x7820, 0x6018,
+       0x2068, 0x7038, 0x680a, 0x703c, 0x680e, 0x6800, 0xc08d, 0x6802,
+       0x0d7f, 0x0078, 0x7608, 0x2100, 0xa1b2, 0x0044, 0x10c8, 0x1328,
+       0xa1b2, 0x0040, 0x00c8, 0x7888, 0x0079, 0x782e, 0x787c, 0x7870,
+       0x787c, 0x787c, 0x787c, 0x787c, 0x786e, 0x786e, 0x786e, 0x786e,
+       0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e,
+       0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e,
+       0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x787c, 0x786e, 0x787c,
+       0x787c, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x787c, 0x786e,
+       0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e,
+       0x787c, 0x787c, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e,
+       0x786e, 0x786e, 0x786e, 0x787c, 0x786e, 0x786e, 0x1078, 0x1328,
+       0x6003, 0x0001, 0x6106, 0x1078, 0x5c45, 0x127e, 0x2091, 0x8000,
+       0x1078, 0x6109, 0x127f, 0x007c, 0x6003, 0x0001, 0x6106, 0x1078,
+       0x5c45, 0x127e, 0x2091, 0x8000, 0x1078, 0x6109, 0x127f, 0x007c,
+       0x2600, 0x0079, 0x788b, 0x788f, 0x788f, 0x788f, 0x787c, 0x1078,
+       0x1328, 0x6004, 0xa0b2, 0x0044, 0x10c8, 0x1328, 0xa1b6, 0x0013,
+       0x00c0, 0x78a1, 0xa0b2, 0x0040, 0x00c8, 0x79fb, 0x2008, 0x0079,
+       0x7941, 0xa1b6, 0x0027, 0x00c0, 0x78fe, 0x1078, 0x6010, 0x6004,
+       0x1078, 0x8c27, 0x0040, 0x78be, 0x1078, 0x8c3b, 0x0040, 0x78f6,
+       0xa08e, 0x0021, 0x0040, 0x78fa, 0xa08e, 0x0022, 0x0040, 0x78f6,
+       0xa08e, 0x003d, 0x0040, 0x78fa, 0x0078, 0x78f1, 0x1078, 0x2839,
+       0x2001, 0x0007, 0x1078, 0x443f, 0x6018, 0xa080, 0x0028, 0x200c,
+       0x1078, 0x7a05, 0xa186, 0x007e, 0x00c0, 0x78d3, 0x2001, 0xa332,
+       0x2014, 0xc285, 0x2202, 0x017e, 0x027e, 0x037e, 0x2110, 0x2019,
+       0x0028, 0x1078, 0x5d53, 0x077e, 0x2039, 0x0000, 0x1078, 0x5c78,
+       0x0c7e, 0x6018, 0xa065, 0x0040, 0x78e7, 0x1078, 0x471b, 0x0c7f,
+       0x2c08, 0x1078, 0x9c38, 0x077f, 0x037f, 0x027f, 0x017f, 0x1078,
+       0x44bc, 0x1078, 0x753d, 0x1078, 0x6109, 0x007c, 0x1078, 0x7a05,
+       0x0078, 0x78f1, 0x1078, 0x7a28, 0x0078, 0x78f1, 0xa186, 0x0014,
+       0x00c0, 0x78f5, 0x1078, 0x6010, 0x1078, 0x2813, 0x1078, 0x8c27,
+       0x00c0, 0x791d, 0x1078, 0x2839, 0x6018, 0xa080, 0x0028, 0x200c,
+       0x1078, 0x7a05, 0xa186, 0x007e, 0x00c0, 0x791b, 0x2001, 0xa332,
+       0x200c, 0xc185, 0x2102, 0x0078, 0x78f1, 0x1078, 0x8c3b, 0x00c0,
+       0x7925, 0x1078, 0x7a05, 0x0078, 0x78f1, 0x6004, 0xa08e, 0x0032,
+       0x00c0, 0x7936, 0x0e7e, 0x0f7e, 0x2071, 0xa381, 0x2079, 0x0000,
+       0x1078, 0x2b56, 0x0f7f, 0x0e7f, 0x0078, 0x78f1, 0x6004, 0xa08e,
+       0x0021, 0x0040, 0x7921, 0xa08e, 0x0022, 0x1040, 0x7a05, 0x0078,
+       0x78f1, 0x7983, 0x7985, 0x7989, 0x798d, 0x7991, 0x7995, 0x7981,
+       0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981,
+       0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981,
+       0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7999,
+       0x79ab, 0x7981, 0x79ad, 0x79ab, 0x7981, 0x7981, 0x7981, 0x7981,
+       0x7981, 0x79ab, 0x79ab, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981,
+       0x7981, 0x7981, 0x7981, 0x79de, 0x79ab, 0x7981, 0x79a5, 0x7981,
+       0x7981, 0x7981, 0x79a7, 0x7981, 0x7981, 0x7981, 0x79ab, 0x7981,
+       0x7981, 0x1078, 0x1328, 0x0078, 0x79ab, 0x2001, 0x000b, 0x0078,
+       0x79b8, 0x2001, 0x0003, 0x0078, 0x79b8, 0x2001, 0x0005, 0x0078,
+       0x79b8, 0x2001, 0x0001, 0x0078, 0x79b8, 0x2001, 0x0009, 0x0078,
+       0x79b8, 0x1078, 0x6010, 0x6003, 0x0005, 0x2001, 0xa5a2, 0x2004,
+       0x603e, 0x1078, 0x6109, 0x0078, 0x79b7, 0x0078, 0x79ab, 0x0078,
+       0x79ab, 0x1078, 0x443f, 0x0078, 0x79f0, 0x1078, 0x6010, 0x6003,
+       0x0004, 0x2001, 0xa5a0, 0x2004, 0x6016, 0x1078, 0x6109, 0x007c,
+       0x1078, 0x443f, 0x1078, 0x6010, 0x2001, 0xa5a2, 0x2004, 0x603e,
+       0x6003, 0x0002, 0x037e, 0x2019, 0xa35c, 0x2304, 0xa084, 0xff00,
+       0x00c0, 0x79cf, 0x2019, 0xa5a0, 0x231c, 0x0078, 0x79d8, 0x8007,
+       0xa09a, 0x0004, 0x0048, 0x79ca, 0x8003, 0x801b, 0x831b, 0xa318,
+       0x6316, 0x037f, 0x1078, 0x6109, 0x0078, 0x79b7, 0x0e7e, 0x0f7e,
+       0x2071, 0xa381, 0x2079, 0x0000, 0x1078, 0x2b56, 0x0f7f, 0x0e7f,
+       0x1078, 0x6010, 0x1078, 0x753d, 0x1078, 0x6109, 0x0078, 0x79b7,
+       0x1078, 0x6010, 0x6003, 0x0002, 0x2001, 0xa5a0, 0x2004, 0x6016,
+       0x1078, 0x6109, 0x007c, 0x2600, 0x2008, 0x0079, 0x79ff, 0x7a03,
+       0x7a03, 0x7a03, 0x79f0, 0x1078, 0x1328, 0x0e7e, 0x1078, 0x8a44,
+       0x0040, 0x7a21, 0x6010, 0x2070, 0x7038, 0xd0fc, 0x0040, 0x7a21,
+       0x7007, 0x0000, 0x017e, 0x6004, 0xa08e, 0x0021, 0x0040, 0x7a23,
+       0xa08e, 0x003d, 0x0040, 0x7a23, 0x017f, 0x7037, 0x0103, 0x7033,
+       0x0100, 0x0e7f, 0x007c, 0x017f, 0x1078, 0x7a28, 0x0078, 0x7a21,
+       0x0e7e, 0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070, 0x7037, 0x0103,
+       0x7023, 0x8001, 0x0e7f, 0x007c, 0x0d7e, 0x6618, 0x2668, 0x6804,
+       0xa084, 0x00ff, 0x0d7f, 0xa0b2, 0x000c, 0x10c8, 0x1328, 0x6604,
+       0xa6b6, 0x0043, 0x00c0, 0x7a48, 0x1078, 0x8e6d, 0x0078, 0x7aa7,
+       0x6604, 0xa6b6, 0x0033, 0x00c0, 0x7a51, 0x1078, 0x8e11, 0x0078,
+       0x7aa7, 0x6604, 0xa6b6, 0x0028, 0x00c0, 0x7a5a, 0x1078, 0x8c6a,
+       0x0078, 0x7aa7, 0x6604, 0xa6b6, 0x0029, 0x00c0, 0x7a63, 0x1078,
+       0x8c84, 0x0078, 0x7aa7, 0x6604, 0xa6b6, 0x001f, 0x00c0, 0x7a6c,
+       0x1078, 0x75ee, 0x0078, 0x7aa7, 0x6604, 0xa6b6, 0x0000, 0x00c0,
+       0x7a75, 0x1078, 0x780c, 0x0078, 0x7aa7, 0x6604, 0xa6b6, 0x0022,
+       0x00c0, 0x7a7e, 0x1078, 0x7617, 0x0078, 0x7aa7, 0x6604, 0xa6b6,
+       0x0035, 0x00c0, 0x7a87, 0x1078, 0x7653, 0x0078, 0x7aa7, 0x6604,
+       0xa6b6, 0x0039, 0x00c0, 0x7a90, 0x1078, 0x77b2, 0x0078, 0x7aa7,
+       0x6604, 0xa6b6, 0x003d, 0x00c0, 0x7a99, 0x1078, 0x7633, 0x0078,
+       0x7aa7, 0xa1b6, 0x0015, 0x00c0, 0x7aa1, 0x1079, 0x7aac, 0x0078,
+       0x7aa7, 0xa1b6, 0x0016, 0x00c0, 0x7aa8, 0x1079, 0x7bfd, 0x007c,
+       0x1078, 0x7583, 0x0078, 0x7aa7, 0x7ad0, 0x7ad3, 0x7ad0, 0x7b1e,
+       0x7ad0, 0x7b91, 0x7c09, 0x7ad0, 0x7ad0, 0x7bd5, 0x7ad0, 0x7beb,
+       0xa1b6, 0x0048, 0x0040, 0x7ac4, 0x20e1, 0x0005, 0x3d18, 0x3e20,
+       0x2c10, 0x1078, 0x15ec, 0x007c, 0x0e7e, 0xacf0, 0x0004, 0x2e74,
+       0x7000, 0x2070, 0x7037, 0x0103, 0x0e7f, 0x1078, 0x753d, 0x007c,
+       0x0005, 0x0005, 0x007c, 0x0e7e, 0x2071, 0xa300, 0x707c, 0xa086,
+       0x0074, 0x00c0, 0x7b07, 0x1078, 0x9c0c, 0x00c0, 0x7af9, 0x0d7e,
+       0x6018, 0x2068, 0x7030, 0xd08c, 0x0040, 0x7aec, 0x6800, 0xd0bc,
+       0x0040, 0x7aec, 0xc0c5, 0x6802, 0x1078, 0x7b0b, 0x0d7f, 0x2001,
+       0x0006, 0x1078, 0x443f, 0x1078, 0x2839, 0x1078, 0x753d, 0x0078,
+       0x7b09, 0x2001, 0x000a, 0x1078, 0x443f, 0x1078, 0x2839, 0x6003,
+       0x0001, 0x6007, 0x0001, 0x1078, 0x5c45, 0x0078, 0x7b09, 0x1078,
+       0x7b81, 0x0e7f, 0x007c, 0x6800, 0xd084, 0x0040, 0x7b1d, 0x2001,
+       0x0000, 0x1078, 0x442b, 0x2069, 0xa351, 0x6804, 0xd0a4, 0x0040,
+       0x7b1d, 0x2001, 0x0006, 0x1078, 0x4472, 0x007c, 0x0d7e, 0x2011,
+       0xa31f, 0x2204, 0xa086, 0x0074, 0x00c0, 0x7b7d, 0x6018, 0x2068,
+       0x6aa0, 0xa286, 0x007e, 0x00c0, 0x7b31, 0x1078, 0x7d17, 0x0078,
+       0x7b7f, 0x1078, 0x7d0d, 0x6018, 0x2068, 0xa080, 0x0028, 0x2014,
+       0xa286, 0x0080, 0x00c0, 0x7b55, 0x6813, 0x00ff, 0x6817, 0xfffc,
+       0x6010, 0xa005, 0x0040, 0x7b4b, 0x2068, 0x6807, 0x0000, 0x6837,
+       0x0103, 0x6833, 0x0200, 0x2001, 0x0006, 0x1078, 0x443f, 0x1078,
+       0x2839, 0x1078, 0x753d, 0x0078, 0x7b7f, 0x0e7e, 0x2071, 0xa332,
+       0x2e04, 0xd09c, 0x0040, 0x7b70, 0x2071, 0xa880, 0x7108, 0x720c,
+       0xa18c, 0x00ff, 0x00c0, 0x7b68, 0xa284, 0xff00, 0x0040, 0x7b70,
+       0x6018, 0x2070, 0x70a0, 0xd0bc, 0x00c0, 0x7b70, 0x7112, 0x7216,
+       0x0e7f, 0x2001, 0x0004, 0x1078, 0x443f, 0x6003, 0x0001, 0x6007,
+       0x0003, 0x1078, 0x5c45, 0x0078, 0x7b7f, 0x1078, 0x7b81, 0x0d7f,
+       0x007c, 0x2001, 0xa300, 0x2004, 0xa086, 0x0003, 0x0040, 0x7b8c,
+       0x2001, 0x0007, 0x1078, 0x443f, 0x1078, 0x2839, 0x1078, 0x753d,
+       0x007c, 0x0e7e, 0x2071, 0xa300, 0x707c, 0xa086, 0x0014, 0x00c0,
+       0x7bcf, 0x7000, 0xa086, 0x0003, 0x00c0, 0x7ba4, 0x6010, 0xa005,
+       0x00c0, 0x7ba4, 0x1078, 0x35f7, 0x0d7e, 0x6018, 0x2068, 0x1078,
+       0x457d, 0x1078, 0x7b0b, 0x0d7f, 0x1078, 0x7dba, 0x00c0, 0x7bcf,
+       0x0d7e, 0x6018, 0x2068, 0x6890, 0x0d7f, 0xa005, 0x0040, 0x7bcf,
+       0x2001, 0x0006, 0x1078, 0x443f, 0x0e7e, 0x6010, 0xa005, 0x0040,
+       0x7bc8, 0x2070, 0x7007, 0x0000, 0x7037, 0x0103, 0x7033, 0x0200,
+       0x0e7f, 0x1078, 0x2839, 0x1078, 0x753d, 0x0078, 0x7bd3, 0x1078,
+       0x7a05, 0x1078, 0x7b81, 0x0e7f, 0x007c, 0x2011, 0xa31f, 0x2204,
+       0xa086, 0x0014, 0x00c0, 0x7be8, 0x2001, 0x0002, 0x1078, 0x443f,
+       0x6003, 0x0001, 0x6007, 0x0001, 0x1078, 0x5c45, 0x0078, 0x7bea,
+       0x1078, 0x7b81, 0x007c, 0x2011, 0xa31f, 0x2204, 0xa086, 0x0004,
+       0x00c0, 0x7bfa, 0x2001, 0x0007, 0x1078, 0x443f, 0x1078, 0x753d,
+       0x0078, 0x7bfc, 0x1078, 0x7b81, 0x007c, 0x7ad0, 0x7c11, 0x7ad0,
+       0x7c4e, 0x7ad0, 0x7cc0, 0x7c09, 0x7ad0, 0x7ad0, 0x7cd5, 0x7ad0,
+       0x7ce8, 0x6604, 0xa6b6, 0x001e, 0x00c0, 0x7c10, 0x1078, 0x753d,
+       0x007c, 0x0d7e, 0x0c7e, 0x1078, 0x7cfb, 0x00c0, 0x7c27, 0x2001,
+       0x0000, 0x1078, 0x442b, 0x2001, 0x0002, 0x1078, 0x443f, 0x6003,
+       0x0001, 0x6007, 0x0002, 0x1078, 0x5c45, 0x0078, 0x7c4b, 0x2009,
+       0xa88e, 0x2104, 0xa086, 0x0009, 0x00c0, 0x7c3c, 0x6018, 0x2068,
+       0x6840, 0xa084, 0x00ff, 0xa005, 0x0040, 0x7c49, 0x8001, 0x6842,
+       0x6017, 0x000a, 0x0078, 0x7c4b, 0x2009, 0xa88f, 0x2104, 0xa084,
+       0xff00, 0xa086, 0x1900, 0x00c0, 0x7c49, 0x1078, 0x753d, 0x0078,
+       0x7c4b, 0x1078, 0x7b81, 0x0c7f, 0x0d7f, 0x007c, 0x1078, 0x7d0a,
+       0x00c0, 0x7c62, 0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0002,
+       0x1078, 0x443f, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078, 0x5c45,
+       0x0078, 0x7c8e, 0x1078, 0x7a05, 0x2009, 0xa88e, 0x2134, 0xa6b4,
+       0x00ff, 0xa686, 0x0005, 0x0040, 0x7c8f, 0xa686, 0x000b, 0x0040,
+       0x7c8c, 0x2009, 0xa88f, 0x2104, 0xa084, 0xff00, 0x00c0, 0x7c7c,
+       0xa686, 0x0009, 0x0040, 0x7c8f, 0xa086, 0x1900, 0x00c0, 0x7c8c,
+       0xa686, 0x0009, 0x0040, 0x7c8f, 0x2001, 0x0004, 0x1078, 0x443f,
+       0x1078, 0x753d, 0x0078, 0x7c8e, 0x1078, 0x7b81, 0x007c, 0x0d7e,
+       0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x7c9d, 0x6838, 0xd0fc,
+       0x0040, 0x7c9d, 0x0d7f, 0x0078, 0x7c8c, 0x6018, 0x2068, 0x6840,
+       0xa084, 0x00ff, 0xa005, 0x0040, 0x7cae, 0x8001, 0x6842, 0x6017,
+       0x000a, 0x6007, 0x0016, 0x0d7f, 0x0078, 0x7c8e, 0x68a0, 0xa086,
+       0x007e, 0x00c0, 0x7cbb, 0x0e7e, 0x2071, 0xa300, 0x1078, 0x41f5,
+       0x0e7f, 0x0078, 0x7cbd, 0x1078, 0x2813, 0x0d7f, 0x0078, 0x7c8c,
+       0x1078, 0x7d0a, 0x00c0, 0x7cd0, 0x2001, 0x0004, 0x1078, 0x443f,
+       0x6003, 0x0001, 0x6007, 0x0003, 0x1078, 0x5c45, 0x0078, 0x7cd4,
+       0x1078, 0x7a05, 0x1078, 0x7b81, 0x007c, 0x1078, 0x7d0a, 0x00c0,
+       0x7ce5, 0x2001, 0x0008, 0x1078, 0x443f, 0x6003, 0x0001, 0x6007,
+       0x0005, 0x1078, 0x5c45, 0x0078, 0x7ce7, 0x1078, 0x7b81, 0x007c,
+       0x1078, 0x7d0a, 0x00c0, 0x7cf8, 0x2001, 0x000a, 0x1078, 0x443f,
+       0x6003, 0x0001, 0x6007, 0x0001, 0x1078, 0x5c45, 0x0078, 0x7cfa,
+       0x1078, 0x7b81, 0x007c, 0x2009, 0xa88e, 0x2104, 0xa086, 0x0003,
+       0x00c0, 0x7d09, 0x2009, 0xa88f, 0x2104, 0xa084, 0xff00, 0xa086,
+       0x2a00, 0x007c, 0xa085, 0x0001, 0x007c, 0x0c7e, 0x017e, 0xac88,
+       0x0006, 0x2164, 0x1078, 0x4513, 0x017f, 0x0c7f, 0x007c, 0x0f7e,
+       0x0e7e, 0x0d7e, 0x037e, 0x017e, 0x6018, 0x2068, 0x2071, 0xa332,
+       0x2e04, 0xa085, 0x0003, 0x2072, 0x1078, 0x7d8b, 0x0040, 0x7d50,
+       0x2001, 0xa352, 0x2004, 0xd0a4, 0x0040, 0x7d39, 0xa006, 0x2020,
+       0x2009, 0x002a, 0x1078, 0x9ec0, 0x2001, 0xa30c, 0x200c, 0xc195,
+       0x2102, 0x2019, 0x002a, 0x2009, 0x0001, 0x1078, 0x27e2, 0x2071,
+       0xa300, 0x1078, 0x260d, 0x0c7e, 0x157e, 0x20a9, 0x0081, 0x2009,
+       0x007f, 0x1078, 0x2921, 0x8108, 0x00f0, 0x7d49, 0x157f, 0x0c7f,
+       0x1078, 0x7d0d, 0x6813, 0x00ff, 0x6817, 0xfffe, 0x2071, 0xa880,
+       0x2079, 0x0100, 0x2e04, 0xa084, 0x00ff, 0x2069, 0xa31a, 0x206a,
+       0x78e6, 0x007e, 0x8e70, 0x2e04, 0x2069, 0xa31b, 0x206a, 0x78ea,
+       0xa084, 0xff00, 0x017f, 0xa105, 0x2009, 0xa325, 0x200a, 0x2069,
+       0xa88e, 0x2071, 0xa59c, 0x6810, 0x2072, 0x6814, 0x7006, 0x6818,
+       0x700a, 0x681c, 0x700e, 0x1078, 0x8da9, 0x2001, 0x0006, 0x1078,
+       0x443f, 0x1078, 0x2839, 0x1078, 0x753d, 0x017f, 0x037f, 0x0d7f,
+       0x0e7f, 0x0f7f, 0x007c, 0x027e, 0x037e, 0x0e7e, 0x157e, 0x2019,
+       0xa325, 0x231c, 0x83ff, 0x0040, 0x7db5, 0x2071, 0xa880, 0x2e14,
+       0xa294, 0x00ff, 0x7004, 0xa084, 0xff00, 0xa205, 0xa306, 0x00c0,
+       0x7db5, 0x2011, 0xa896, 0xad98, 0x000a, 0x20a9, 0x0004, 0x1078,
+       0x7e55, 0x00c0, 0x7db5, 0x2011, 0xa89a, 0xad98, 0x0006, 0x20a9,
+       0x0004, 0x1078, 0x7e55, 0x00c0, 0x7db5, 0x157f, 0x0e7f, 0x037f,
+       0x027f, 0x007c, 0x0e7e, 0x2071, 0xa88c, 0x7004, 0xa086, 0x0014,
+       0x00c0, 0x7ddd, 0x7008, 0xa086, 0x0800, 0x00c0, 0x7ddd, 0x700c,
+       0xd0ec, 0x0040, 0x7ddb, 0xa084, 0x0f00, 0xa086, 0x0100, 0x00c0,
+       0x7ddb, 0x7024, 0xd0a4, 0x00c0, 0x7dd8, 0xd0ac, 0x0040, 0x7ddb,
+       0xa006, 0x0078, 0x7ddd, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x0e7e,
+       0x0d7e, 0x0c7e, 0x077e, 0x057e, 0x047e, 0x027e, 0x007e, 0x127e,
+       0x2091, 0x8000, 0x2029, 0xa5b4, 0x252c, 0x2021, 0xa5ba, 0x2424,
+       0x2061, 0xaa00, 0x2071, 0xa300, 0x7244, 0x7060, 0xa202, 0x00c8,
+       0x7e43, 0x1078, 0x9ee5, 0x0040, 0x7e3b, 0x671c, 0xa786, 0x0001,
+       0x0040, 0x7e3b, 0xa786, 0x0007, 0x0040, 0x7e3b, 0x2500, 0xac06,
+       0x0040, 0x7e3b, 0x2400, 0xac06, 0x0040, 0x7e3b, 0x0c7e, 0x6000,
+       0xa086, 0x0004, 0x00c0, 0x7e16, 0x1078, 0x1749, 0xa786, 0x0008,
+       0x00c0, 0x7e25, 0x1078, 0x8c3b, 0x00c0, 0x7e25, 0x0c7f, 0x1078,
+       0x7a05, 0x1078, 0x8c01, 0x0078, 0x7e3b, 0x6010, 0x2068, 0x1078,
+       0x8a44, 0x0040, 0x7e38, 0xa786, 0x0003, 0x00c0, 0x7e4d, 0x6837,
+       0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x4982, 0x1078, 0x8bf4,
+       0x1078, 0x8c01, 0x0c7f, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8,
+       0x7e43, 0x0078, 0x7df4, 0x127f, 0x007f, 0x027f, 0x047f, 0x057f,
+       0x077f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0xa786, 0x0006, 0x00c0,
+       0x7e2f, 0x1078, 0x9e70, 0x0078, 0x7e38, 0x220c, 0x2304, 0xa106,
+       0x00c0, 0x7e60, 0x8210, 0x8318, 0x00f0, 0x7e55, 0xa006, 0x007c,
+       0x2304, 0xa102, 0x0048, 0x7e68, 0x2001, 0x0001, 0x0078, 0x7e6a,
+       0x2001, 0x0000, 0xa18d, 0x0001, 0x007c, 0x6004, 0xa08a, 0x0044,
+       0x10c8, 0x1328, 0x1078, 0x8c27, 0x0040, 0x7e7c, 0x1078, 0x8c3b,
+       0x0040, 0x7e89, 0x0078, 0x7e82, 0x1078, 0x2839, 0x1078, 0x8c3b,
+       0x0040, 0x7e89, 0x1078, 0x6010, 0x1078, 0x753d, 0x1078, 0x6109,
+       0x007c, 0x1078, 0x7a05, 0x0078, 0x7e82, 0xa182, 0x0040, 0x0079,
+       0x7e91, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4,
+       0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea6, 0x7ea6, 0x7ea6, 0x7ea6,
+       0x7ea4, 0x7ea4, 0x7ea4, 0x7ea6, 0x1078, 0x1328, 0x600b, 0xffff,
+       0x6003, 0x0001, 0x6106, 0x1078, 0x5bf8, 0x127e, 0x2091, 0x8000,
+       0x1078, 0x6109, 0x127f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x7ebd,
+       0x6004, 0xa082, 0x0040, 0x0079, 0x7f48, 0xa186, 0x0027, 0x00c0,
+       0x7edf, 0x1078, 0x6010, 0x1078, 0x2813, 0x0d7e, 0x6110, 0x2168,
+       0x1078, 0x8a44, 0x0040, 0x7ed9, 0x6837, 0x0103, 0x684b, 0x0029,
+       0x6847, 0x0000, 0x694c, 0xc1c5, 0x694e, 0x1078, 0x4982, 0x1078,
+       0x8bf4, 0x0d7f, 0x1078, 0x753d, 0x1078, 0x6109, 0x007c, 0xa186,
+       0x0014, 0x00c0, 0x7ee8, 0x6004, 0xa082, 0x0040, 0x0079, 0x7f10,
+       0xa186, 0x0046, 0x0040, 0x7ef4, 0xa186, 0x0045, 0x0040, 0x7ef4,
+       0xa186, 0x0047, 0x10c0, 0x1328, 0x2001, 0x0109, 0x2004, 0xd084,
+       0x0040, 0x7f0d, 0x127e, 0x2091, 0x2200, 0x007e, 0x017e, 0x027e,
+       0x1078, 0x5ad2, 0x027f, 0x017f, 0x007f, 0x127f, 0x6000, 0xa086,
+       0x0002, 0x00c0, 0x7f0d, 0x0078, 0x7f81, 0x1078, 0x7583, 0x007c,
+       0x7f25, 0x7f23, 0x7f23, 0x7f23, 0x7f23, 0x7f23, 0x7f23, 0x7f23,
+       0x7f23, 0x7f23, 0x7f23, 0x7f41, 0x7f41, 0x7f41, 0x7f41, 0x7f23,
+       0x7f41, 0x7f23, 0x7f41, 0x1078, 0x1328, 0x1078, 0x6010, 0x0d7e,
+       0x6110, 0x2168, 0x1078, 0x8a44, 0x0040, 0x7f3b, 0x6837, 0x0103,
+       0x684b, 0x0006, 0x6847, 0x0000, 0x6850, 0xc0ec, 0x6852, 0x1078,
+       0x4982, 0x1078, 0x8bf4, 0x0d7f, 0x1078, 0x753d, 0x1078, 0x6109,
+       0x007c, 0x1078, 0x6010, 0x1078, 0x753d, 0x1078, 0x6109, 0x007c,
+       0x7f5d, 0x7f5b, 0x7f5b, 0x7f5b, 0x7f5b, 0x7f5b, 0x7f5b, 0x7f5b,
+       0x7f5b, 0x7f5b, 0x7f5b, 0x7f6f, 0x7f6f, 0x7f6f, 0x7f6f, 0x7f5b,
+       0x7f7a, 0x7f5b, 0x7f6f, 0x1078, 0x1328, 0x1078, 0x6010, 0x2001,
+       0xa5a2, 0x2004, 0x603e, 0x6003, 0x0002, 0x1078, 0x6109, 0x6010,
+       0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x007c, 0x1078,
+       0x6010, 0x2001, 0xa5a2, 0x2004, 0x603e, 0x6003, 0x000f, 0x1078,
+       0x6109, 0x007c, 0x1078, 0x6010, 0x1078, 0x753d, 0x1078, 0x6109,
+       0x007c, 0xa182, 0x0040, 0x0079, 0x7f85, 0x7f98, 0x7f98, 0x7f98,
+       0x7f98, 0x7f98, 0x7f9a, 0x8095, 0x80b7, 0x7f98, 0x7f98, 0x7f98,
+       0x7f98, 0x7f98, 0x7f98, 0x7f98, 0x7f98, 0x7f98, 0x7f98, 0x7f98,
+       0x1078, 0x1328, 0x0e7e, 0x0d7e, 0x603f, 0x0000, 0x2071, 0xa880,
+       0x7124, 0x610a, 0x2071, 0xa88c, 0x6110, 0x2168, 0x7614, 0xa6b4,
+       0x0fff, 0x86ff, 0x0040, 0x8058, 0xa68c, 0x0c00, 0x0040, 0x7fd1,
+       0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x0040, 0x7fcd, 0x684c,
+       0xd0ac, 0x0040, 0x7fcd, 0x6024, 0xd0dc, 0x00c0, 0x7fcd, 0x6850,
+       0xd0bc, 0x00c0, 0x7fcd, 0x7318, 0x6814, 0xa306, 0x00c0, 0x806f,
+       0x731c, 0x6810, 0xa306, 0x00c0, 0x806f, 0x7318, 0x6b62, 0x731c,
+       0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0040, 0x8004, 0xa186,
+       0x0028, 0x00c0, 0x7fe1, 0x1078, 0x8c15, 0x684b, 0x001c, 0x0078,
+       0x8006, 0xd6dc, 0x0040, 0x7ffd, 0x684b, 0x0015, 0x684c, 0xd0ac,
+       0x0040, 0x7ffb, 0x6914, 0x6a10, 0x2100, 0xa205, 0x0040, 0x7ffb,
+       0x7018, 0xa106, 0x00c0, 0x7ff8, 0x701c, 0xa206, 0x0040, 0x7ffb,
+       0x6962, 0x6a5e, 0xc6dc, 0x0078, 0x8006, 0xd6d4, 0x0040, 0x8004,
+       0x684b, 0x0007, 0x0078, 0x8006, 0x684b, 0x0000, 0x6837, 0x0103,
+       0x6e46, 0xa01e, 0xd6c4, 0x0040, 0x802f, 0xa686, 0x0100, 0x00c0,
+       0x801a, 0x2001, 0xa899, 0x2004, 0xa005, 0x00c0, 0x801a, 0xc6c4,
+       0x0078, 0x7fa9, 0x7328, 0x732c, 0x6b56, 0x83ff, 0x0040, 0x802f,
+       0xa38a, 0x0009, 0x0048, 0x8026, 0x2019, 0x0008, 0x037e, 0x2308,
+       0x2019, 0xa898, 0xad90, 0x0019, 0x1078, 0x8739, 0x037f, 0xd6cc,
+       0x0040, 0x8085, 0x7124, 0x695a, 0x81ff, 0x0040, 0x8085, 0xa192,
+       0x0021, 0x00c8, 0x8046, 0x2071, 0xa898, 0x831c, 0x2300, 0xae18,
+       0xad90, 0x001d, 0x1078, 0x8739, 0x0078, 0x8085, 0x6838, 0xd0fc,
+       0x0040, 0x804f, 0x2009, 0x0020, 0x695a, 0x0078, 0x803b, 0x0f7e,
+       0x2d78, 0x1078, 0x86d1, 0x0f7f, 0x1078, 0x8726, 0x0078, 0x8087,
+       0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x0040, 0x8075, 0x684c,
+       0xd0ac, 0x0040, 0x8075, 0x6024, 0xd0dc, 0x00c0, 0x8075, 0x6850,
+       0xd0bc, 0x00c0, 0x8075, 0x684c, 0xd0f4, 0x00c0, 0x8075, 0x1078,
+       0x8cfa, 0x0d7f, 0x0e7f, 0x0078, 0x8094, 0x684b, 0x0000, 0x6837,
+       0x0103, 0x6e46, 0x684c, 0xd0ac, 0x0040, 0x8085, 0x6810, 0x6914,
+       0xa115, 0x0040, 0x8085, 0x1078, 0x8233, 0x1078, 0x4982, 0x6218,
+       0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x1078, 0x8cc4, 0x0d7f, 0x0e7f,
+       0x00c0, 0x8094, 0x1078, 0x753d, 0x007c, 0x0f7e, 0x6003, 0x0003,
+       0x2079, 0xa88c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078,
+       0x784c, 0xd0ac, 0x0040, 0x80a8, 0x6003, 0x0002, 0x0f7f, 0x007c,
+       0x7c12, 0x7b16, 0x7e0a, 0x7d0e, 0x0f7f, 0x603f, 0x0000, 0x2c10,
+       0x1078, 0x1cab, 0x1078, 0x5c64, 0x1078, 0x61d3, 0x007c, 0x2001,
+       0xa5a2, 0x2004, 0x603e, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005,
+       0x3d18, 0x3e20, 0x2c10, 0x1078, 0x15ec, 0x007c, 0xa182, 0x0040,
+       0x0079, 0x80ca, 0x80dd, 0x80dd, 0x80dd, 0x80dd, 0x80dd, 0x80df,
+       0x8182, 0x80dd, 0x80dd, 0x8198, 0x8209, 0x80dd, 0x80dd, 0x80dd,
+       0x80dd, 0x8218, 0x80dd, 0x80dd, 0x80dd, 0x1078, 0x1328, 0x077e,
+       0x0f7e, 0x0e7e, 0x0d7e, 0x2071, 0xa88c, 0x6110, 0x2178, 0x7614,
+       0xa6b4, 0x0fff, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268,
+       0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0040, 0x817d, 0xa694, 0xff00,
+       0xa284, 0x0c00, 0x0040, 0x8100, 0x7018, 0x7862, 0x701c, 0x785e,
+       0xa284, 0x0300, 0x0040, 0x817d, 0x1078, 0x1381, 0x1040, 0x1328,
+       0x2d00, 0x784a, 0x7f4c, 0xc7cd, 0x7f4e, 0x6837, 0x0103, 0x7838,
+       0x683a, 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00,
+       0x0040, 0x811e, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff,
+       0xa186, 0x0002, 0x0040, 0x813a, 0xa186, 0x0028, 0x00c0, 0x812c,
+       0x684b, 0x001c, 0x0078, 0x813c, 0xd6dc, 0x0040, 0x8133, 0x684b,
+       0x0015, 0x0078, 0x813c, 0xd6d4, 0x0040, 0x813a, 0x684b, 0x0007,
+       0x0078, 0x813c, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854,
+       0x6856, 0xa01e, 0xd6c4, 0x0040, 0x815a, 0x7328, 0x732c, 0x6b56,
+       0x83ff, 0x0040, 0x815a, 0xa38a, 0x0009, 0x0048, 0x8151, 0x2019,
+       0x0008, 0x037e, 0x2308, 0x2019, 0xa898, 0xad90, 0x0019, 0x1078,
+       0x8739, 0x037f, 0xd6cc, 0x0040, 0x817d, 0x7124, 0x695a, 0x81ff,
+       0x0040, 0x817d, 0xa192, 0x0021, 0x00c8, 0x8171, 0x2071, 0xa898,
+       0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078, 0x8739, 0x0078,
+       0x817d, 0x7838, 0xd0fc, 0x0040, 0x817a, 0x2009, 0x0020, 0x695a,
+       0x0078, 0x8166, 0x2d78, 0x1078, 0x86d1, 0x0d7f, 0x0e7f, 0x0f7f,
+       0x077f, 0x007c, 0x0f7e, 0x6003, 0x0003, 0x2079, 0xa88c, 0x7c04,
+       0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12, 0x7b16, 0x7e0a,
+       0x7d0e, 0x0f7f, 0x2c10, 0x1078, 0x1cab, 0x1078, 0x6c26, 0x007c,
+       0x0d7e, 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x0040, 0x81a4,
+       0x2001, 0xa5a2, 0x2004, 0x603e, 0x6003, 0x0002, 0x1078, 0x60b8,
+       0x1078, 0x61d3, 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0040, 0x8207,
+       0xd1cc, 0x0040, 0x81de, 0x6948, 0x6838, 0xd0fc, 0x0040, 0x81d6,
+       0x017e, 0x684c, 0x007e, 0x6850, 0x007e, 0xad90, 0x000d, 0xa198,
+       0x000d, 0x2009, 0x0020, 0x157e, 0x21a8, 0x2304, 0x2012, 0x8318,
+       0x8210, 0x00f0, 0x81c5, 0x157f, 0x007f, 0x6852, 0x007f, 0x684e,
+       0x017f, 0x2168, 0x1078, 0x13aa, 0x0078, 0x8201, 0x017e, 0x1078,
+       0x13aa, 0x0d7f, 0x1078, 0x8726, 0x0078, 0x8201, 0x6837, 0x0103,
+       0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0040, 0x81fd, 0xa086,
+       0x0028, 0x00c0, 0x81ef, 0x684b, 0x001c, 0x0078, 0x81ff, 0xd1dc,
+       0x0040, 0x81f6, 0x684b, 0x0015, 0x0078, 0x81ff, 0xd1d4, 0x0040,
+       0x81fd, 0x684b, 0x0007, 0x0078, 0x81ff, 0x684b, 0x0000, 0x1078,
+       0x4982, 0x1078, 0x8cc4, 0x00c0, 0x8207, 0x1078, 0x753d, 0x0d7f,
+       0x007c, 0x2019, 0x0001, 0x1078, 0x6e6c, 0x6003, 0x0002, 0x2001,
+       0xa5a2, 0x2004, 0x603e, 0x1078, 0x60b8, 0x1078, 0x61d3, 0x007c,
+       0x1078, 0x60b8, 0x1078, 0x2813, 0x0d7e, 0x6110, 0x2168, 0x1078,
+       0x8a44, 0x0040, 0x822d, 0x6837, 0x0103, 0x684b, 0x0029, 0x6847,
+       0x0000, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x0d7f, 0x1078, 0x753d,
+       0x1078, 0x61d3, 0x007c, 0x684b, 0x0015, 0xd1fc, 0x0040, 0x823f,
+       0x684b, 0x0007, 0x8002, 0x8000, 0x810a, 0xa189, 0x0000, 0x6962,
+       0x685e, 0x007c, 0xa182, 0x0040, 0x0079, 0x8246, 0x8259, 0x8259,
+       0x8259, 0x8259, 0x8259, 0x825b, 0x8259, 0x8333, 0x833f, 0x8259,
+       0x8259, 0x8259, 0x8259, 0x8259, 0x8259, 0x8259, 0x8259, 0x8259,
+       0x8259, 0x1078, 0x1328, 0x077e, 0x0f7e, 0x0e7e, 0x0d7e, 0x2071,
+       0xa88c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x0f7e, 0x2c78,
+       0x1078, 0x4893, 0x0f7f, 0x0040, 0x827e, 0xa684, 0x00ff, 0x00c0,
+       0x827e, 0x6024, 0xd0f4, 0x00c0, 0x827a, 0x7808, 0xa086, 0x0000,
+       0x00c0, 0x827e, 0x1078, 0x8cfa, 0x0078, 0x832e, 0x7e46, 0x7f4c,
+       0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff,
+       0x0040, 0x8323, 0xa694, 0xff00, 0xa284, 0x0c00, 0x0040, 0x8294,
+       0x7018, 0x7862, 0x701c, 0x785e, 0xa284, 0x0300, 0x0040, 0x8320,
+       0xa686, 0x0100, 0x00c0, 0x82a6, 0x2001, 0xa899, 0x2004, 0xa005,
+       0x00c0, 0x82a6, 0xc6c4, 0x7e46, 0x0078, 0x8287, 0x1078, 0x1381,
+       0x1040, 0x1328, 0x2d00, 0x784a, 0x7f4c, 0xa7bd, 0x0200, 0x7f4e,
+       0x6837, 0x0103, 0x7838, 0x683a, 0x783c, 0x683e, 0x7840, 0x6842,
+       0x6e46, 0xa68c, 0x0c00, 0x0040, 0x82c1, 0x7318, 0x6b62, 0x731c,
+       0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0040, 0x82dd, 0xa186,
+       0x0028, 0x00c0, 0x82cf, 0x684b, 0x001c, 0x0078, 0x82df, 0xd6dc,
+       0x0040, 0x82d6, 0x684b, 0x0015, 0x0078, 0x82df, 0xd6d4, 0x0040,
+       0x82dd, 0x684b, 0x0007, 0x0078, 0x82df, 0x684b, 0x0000, 0x6f4e,
+       0x7850, 0x6852, 0x7854, 0x6856, 0xa01e, 0xd6c4, 0x0040, 0x82fd,
+       0x7328, 0x732c, 0x6b56, 0x83ff, 0x0040, 0x82fd, 0xa38a, 0x0009,
+       0x0048, 0x82f4, 0x2019, 0x0008, 0x037e, 0x2308, 0x2019, 0xa898,
+       0xad90, 0x0019, 0x1078, 0x8739, 0x037f, 0xd6cc, 0x0040, 0x8320,
+       0x7124, 0x695a, 0x81ff, 0x0040, 0x8320, 0xa192, 0x0021, 0x00c8,
+       0x8314, 0x2071, 0xa898, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d,
+       0x1078, 0x8739, 0x0078, 0x8320, 0x7838, 0xd0fc, 0x0040, 0x831d,
+       0x2009, 0x0020, 0x695a, 0x0078, 0x8309, 0x2d78, 0x1078, 0x86d1,
+       0xd6dc, 0x00c0, 0x8326, 0xa006, 0x0078, 0x832c, 0x2001, 0x0001,
+       0x2071, 0xa88c, 0x7218, 0x731c, 0x1078, 0x1645, 0x0d7f, 0x0e7f,
+       0x0f7f, 0x077f, 0x007c, 0x2001, 0xa5a2, 0x2004, 0x603e, 0x20e1,
+       0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x15ec, 0x007c, 0x2001,
+       0xa5a2, 0x2004, 0x603e, 0x0d7e, 0x6003, 0x0002, 0x6110, 0x2168,
+       0x694c, 0xd1e4, 0x0040, 0x846b, 0x603f, 0x0000, 0x0f7e, 0x2c78,
+       0x1078, 0x4893, 0x0f7f, 0x0040, 0x8385, 0x6814, 0x6910, 0xa115,
+       0x0040, 0x8385, 0x6a60, 0xa206, 0x00c0, 0x8362, 0x685c, 0xa106,
+       0x0040, 0x8385, 0x684c, 0xc0e4, 0x684e, 0x6847, 0x0000, 0x6863,
+       0x0000, 0x685f, 0x0000, 0x6024, 0xd0f4, 0x00c0, 0x837a, 0x697c,
+       0x6810, 0xa102, 0x603a, 0x6980, 0x6814, 0xa103, 0x6036, 0x6024,
+       0xc0f5, 0x6026, 0x0d7e, 0x6018, 0x2068, 0x683c, 0x8000, 0x683e,
+       0x0d7f, 0x1078, 0x8cfa, 0x0078, 0x846b, 0x694c, 0xd1cc, 0x0040,
+       0x8430, 0x6948, 0x6838, 0xd0fc, 0x0040, 0x83ea, 0x017e, 0x684c,
+       0x007e, 0x6850, 0x007e, 0x0f7e, 0x2178, 0x7944, 0xa184, 0x00ff,
+       0xa0b6, 0x0002, 0x0040, 0x83bf, 0xa086, 0x0028, 0x00c0, 0x83a6,
+       0x684b, 0x001c, 0x784b, 0x001c, 0x0078, 0x83ca, 0xd1dc, 0x0040,
+       0x83b6, 0x684b, 0x0015, 0x784b, 0x0015, 0x1078, 0x8ea5, 0x0040,
+       0x83b4, 0x7944, 0xc1dc, 0x7946, 0x0078, 0x83ca, 0xd1d4, 0x0040,
+       0x83bf, 0x684b, 0x0007, 0x784b, 0x0007, 0x0078, 0x83ca, 0x684c,
+       0xd0ac, 0x0040, 0x83ca, 0x6810, 0x6914, 0xa115, 0x0040, 0x83ca,
+       0x1078, 0x8233, 0x6848, 0x784a, 0x6860, 0x7862, 0x685c, 0x785e,
+       0xad90, 0x000d, 0xaf98, 0x000d, 0x2009, 0x0020, 0x157e, 0x21a8,
+       0x2304, 0x2012, 0x8318, 0x8210, 0x00f0, 0x83d8, 0x157f, 0x0f7f,
+       0x007f, 0x6852, 0x007f, 0x684e, 0x017f, 0x2168, 0x1078, 0x13aa,
+       0x0078, 0x8465, 0x017e, 0x0f7e, 0x2178, 0x7944, 0xa184, 0x00ff,
+       0xa0b6, 0x0002, 0x0040, 0x8417, 0xa086, 0x0028, 0x00c0, 0x83fe,
+       0x684b, 0x001c, 0x784b, 0x001c, 0x0078, 0x8422, 0xd1dc, 0x0040,
+       0x840e, 0x684b, 0x0015, 0x784b, 0x0015, 0x1078, 0x8ea5, 0x0040,
+       0x840c, 0x7944, 0xc1dc, 0x7946, 0x0078, 0x8422, 0xd1d4, 0x0040,
+       0x8417, 0x684b, 0x0007, 0x784b, 0x0007, 0x0078, 0x8422, 0x684c,
+       0xd0ac, 0x0040, 0x8422, 0x6810, 0x6914, 0xa115, 0x0040, 0x8422,
+       0x1078, 0x8233, 0x6860, 0x7862, 0x685c, 0x785e, 0x684c, 0x784e,
+       0x0f7f, 0x1078, 0x13aa, 0x0d7f, 0x1078, 0x8726, 0x0078, 0x8465,
+       0x6837, 0x0103, 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0040,
+       0x8456, 0xa086, 0x0028, 0x00c0, 0x8441, 0x684b, 0x001c, 0x0078,
+       0x8463, 0xd1dc, 0x0040, 0x844f, 0x684b, 0x0015, 0x1078, 0x8ea5,
+       0x0040, 0x844d, 0x6944, 0xc1dc, 0x6946, 0x0078, 0x8463, 0xd1d4,
+       0x0040, 0x8456, 0x684b, 0x0007, 0x0078, 0x8463, 0x684b, 0x0000,
+       0x684c, 0xd0ac, 0x0040, 0x8463, 0x6810, 0x6914, 0xa115, 0x0040,
+       0x8463, 0x1078, 0x8233, 0x1078, 0x4982, 0x1078, 0x8cc4, 0x00c0,
+       0x846b, 0x1078, 0x753d, 0x0d7f, 0x007c, 0x1078, 0x6010, 0x0078,
+       0x8473, 0x1078, 0x60b8, 0x1078, 0x8a44, 0x0040, 0x8492, 0x0d7e,
+       0x6110, 0x2168, 0x6837, 0x0103, 0x2009, 0xa30c, 0x210c, 0xd18c,
+       0x00c0, 0x849d, 0xd184, 0x00c0, 0x8499, 0x6108, 0x694a, 0xa18e,
+       0x0029, 0x00c0, 0x848d, 0x1078, 0xa181, 0x6847, 0x0000, 0x1078,
+       0x4982, 0x0d7f, 0x1078, 0x753d, 0x1078, 0x6109, 0x1078, 0x61d3,
+       0x007c, 0x684b, 0x0004, 0x0078, 0x848d, 0x684b, 0x0004, 0x0078,
+       0x848d, 0xa182, 0x0040, 0x0079, 0x84a5, 0x84b8, 0x84b8, 0x84b8,
+       0x84b8, 0x84b8, 0x84ba, 0x84b8, 0x84bd, 0x84b8, 0x84b8, 0x84b8,
+       0x84b8, 0x84b8, 0x84b8, 0x84b8, 0x84b8, 0x84b8, 0x84b8, 0x84b8,
+       0x1078, 0x1328, 0x1078, 0x753d, 0x007c, 0x007e, 0x027e, 0xa016,
+       0x1078, 0x15ec, 0x027f, 0x007f, 0x007c, 0xa182, 0x0085, 0x0079,
+       0x84c9, 0x84d2, 0x84d0, 0x84d0, 0x84de, 0x84d0, 0x84d0, 0x84d0,
+       0x1078, 0x1328, 0x6003, 0x0001, 0x6106, 0x1078, 0x5bf8, 0x127e,
+       0x2091, 0x8000, 0x1078, 0x6109, 0x127f, 0x007c, 0x027e, 0x057e,
+       0x0d7e, 0x0e7e, 0x2071, 0xa880, 0x7224, 0x6212, 0x7220, 0x1078,
+       0x8a30, 0x0040, 0x8503, 0x2268, 0x6800, 0xa086, 0x0000, 0x0040,
+       0x8503, 0x6018, 0x6d18, 0xa52e, 0x00c0, 0x8503, 0x0c7e, 0x2d60,
+       0x1078, 0x874a, 0x0c7f, 0x0040, 0x8503, 0x6803, 0x0002, 0x6007,
+       0x0086, 0x0078, 0x8505, 0x6007, 0x0087, 0x6003, 0x0001, 0x1078,
+       0x5bf8, 0x1078, 0x6109, 0x0f7e, 0x2278, 0x1078, 0x4893, 0x0f7f,
+       0x0040, 0x851d, 0x6824, 0xd0ec, 0x0040, 0x851d, 0x0c7e, 0x2260,
+       0x603f, 0x0000, 0x1078, 0x8cfa, 0x0c7f, 0x0e7f, 0x0d7f, 0x057f,
+       0x027f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x8533, 0x6004, 0xa08a,
+       0x0085, 0x1048, 0x1328, 0xa08a, 0x008c, 0x10c8, 0x1328, 0xa082,
+       0x0085, 0x0079, 0x8542, 0xa186, 0x0027, 0x0040, 0x853b, 0xa186,
+       0x0014, 0x10c0, 0x1328, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078,
+       0x6109, 0x007c, 0x8549, 0x854b, 0x854b, 0x8549, 0x8549, 0x8549,
+       0x8549, 0x1078, 0x1328, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078,
+       0x6109, 0x007c, 0xa186, 0x0013, 0x00c0, 0x855c, 0x6004, 0xa082,
+       0x0085, 0x2008, 0x0078, 0x8597, 0xa186, 0x0027, 0x00c0, 0x857f,
+       0x1078, 0x6010, 0x1078, 0x2813, 0x0d7e, 0x6010, 0x2068, 0x1078,
+       0x8a44, 0x0040, 0x8575, 0x6837, 0x0103, 0x6847, 0x0000, 0x684b,
+       0x0029, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x0d7f, 0x1078, 0x753d,
+       0x1078, 0x6109, 0x007c, 0x1078, 0x7583, 0x0078, 0x857a, 0xa186,
+       0x0014, 0x00c0, 0x857b, 0x1078, 0x6010, 0x0d7e, 0x6010, 0x2068,
+       0x1078, 0x8a44, 0x0040, 0x8575, 0x6837, 0x0103, 0x6847, 0x0000,
+       0x684b, 0x0006, 0x6850, 0xc0ec, 0x6852, 0x0078, 0x8571, 0x0079,
+       0x8599, 0x85a2, 0x85a0, 0x85a0, 0x85a0, 0x85a0, 0x85a0, 0x85bd,
+       0x1078, 0x1328, 0x1078, 0x6010, 0x6030, 0xa08c, 0xff00, 0x810f,
+       0xa186, 0x0039, 0x0040, 0x85b0, 0xa186, 0x0035, 0x00c0, 0x85b4,
+       0x2001, 0xa5a0, 0x0078, 0x85b6, 0x2001, 0xa5a1, 0x2004, 0x6016,
+       0x6003, 0x000c, 0x1078, 0x6109, 0x007c, 0x1078, 0x6010, 0x6030,
+       0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0040, 0x85cb, 0xa186,
+       0x0035, 0x00c0, 0x85cf, 0x2001, 0xa5a0, 0x0078, 0x85d1, 0x2001,
+       0xa5a1, 0x2004, 0x6016, 0x6003, 0x000e, 0x1078, 0x6109, 0x007c,
+       0xa182, 0x008c, 0x00c8, 0x85e2, 0xa182, 0x0085, 0x0048, 0x85e2,
+       0x0079, 0x85e5, 0x1078, 0x7583, 0x007c, 0x85ec, 0x85ec, 0x85ec,
+       0x85ec, 0x85ee, 0x8643, 0x85ec, 0x1078, 0x1328, 0x0f7e, 0x2c78,
+       0x1078, 0x4893, 0x0f7f, 0x0040, 0x8601, 0x6030, 0xa08c, 0xff00,
+       0x810f, 0xa186, 0x0039, 0x0040, 0x865a, 0xa186, 0x0035, 0x0040,
+       0x865a, 0x0d7e, 0x1078, 0x8bf4, 0x1078, 0x8a44, 0x0040, 0x8625,
+       0x6010, 0x2068, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0040, 0x8616,
+       0x684b, 0x0006, 0xc0ec, 0x6852, 0x0078, 0x8621, 0xd0bc, 0x0040,
+       0x861d, 0x684b, 0x0002, 0x0078, 0x8621, 0x684b, 0x0005, 0x1078,
+       0x8cc0, 0x6847, 0x0000, 0x1078, 0x4982, 0x2c68, 0x1078, 0x74d7,
+       0x0040, 0x863e, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0xa88e,
+       0x210c, 0x6136, 0x2009, 0xa88f, 0x210c, 0x613a, 0x6918, 0x611a,
+       0x6920, 0x6122, 0x601f, 0x0001, 0x1078, 0x5bf8, 0x2d60, 0x1078,
+       0x753d, 0x0d7f, 0x007c, 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f,
+       0x0040, 0x8680, 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0035,
+       0x0040, 0x865a, 0xa186, 0x001e, 0x0040, 0x865a, 0xa186, 0x0039,
+       0x00c0, 0x8680, 0x0d7e, 0x2c68, 0x1078, 0x8ef5, 0x00c0, 0x86a4,
+       0x1078, 0x74d7, 0x0040, 0x867d, 0x6106, 0x6003, 0x0001, 0x601f,
+       0x0001, 0x6918, 0x611a, 0x6928, 0x612a, 0x692c, 0x612e, 0x6930,
+       0xa18c, 0x00ff, 0x6132, 0x6934, 0x6136, 0x6938, 0x613a, 0x6920,
+       0x6122, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x2d60, 0x0078, 0x86a4,
+       0x0d7e, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x86a4, 0x6837,
+       0x0103, 0x6850, 0xd0b4, 0x0040, 0x8693, 0xc0ec, 0x6852, 0x684b,
+       0x0006, 0x0078, 0x869e, 0xd0bc, 0x0040, 0x869a, 0x684b, 0x0002,
+       0x0078, 0x869e, 0x684b, 0x0005, 0x1078, 0x8cc0, 0x6847, 0x0000,
+       0x1078, 0x4982, 0x1078, 0x8bf4, 0x0d7f, 0x1078, 0x753d, 0x007c,
+       0x017e, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x86b8,
+       0x6837, 0x0103, 0x684b, 0x0028, 0x6847, 0x0000, 0x1078, 0x4982,
+       0x0d7f, 0x017f, 0xa186, 0x0013, 0x0040, 0x86ca, 0xa186, 0x0014,
+       0x0040, 0x86ca, 0xa186, 0x0027, 0x0040, 0x86ca, 0x1078, 0x7583,
+       0x0078, 0x86d0, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078, 0x6109,
+       0x007c, 0x057e, 0x067e, 0x0d7e, 0x0f7e, 0x2029, 0x0001, 0xa182,
+       0x0101, 0x00c8, 0x86dd, 0x0078, 0x86df, 0x2009, 0x0100, 0x2130,
+       0x2069, 0xa898, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020, 0xaf90,
+       0x001d, 0x1078, 0x8739, 0xa6b2, 0x0020, 0x7804, 0xa06d, 0x0040,
+       0x86f3, 0x1078, 0x13aa, 0x1078, 0x1381, 0x0040, 0x871d, 0x8528,
+       0x6837, 0x0110, 0x683b, 0x0000, 0x2d20, 0x7c06, 0xa68a, 0x003d,
+       0x00c8, 0x8709, 0x2608, 0xad90, 0x000f, 0x1078, 0x8739, 0x0078,
+       0x871d, 0xa6b2, 0x003c, 0x2009, 0x003c, 0x2d78, 0xad90, 0x000f,
+       0x1078, 0x8739, 0x0078, 0x86f3, 0x0f7f, 0x852f, 0xa5ad, 0x0003,
+       0x7d36, 0xa5ac, 0x0000, 0x0078, 0x8722, 0x0f7f, 0x852f, 0xa5ad,
+       0x0003, 0x7d36, 0x0d7f, 0x067f, 0x057f, 0x007c, 0x0f7e, 0x8dff,
+       0x0040, 0x8737, 0x6804, 0xa07d, 0x0040, 0x8735, 0x6807, 0x0000,
+       0x1078, 0x4982, 0x2f68, 0x0078, 0x872a, 0x1078, 0x4982, 0x0f7f,
+       0x007c, 0x157e, 0xa184, 0x0001, 0x0040, 0x873f, 0x8108, 0x810c,
+       0x21a8, 0x2304, 0x8007, 0x2012, 0x8318, 0x8210, 0x00f0, 0x8741,
+       0x157f, 0x007c, 0x067e, 0x127e, 0x2091, 0x8000, 0x2031, 0x0001,
+       0x601c, 0xa084, 0x000f, 0x1079, 0x8766, 0x127f, 0x067f, 0x007c,
+       0x127e, 0x2091, 0x8000, 0x067e, 0x2031, 0x0000, 0x601c, 0xa084,
+       0x000f, 0x1079, 0x8766, 0x067f, 0x127f, 0x007c, 0x8780, 0x876e,
+       0x877b, 0x879c, 0x876e, 0x877b, 0x879c, 0x877b, 0x1078, 0x1328,
+       0x037e, 0x2019, 0x0010, 0x1078, 0x9a6a, 0x601f, 0x0006, 0x6003,
+       0x0007, 0x037f, 0x007c, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c,
+       0x0d7e, 0x86ff, 0x00c0, 0x8797, 0x6010, 0x2068, 0x1078, 0x8a44,
+       0x0040, 0x8799, 0xa00e, 0x2001, 0x0005, 0x1078, 0x4a60, 0x1078,
+       0x8cc0, 0x1078, 0x4982, 0x1078, 0x753d, 0xa085, 0x0001, 0x0d7f,
+       0x007c, 0xa006, 0x0078, 0x8797, 0x6000, 0xa08a, 0x0010, 0x10c8,
+       0x1328, 0x1079, 0x87a4, 0x007c, 0x87b4, 0x87d4, 0x87b6, 0x87f7,
+       0x87d0, 0x87b4, 0x877b, 0x8780, 0x8780, 0x877b, 0x877b, 0x877b,
+       0x877b, 0x877b, 0x877b, 0x877b, 0x1078, 0x1328, 0x86ff, 0x00c0,
+       0x87cd, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x87c2,
+       0x1078, 0x8cc0, 0x0d7f, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f,
+       0x0002, 0x1078, 0x5bf8, 0x1078, 0x6109, 0xa085, 0x0001, 0x007c,
+       0x1078, 0x1749, 0x0078, 0x87b6, 0x0e7e, 0x2071, 0xa5ab, 0x7024,
+       0xac06, 0x00c0, 0x87dd, 0x1078, 0x6dda, 0x601c, 0xa084, 0x000f,
+       0xa086, 0x0006, 0x00c0, 0x87ef, 0x087e, 0x097e, 0x2049, 0x0001,
+       0x2c40, 0x1078, 0x7058, 0x097f, 0x087f, 0x0078, 0x87f1, 0x1078,
+       0x6cd2, 0x0e7f, 0x00c0, 0x87b6, 0x1078, 0x877b, 0x007c, 0x037e,
+       0x0e7e, 0x2071, 0xa5ab, 0x703c, 0xac06, 0x00c0, 0x8807, 0x2019,
+       0x0000, 0x1078, 0x6e6c, 0x0e7f, 0x037f, 0x0078, 0x87b6, 0x1078,
+       0x719a, 0x0e7f, 0x037f, 0x00c0, 0x87b6, 0x1078, 0x877b, 0x007c,
+       0x0c7e, 0x601c, 0xa084, 0x000f, 0x1079, 0x8818, 0x0c7f, 0x007c,
+       0x8827, 0x8895, 0x89cd, 0x8832, 0x8c01, 0x8827, 0x9a5b, 0x753d,
+       0x8895, 0x1078, 0x8c3b, 0x00c0, 0x8827, 0x1078, 0x7a05, 0x007c,
+       0x1078, 0x6010, 0x1078, 0x6109, 0x1078, 0x753d, 0x007c, 0x6017,
+       0x0001, 0x007c, 0x6010, 0xa080, 0x0019, 0x2c02, 0x6000, 0xa08a,
+       0x0010, 0x10c8, 0x1328, 0x1079, 0x883e, 0x007c, 0x884e, 0x8850,
+       0x8872, 0x8884, 0x8891, 0x884e, 0x8827, 0x8827, 0x8827, 0x8884,
+       0x8884, 0x884e, 0x884e, 0x884e, 0x884e, 0x888e, 0x1078, 0x1328,
+       0x0e7e, 0x6010, 0x2070, 0x7050, 0xc0b5, 0x7052, 0x2071, 0xa5ab,
+       0x7024, 0xac06, 0x0040, 0x886e, 0x1078, 0x6cd2, 0x6007, 0x0085,
+       0x6003, 0x000b, 0x601f, 0x0002, 0x2001, 0xa5a1, 0x2004, 0x6016,
+       0x1078, 0x5bf8, 0x1078, 0x6109, 0x0e7f, 0x007c, 0x6017, 0x0001,
+       0x0078, 0x886c, 0x0d7e, 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852,
+       0x0d7f, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x1078,
+       0x5bf8, 0x1078, 0x6109, 0x007c, 0x0d7e, 0x6017, 0x0001, 0x6010,
+       0x2068, 0x6850, 0xc0b5, 0x6852, 0x0d7f, 0x007c, 0x1078, 0x753d,
+       0x007c, 0x1078, 0x1749, 0x0078, 0x8872, 0x6000, 0xa08a, 0x0010,
+       0x10c8, 0x1328, 0x1079, 0x889d, 0x007c, 0x88ad, 0x882f, 0x88af,
+       0x88ad, 0x88af, 0x88af, 0x8828, 0x88ad, 0x8821, 0x8821, 0x88ad,
+       0x88ad, 0x88ad, 0x88ad, 0x88ad, 0x88ad, 0x1078, 0x1328, 0x0d7e,
+       0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x0d7f, 0xa08a, 0x000c,
+       0x10c8, 0x1328, 0x1079, 0x88bd, 0x007c, 0x88c9, 0x8971, 0x88cb,
+       0x890b, 0x88cb, 0x890b, 0x88cb, 0x88d8, 0x88c9, 0x890b, 0x88c9,
+       0x88f5, 0x1078, 0x1328, 0x6004, 0xa08e, 0x0016, 0x0040, 0x8906,
+       0xa08e, 0x0004, 0x0040, 0x8906, 0xa08e, 0x0002, 0x0040, 0x8906,
+       0x6004, 0x1078, 0x8c3b, 0x0040, 0x898c, 0xa08e, 0x0021, 0x0040,
+       0x8990, 0xa08e, 0x0022, 0x0040, 0x898c, 0xa08e, 0x003d, 0x0040,
+       0x8990, 0xa08e, 0x0039, 0x0040, 0x8994, 0xa08e, 0x0035, 0x0040,
+       0x8994, 0xa08e, 0x001e, 0x0040, 0x8908, 0xa08e, 0x0001, 0x00c0,
+       0x8904, 0x0d7e, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x0d7f,
+       0xa086, 0x0006, 0x0040, 0x8906, 0x1078, 0x2813, 0x1078, 0x7a05,
+       0x1078, 0x8c01, 0x007c, 0x0c7e, 0x0d7e, 0x6104, 0xa186, 0x0016,
+       0x0040, 0x8961, 0xa186, 0x0002, 0x00c0, 0x8934, 0x6018, 0x2068,
+       0x68a0, 0xd0bc, 0x00c0, 0x89b8, 0x6840, 0xa084, 0x00ff, 0xa005,
+       0x0040, 0x8934, 0x8001, 0x6842, 0x6013, 0x0000, 0x601f, 0x0007,
+       0x6017, 0x0398, 0x1078, 0x74d7, 0x0040, 0x8934, 0x2d00, 0x601a,
+       0x601f, 0x0001, 0x0078, 0x8961, 0x0d7f, 0x0c7f, 0x6004, 0xa08e,
+       0x0002, 0x00c0, 0x8952, 0x6018, 0xa080, 0x0028, 0x2004, 0xa086,
+       0x007e, 0x00c0, 0x8952, 0x2009, 0xa332, 0x2104, 0xc085, 0x200a,
+       0x0e7e, 0x2071, 0xa300, 0x1078, 0x41f5, 0x0e7f, 0x1078, 0x7a05,
+       0x0078, 0x8956, 0x1078, 0x7a05, 0x1078, 0x2813, 0x0e7e, 0x127e,
+       0x2091, 0x8000, 0x1078, 0x2839, 0x127f, 0x0e7f, 0x1078, 0x8c01,
+       0x007c, 0x2001, 0x0002, 0x1078, 0x443f, 0x6003, 0x0001, 0x6007,
+       0x0002, 0x1078, 0x5c45, 0x1078, 0x6109, 0x0d7f, 0x0c7f, 0x0078,
+       0x8960, 0x0c7e, 0x0d7e, 0x6104, 0xa186, 0x0016, 0x0040, 0x8961,
+       0x6018, 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0040, 0x8934,
+       0x8001, 0x6842, 0x6003, 0x0001, 0x1078, 0x5c45, 0x1078, 0x6109,
+       0x0d7f, 0x0c7f, 0x0078, 0x8960, 0x1078, 0x7a05, 0x0078, 0x8908,
+       0x1078, 0x7a28, 0x0078, 0x8908, 0x0d7e, 0x2c68, 0x6104, 0x1078,
+       0x8ef5, 0x0d7f, 0x0040, 0x89a0, 0x1078, 0x753d, 0x0078, 0x89b7,
+       0x6004, 0x8007, 0x6130, 0xa18c, 0x00ff, 0xa105, 0x6032, 0x6007,
+       0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x6038, 0x600a, 0x2001,
+       0xa5a1, 0x2004, 0x6016, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x007c,
+       0x0d7f, 0x0c7f, 0x1078, 0x7a05, 0x1078, 0x2813, 0x0e7e, 0x127e,
+       0x2091, 0x8000, 0x1078, 0x2839, 0x6013, 0x0000, 0x601f, 0x0007,
+       0x6017, 0x0398, 0x127f, 0x0e7f, 0x007c, 0x6000, 0xa08a, 0x0010,
+       0x10c8, 0x1328, 0x1079, 0x89d5, 0x007c, 0x89e5, 0x89e5, 0x89e5,
+       0x89e5, 0x89e5, 0x89e5, 0x89e5, 0x89e5, 0x89e5, 0x8827, 0x89e5,
+       0x882f, 0x89e7, 0x882f, 0x89f5, 0x89e5, 0x1078, 0x1328, 0x6004,
+       0xa086, 0x008b, 0x0040, 0x89f5, 0x6007, 0x008b, 0x6003, 0x000d,
+       0x1078, 0x5bf8, 0x1078, 0x6109, 0x007c, 0x1078, 0x8bf4, 0x1078,
+       0x8a44, 0x0040, 0x8a2d, 0x1078, 0x2813, 0x0d7e, 0x1078, 0x8a44,
+       0x0040, 0x8a0f, 0x6010, 0x2068, 0x6837, 0x0103, 0x684b, 0x0006,
+       0x6847, 0x0000, 0x6850, 0xc0ed, 0x6852, 0x1078, 0x4982, 0x2c68,
+       0x1078, 0x74d7, 0x0040, 0x8a1d, 0x6818, 0x601a, 0x0c7e, 0x2d60,
+       0x1078, 0x8c01, 0x0c7f, 0x0078, 0x8a1e, 0x2d60, 0x0d7f, 0x6013,
+       0x0000, 0x601f, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078,
+       0x5c45, 0x1078, 0x6109, 0x0078, 0x8a2f, 0x1078, 0x8c01, 0x007c,
+       0xa284, 0x000f, 0x00c0, 0x8a41, 0xa282, 0xaa00, 0x0048, 0x8a41,
+       0x2001, 0xa315, 0x2004, 0xa202, 0x00c8, 0x8a41, 0xa085, 0x0001,
+       0x007c, 0xa006, 0x0078, 0x8a40, 0x027e, 0x0e7e, 0x2071, 0xa300,
+       0x6210, 0x7058, 0xa202, 0x0048, 0x8a56, 0x705c, 0xa202, 0x00c8,
+       0x8a56, 0xa085, 0x0001, 0x0e7f, 0x027f, 0x007c, 0xa006, 0x0078,
+       0x8a53, 0x0e7e, 0x0c7e, 0x037e, 0x007e, 0x127e, 0x2091, 0x8000,
+       0x2061, 0xaa00, 0x2071, 0xa300, 0x7344, 0x7060, 0xa302, 0x00c8,
+       0x8a83, 0x601c, 0xa206, 0x00c0, 0x8a7b, 0x1078, 0x8d66, 0x0040,
+       0x8a7b, 0x1078, 0x8c3b, 0x00c0, 0x8a77, 0x1078, 0x7a05, 0x0c7e,
+       0x1078, 0x753d, 0x0c7f, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8,
+       0x8a83, 0x0078, 0x8a64, 0x127f, 0x007f, 0x037f, 0x0c7f, 0x0e7f,
+       0x007c, 0x0e7e, 0x0c7e, 0x017e, 0xa188, 0xa434, 0x210c, 0x81ff,
+       0x0040, 0x8aa1, 0x2061, 0xaa00, 0x2071, 0xa300, 0x017e, 0x1078,
+       0x74d7, 0x017f, 0x0040, 0x8aa4, 0x611a, 0x1078, 0x2813, 0x1078,
+       0x753d, 0xa006, 0x0078, 0x8aa6, 0xa085, 0x0001, 0x017f, 0x0c7f,
+       0x0e7f, 0x007c, 0x0c7e, 0x057e, 0x127e, 0x2091, 0x8000, 0x0c7e,
+       0x1078, 0x74d7, 0x057f, 0x0040, 0x8ac3, 0x6612, 0x651a, 0x601f,
+       0x0003, 0x2009, 0x004b, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f,
+       0x057f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8abf, 0x0c7e, 0x057e,
+       0x127e, 0x2091, 0x8000, 0x62a0, 0x0c7e, 0x1078, 0x74d7, 0x057f,
+       0x0040, 0x8af1, 0x6013, 0x0000, 0x651a, 0x601f, 0x0003, 0x0c7e,
+       0x2560, 0x1078, 0x471b, 0x0c7f, 0x1078, 0x5d53, 0x077e, 0x2039,
+       0x0000, 0x1078, 0x5c78, 0x2c08, 0x1078, 0x9c38, 0x077f, 0x2009,
+       0x004c, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f, 0x057f, 0x0c7f,
+       0x007c, 0xa006, 0x0078, 0x8aed, 0x0f7e, 0x0c7e, 0x047e, 0x0c7e,
+       0x1078, 0x74d7, 0x2c78, 0x0c7f, 0x0040, 0x8b0e, 0x7e12, 0x2c00,
+       0x781a, 0x781f, 0x0003, 0x2021, 0x0005, 0x1078, 0x8b4e, 0x2f60,
+       0x2009, 0x004d, 0x1078, 0x756c, 0xa085, 0x0001, 0x047f, 0x0c7f,
+       0x0f7f, 0x007c, 0x0f7e, 0x0c7e, 0x047e, 0x0c7e, 0x1078, 0x74d7,
+       0x2c78, 0x0c7f, 0x0040, 0x8b2c, 0x7e12, 0x2c00, 0x781a, 0x781f,
+       0x0003, 0x2021, 0x0005, 0x1078, 0x8b4e, 0x2f60, 0x2009, 0x004e,
+       0x1078, 0x756c, 0xa085, 0x0001, 0x047f, 0x0c7f, 0x0f7f, 0x007c,
+       0x0f7e, 0x0c7e, 0x047e, 0x0c7e, 0x1078, 0x74d7, 0x2c78, 0x0c7f,
+       0x0040, 0x8b4a, 0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003, 0x2021,
+       0x0004, 0x1078, 0x8b4e, 0x2f60, 0x2009, 0x0052, 0x1078, 0x756c,
+       0xa085, 0x0001, 0x047f, 0x0c7f, 0x0f7f, 0x007c, 0x097e, 0x077e,
+       0x127e, 0x2091, 0x8000, 0x1078, 0x46a7, 0x0040, 0x8b5b, 0x2001,
+       0x8b53, 0x0078, 0x8b61, 0x1078, 0x466d, 0x0040, 0x8b6a, 0x2001,
+       0x8b5b, 0x007e, 0xa00e, 0x2400, 0x1078, 0x4a60, 0x1078, 0x4982,
+       0x007f, 0x007a, 0x2418, 0x1078, 0x5fa7, 0x62a0, 0x087e, 0x2041,
+       0x0001, 0x2039, 0x0001, 0x2608, 0x1078, 0x5d6d, 0x087f, 0x1078,
+       0x5c78, 0x2f08, 0x2648, 0x1078, 0x9c38, 0x613c, 0x81ff, 0x1040,
+       0x5e21, 0x127f, 0x077f, 0x097f, 0x007c, 0x0c7e, 0x127e, 0x2091,
+       0x8000, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040, 0x8b9e, 0x660a,
+       0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x001f, 0x1078,
+       0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078,
+       0x8b9b, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, 0x74d7,
+       0x017f, 0x0040, 0x8bba, 0x660a, 0x611a, 0x601f, 0x0008, 0x2d00,
+       0x6012, 0x2009, 0x0021, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f,
+       0x0c7f, 0x007c, 0xa006, 0x0078, 0x8bb7, 0x0c7e, 0x127e, 0x2091,
+       0x8000, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040, 0x8bd6, 0x660a,
+       0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x003d, 0x1078,
+       0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078,
+       0x8bd3, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, 0x74d7,
+       0x017f, 0x0040, 0x8bf1, 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012,
+       0x2009, 0x0000, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f,
+       0x007c, 0xa006, 0x0078, 0x8bee, 0x027e, 0x0d7e, 0x6218, 0x2268,
+       0x6a3c, 0x82ff, 0x0040, 0x8bfe, 0x8211, 0x6a3e, 0x0d7f, 0x027f,
+       0x007c, 0x007e, 0x6000, 0xa086, 0x0000, 0x0040, 0x8c13, 0x6013,
+       0x0000, 0x601f, 0x0007, 0x2001, 0xa5a1, 0x2004, 0x6016, 0x1078,
+       0xa134, 0x603f, 0x0000, 0x007f, 0x007c, 0x067e, 0x0c7e, 0x0d7e,
+       0x2031, 0xa352, 0x2634, 0xd6e4, 0x0040, 0x8c23, 0x6618, 0x2660,
+       0x6e48, 0x1078, 0x461b, 0x0d7f, 0x0c7f, 0x067f, 0x007c, 0x007e,
+       0x017e, 0x6004, 0xa08e, 0x0002, 0x0040, 0x8c38, 0xa08e, 0x0003,
+       0x0040, 0x8c38, 0xa08e, 0x0004, 0x0040, 0x8c38, 0xa085, 0x0001,
+       0x017f, 0x007f, 0x007c, 0x007e, 0x0d7e, 0x6010, 0xa06d, 0x0040,
+       0x8c48, 0x6838, 0xd0fc, 0x0040, 0x8c48, 0xa006, 0x0078, 0x8c4a,
+       0xa085, 0x0001, 0x0d7f, 0x007f, 0x007c, 0x0c7e, 0x127e, 0x2091,
+       0x8000, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040, 0x8c67, 0x611a,
+       0x601f, 0x0001, 0x2d00, 0x6012, 0x1078, 0x2813, 0x2009, 0x0028,
+       0x1078, 0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006,
+       0x0078, 0x8c64, 0xa186, 0x0015, 0x00c0, 0x8c7f, 0x2011, 0xa31f,
+       0x2204, 0xa086, 0x0074, 0x00c0, 0x8c7f, 0x1078, 0x7d0d, 0x6003,
+       0x0001, 0x6007, 0x0029, 0x1078, 0x5c45, 0x0078, 0x8c83, 0x1078,
+       0x7a05, 0x1078, 0x753d, 0x007c, 0xa186, 0x0016, 0x00c0, 0x8c8e,
+       0x2001, 0x0004, 0x1078, 0x443f, 0x0078, 0x8caf, 0xa186, 0x0015,
+       0x00c0, 0x8cb3, 0x2011, 0xa31f, 0x2204, 0xa086, 0x0014, 0x00c0,
+       0x8cb3, 0x0d7e, 0x6018, 0x2068, 0x1078, 0x457d, 0x0d7f, 0x1078,
+       0x7dba, 0x00c0, 0x8cb3, 0x0d7e, 0x6018, 0x2068, 0x6890, 0x0d7f,
+       0xa005, 0x0040, 0x8cb3, 0x2001, 0x0006, 0x1078, 0x443f, 0x1078,
+       0x7608, 0x0078, 0x8cb7, 0x1078, 0x7a05, 0x1078, 0x753d, 0x007c,
+       0x6848, 0xa086, 0x0005, 0x00c0, 0x8cbf, 0x1078, 0x8cc0, 0x007c,
+       0x6850, 0xc0ad, 0x6852, 0x007c, 0x0e7e, 0x2071, 0xa88c, 0x7014,
+       0xd0e4, 0x0040, 0x8cd5, 0x6013, 0x0000, 0x6003, 0x0001, 0x6007,
+       0x0050, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0e7f, 0x007c, 0x0c7e,
+       0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x0040, 0x8ce4, 0x601c,
+       0xa084, 0x000f, 0x1079, 0x8ce6, 0x0c7f, 0x007c, 0x8827, 0x8cf1,
+       0x8cf4, 0x8cf7, 0x9f00, 0x9f1c, 0x9f1f, 0x8827, 0x8827, 0x1078,
+       0x1328, 0x0005, 0x0005, 0x007c, 0x0005, 0x0005, 0x007c, 0x1078,
+       0x8cfa, 0x007c, 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0040, 0x8d29,
+       0x1078, 0x74d7, 0x00c0, 0x8d0a, 0x2001, 0xa5a2, 0x2004, 0x783e,
+       0x0078, 0x8d29, 0x7818, 0x601a, 0x781c, 0xa086, 0x0003, 0x0040,
+       0x8d17, 0x7808, 0x6036, 0x2f00, 0x603a, 0x0078, 0x8d1b, 0x7808,
+       0x603a, 0x2f00, 0x6036, 0x602a, 0x601f, 0x0001, 0x6007, 0x0035,
+       0x6003, 0x0001, 0x7920, 0x6122, 0x1078, 0x5bf8, 0x1078, 0x6109,
+       0x2f60, 0x0f7f, 0x007c, 0x017e, 0x0f7e, 0x682c, 0x6032, 0xa08e,
+       0x0001, 0x0040, 0x8d3c, 0xa086, 0x0005, 0x0040, 0x8d40, 0xa006,
+       0x602a, 0x602e, 0x0078, 0x8d51, 0x6824, 0xc0f4, 0xc0d5, 0x6826,
+       0x6810, 0x2078, 0x787c, 0x6938, 0xa102, 0x7880, 0x6934, 0xa103,
+       0x00c8, 0x8d37, 0x6834, 0x602a, 0x6838, 0xa084, 0xfffc, 0x683a,
+       0x602e, 0x2d00, 0x6036, 0x6808, 0x603a, 0x6918, 0x611a, 0x6920,
+       0x6122, 0x601f, 0x0001, 0x6007, 0x0039, 0x6003, 0x0001, 0x1078,
+       0x5bf8, 0x6803, 0x0002, 0x0f7f, 0x017f, 0x007c, 0x007e, 0x017e,
+       0x6004, 0xa08e, 0x0034, 0x0040, 0x8d8b, 0xa08e, 0x0035, 0x0040,
+       0x8d8b, 0xa08e, 0x0036, 0x0040, 0x8d8b, 0xa08e, 0x0037, 0x0040,
+       0x8d8b, 0xa08e, 0x0038, 0x0040, 0x8d8b, 0xa08e, 0x0039, 0x0040,
+       0x8d8b, 0xa08e, 0x003a, 0x0040, 0x8d8b, 0xa08e, 0x003b, 0x0040,
+       0x8d8b, 0xa085, 0x0001, 0x017f, 0x007f, 0x007c, 0x0f7e, 0x2c78,
+       0x1078, 0x4893, 0x00c0, 0x8d98, 0xa085, 0x0001, 0x0078, 0x8da7,
+       0x6024, 0xd0f4, 0x00c0, 0x8da6, 0xc0f5, 0x6026, 0x6010, 0x2078,
+       0x7828, 0x603a, 0x782c, 0x6036, 0x1078, 0x1749, 0xa006, 0x0f7f,
+       0x007c, 0x007e, 0x017e, 0x027e, 0x037e, 0x0e7e, 0x2001, 0xa59c,
+       0x200c, 0x8000, 0x2014, 0x2001, 0x0032, 0x1078, 0x5a98, 0x2001,
+       0xa5a0, 0x82ff, 0x00c0, 0x8dbe, 0x2011, 0x0002, 0x2202, 0x2001,
+       0xa59e, 0x200c, 0x8000, 0x2014, 0x2071, 0xa58c, 0x711a, 0x721e,
+       0x2001, 0x0064, 0x1078, 0x5a98, 0x2001, 0xa5a1, 0x82ff, 0x00c0,
+       0x8dd3, 0x2011, 0x0002, 0x2202, 0x2009, 0xa5a2, 0xa280, 0x000a,
+       0x200a, 0x0e7f, 0x037f, 0x027f, 0x017f, 0x007f, 0x007c, 0x007e,
+       0x0e7e, 0x2001, 0xa5a0, 0x2003, 0x0028, 0x2001, 0xa5a1, 0x2003,
+       0x0014, 0x2071, 0xa58c, 0x701b, 0x0000, 0x701f, 0x07d0, 0x2001,
+       0xa5a2, 0x2003, 0x001e, 0x0e7f, 0x007f, 0x007c, 0x0c7e, 0x127e,
+       0x2091, 0x8000, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040, 0x8e0e,
+       0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0033, 0x1078,
+       0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078,
+       0x8e0b, 0x0d7e, 0x0e7e, 0x0f7e, 0x2071, 0xa300, 0xa186, 0x0015,
+       0x00c0, 0x8e40, 0x707c, 0xa086, 0x0018, 0x00c0, 0x8e40, 0x6010,
+       0x2068, 0x6a3c, 0xd2e4, 0x00c0, 0x8e34, 0x2c78, 0x1078, 0x62c6,
+       0x0040, 0x8e48, 0x7068, 0x6a50, 0xa206, 0x00c0, 0x8e3c, 0x706c,
+       0x6a54, 0xa206, 0x00c0, 0x8e3c, 0x6218, 0xa290, 0x0028, 0x2214,
+       0x2009, 0x0000, 0x1078, 0x285b, 0x1078, 0x7608, 0x0078, 0x8e44,
+       0x1078, 0x7a05, 0x1078, 0x753d, 0x0f7f, 0x0e7f, 0x0d7f, 0x007c,
+       0x704c, 0xa080, 0x293f, 0x2004, 0x6a54, 0xa206, 0x0040, 0x8e34,
+       0x0078, 0x8e3c, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078,
+       0x74d7, 0x017f, 0x0040, 0x8e6a, 0x611a, 0x601f, 0x0001, 0x2d00,
+       0x6012, 0x2009, 0x0043, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f,
+       0x0c7f, 0x007c, 0xa006, 0x0078, 0x8e67, 0x0d7e, 0x0e7e, 0x0f7e,
+       0x2071, 0xa300, 0xa186, 0x0015, 0x00c0, 0x8e93, 0x707c, 0xa086,
+       0x0004, 0x00c0, 0x8e93, 0x6010, 0xa0e8, 0x000f, 0x2c78, 0x1078,
+       0x62c6, 0x0040, 0x8e9b, 0x7068, 0x6a08, 0xa206, 0x00c0, 0x8e8f,
+       0x706c, 0x6a0c, 0xa206, 0x00c0, 0x8e8f, 0x1078, 0x2813, 0x1078,
+       0x7608, 0x0078, 0x8e97, 0x1078, 0x7a05, 0x1078, 0x753d, 0x0f7f,
+       0x0e7f, 0x0d7f, 0x007c, 0x704c, 0xa080, 0x293f, 0x2004, 0x6a0c,
+       0xa206, 0x0040, 0x8e8d, 0x0078, 0x8e8f, 0x017e, 0x027e, 0x684c,
+       0xd0ac, 0x0040, 0x8ebd, 0x6914, 0x6a10, 0x2100, 0xa205, 0x0040,
+       0x8ebd, 0x6860, 0xa106, 0x00c0, 0x8eb9, 0x685c, 0xa206, 0x0040,
+       0x8ebd, 0x6962, 0x6a5e, 0xa085, 0x0001, 0x027f, 0x017f, 0x007c,
+       0x0e7e, 0x127e, 0x2071, 0xa300, 0x2091, 0x8000, 0x7544, 0xa582,
+       0x0001, 0x0048, 0x8ef2, 0x7048, 0x2060, 0x6000, 0xa086, 0x0000,
+       0x0040, 0x8ede, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8, 0x8eda,
+       0x0078, 0x8ecd, 0x2061, 0xaa00, 0x0078, 0x8ecd, 0x6003, 0x0008,
+       0x8529, 0x7546, 0xaca8, 0x0010, 0x7054, 0xa502, 0x00c8, 0x8eee,
+       0x754a, 0xa085, 0x0001, 0x127f, 0x0e7f, 0x007c, 0x704b, 0xaa00,
+       0x0078, 0x8ee9, 0xa006, 0x0078, 0x8eeb, 0x0c7e, 0x027e, 0x017e,
+       0xa186, 0x0035, 0x0040, 0x8eff, 0x6a34, 0x0078, 0x8f00, 0x6a28,
+       0x1078, 0x8a30, 0x0040, 0x8f29, 0x2260, 0x611c, 0xa186, 0x0003,
+       0x0040, 0x8f0e, 0xa186, 0x0006, 0x00c0, 0x8f25, 0x6834, 0xa206,
+       0x0040, 0x8f1d, 0x6838, 0xa206, 0x00c0, 0x8f25, 0x6108, 0x6834,
+       0xa106, 0x00c0, 0x8f25, 0x0078, 0x8f22, 0x6008, 0x6938, 0xa106,
+       0x00c0, 0x8f25, 0x6018, 0x6918, 0xa106, 0x017f, 0x027f, 0x0c7f,
+       0x007c, 0xa085, 0x0001, 0x0078, 0x8f25, 0x067e, 0x6000, 0xa0b2,
+       0x0010, 0x10c8, 0x1328, 0x1079, 0x8f37, 0x067f, 0x007c, 0x8f47,
+       0x93bb, 0x94d3, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x8f81,
+       0x955e, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x1078,
+       0x1328, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x1328, 0x1079,
+       0x8f53, 0x067f, 0x007c, 0x8f63, 0x99f6, 0x8f63, 0x8f63, 0x8f63,
+       0x8f63, 0x8f63, 0x8f63, 0x99b4, 0x9a44, 0x8f63, 0xa053, 0xa087,
+       0xa053, 0xa087, 0x8f63, 0x1078, 0x1328, 0x067e, 0x6000, 0xa0b2,
+       0x0010, 0x10c8, 0x1328, 0x1079, 0x8f6f, 0x067f, 0x007c, 0x8f7f,
+       0x969f, 0x976a, 0x9798, 0x9813, 0x8f7f, 0x9919, 0x98c1, 0x956a,
+       0x9988, 0x999e, 0x8f7f, 0x8f7f, 0x8f7f, 0x8f7f, 0x8f7f, 0x1078,
+       0x1328, 0xa1b2, 0x0044, 0x10c8, 0x1328, 0x2100, 0x0079, 0x8f88,
+       0x8fc8, 0x919a, 0x8fc8, 0x8fc8, 0x8fc8, 0x91a2, 0x8fc8, 0x8fc8,
+       0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8,
+       0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fca,
+       0x902d, 0x9038, 0x9081, 0x909c, 0x911b, 0x918b, 0x8fc8, 0x8fc8,
+       0x91a6, 0x8fc8, 0x8fc8, 0x91b5, 0x91bc, 0x8fc8, 0x8fc8, 0x8fc8,
+       0x8fc8, 0x8fc8, 0x91ea, 0x8fc8, 0x8fc8, 0x91f5, 0x8fc8, 0x8fc8,
+       0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x920a, 0x8fc8, 0x8fc8, 0x8fc8,
+       0x9291, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x9305,
+       0x1078, 0x1328, 0x1078, 0x4897, 0x00c0, 0x8fd7, 0x2001, 0xa332,
+       0x2004, 0xa084, 0x0009, 0xa086, 0x0008, 0x00c0, 0x8fdf, 0x6007,
+       0x0009, 0x602b, 0x0009, 0x6013, 0x0000, 0x0078, 0x9195, 0x1078,
+       0x4887, 0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e, 0x6218, 0x2270,
+       0x72a0, 0x027e, 0x2019, 0x0029, 0x1078, 0x5d53, 0x077e, 0x2039,
+       0x0000, 0x1078, 0x5c78, 0x2c08, 0x1078, 0x9c38, 0x077f, 0x017f,
+       0x2e60, 0x1078, 0x471b, 0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f,
+       0x6618, 0x0c7e, 0x2660, 0x1078, 0x4513, 0x0c7f, 0xa6b0, 0x0001,
+       0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x0048, 0x901f, 0x1078,
+       0x9b6c, 0x00c0, 0x907b, 0x1078, 0x9afd, 0x00c0, 0x901b, 0x6007,
+       0x0008, 0x0078, 0x9195, 0x6007, 0x0009, 0x0078, 0x9195, 0x1078,
+       0x9d45, 0x0040, 0x9029, 0x1078, 0x9b6c, 0x0040, 0x9013, 0x0078,
+       0x907b, 0x6013, 0x1900, 0x0078, 0x901b, 0x6106, 0x1078, 0x9aa8,
+       0x6007, 0x0006, 0x0078, 0x9195, 0x6007, 0x0007, 0x0078, 0x9195,
+       0x1078, 0xa0bf, 0x00c0, 0x9340, 0x0d7e, 0x6618, 0x2668, 0x6e04,
+       0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x905d, 0xa686,
+       0x0004, 0x0040, 0x905d, 0x6e04, 0xa6b4, 0x00ff, 0xa686, 0x0006,
+       0x0040, 0x905d, 0xa686, 0x0004, 0x0040, 0x905d, 0xa686, 0x0005,
+       0x0040, 0x905d, 0x0d7f, 0x0078, 0x907b, 0x1078, 0x9bd2, 0x00c0,
+       0x9076, 0xa686, 0x0006, 0x00c0, 0x906f, 0x027e, 0x6218, 0xa290,
+       0x0028, 0x2214, 0x2009, 0x0000, 0x1078, 0x285b, 0x027f, 0x1078,
+       0x457d, 0x6007, 0x000a, 0x0d7f, 0x0078, 0x9195, 0x6007, 0x000b,
+       0x0d7f, 0x0078, 0x9195, 0x1078, 0x2813, 0x6007, 0x0001, 0x0078,
+       0x9195, 0x1078, 0xa0bf, 0x00c0, 0x9340, 0x6618, 0x0d7e, 0x2668,
+       0x6e04, 0x0d7f, 0xa686, 0x0707, 0x0040, 0x907b, 0x027e, 0x6218,
+       0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x1078, 0x285b, 0x027f,
+       0x6007, 0x000c, 0x0078, 0x9195, 0x1078, 0x4897, 0x00c0, 0x90a9,
+       0x2001, 0xa332, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008, 0x00c0,
+       0x90b1, 0x6007, 0x0009, 0x602b, 0x0009, 0x6013, 0x0000, 0x0078,
+       0x9195, 0x1078, 0x4887, 0x6618, 0xa6b0, 0x0001, 0x2634, 0xa684,
+       0x00ff, 0xa082, 0x0006, 0x0048, 0x90f5, 0xa6b4, 0xff00, 0x8637,
+       0xa686, 0x0004, 0x0040, 0x90c8, 0xa686, 0x0006, 0x00c0, 0x907b,
+       0x1078, 0x9be1, 0x00c0, 0x90d0, 0x6007, 0x000e, 0x0078, 0x9195,
+       0x047e, 0x6418, 0xa4a0, 0x0028, 0x2424, 0xa4a4, 0x00ff, 0x8427,
+       0x047e, 0x1078, 0x2813, 0x047f, 0x017e, 0xa006, 0x2009, 0xa352,
+       0x210c, 0xd1a4, 0x0040, 0x90ef, 0x2009, 0x0029, 0x1078, 0x9ec0,
+       0x6018, 0x0d7e, 0x2068, 0x6800, 0xc0e5, 0x6802, 0x0d7f, 0x017f,
+       0x047f, 0x6007, 0x0001, 0x0078, 0x9195, 0x2001, 0x0001, 0x1078,
+       0x442b, 0x157e, 0x017e, 0x027e, 0x037e, 0x20a9, 0x0004, 0x2019,
+       0xa305, 0x2011, 0xa890, 0x1078, 0x7e55, 0x037f, 0x027f, 0x017f,
+       0x157f, 0xa005, 0x0040, 0x9115, 0xa6b4, 0xff00, 0x8637, 0xa686,
+       0x0006, 0x0040, 0x90c8, 0x0078, 0x907b, 0x6013, 0x1900, 0x6007,
+       0x0009, 0x0078, 0x9195, 0x1078, 0x4897, 0x00c0, 0x9128, 0x2001,
+       0xa332, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008, 0x00c0, 0x9130,
+       0x6007, 0x0009, 0x602b, 0x0009, 0x6013, 0x0000, 0x0078, 0x9195,
+       0x1078, 0x4887, 0x6618, 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff,
+       0xa082, 0x0006, 0x0048, 0x9178, 0xa6b4, 0xff00, 0x8637, 0xa686,
+       0x0004, 0x0040, 0x9147, 0xa686, 0x0006, 0x00c0, 0x907b, 0x1078,
+       0x9c0c, 0x00c0, 0x9153, 0x1078, 0x9afd, 0x00c0, 0x9153, 0x6007,
+       0x0010, 0x0078, 0x9195, 0x047e, 0x6418, 0xa4a0, 0x0028, 0x2424,
+       0xa4a4, 0x00ff, 0x8427, 0x047e, 0x1078, 0x2813, 0x047f, 0x017e,
+       0xa006, 0x2009, 0xa352, 0x210c, 0xd1a4, 0x0040, 0x9172, 0x2009,
+       0x0029, 0x1078, 0x9ec0, 0x6018, 0x0d7e, 0x2068, 0x6800, 0xc0e5,
+       0x6802, 0x0d7f, 0x017f, 0x047f, 0x6007, 0x0001, 0x0078, 0x9195,
+       0x1078, 0x9d45, 0x0040, 0x9185, 0xa6b4, 0xff00, 0x8637, 0xa686,
+       0x0006, 0x0040, 0x9147, 0x0078, 0x907b, 0x6013, 0x1900, 0x6007,
+       0x0009, 0x0078, 0x9195, 0x1078, 0xa0bf, 0x00c0, 0x9340, 0x1078,
+       0x9343, 0x00c0, 0x907b, 0x6007, 0x0012, 0x6003, 0x0001, 0x1078,
+       0x5c45, 0x007c, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078, 0x5c45,
+       0x0078, 0x9199, 0x6007, 0x0005, 0x0078, 0x919c, 0x1078, 0xa0bf,
+       0x00c0, 0x9340, 0x1078, 0x9343, 0x00c0, 0x907b, 0x6007, 0x0020,
+       0x6003, 0x0001, 0x1078, 0x5c45, 0x007c, 0x6007, 0x0023, 0x6003,
+       0x0001, 0x1078, 0x5c45, 0x007c, 0x1078, 0xa0bf, 0x00c0, 0x9340,
+       0x1078, 0x9343, 0x00c0, 0x907b, 0x017e, 0x027e, 0x2011, 0xa890,
+       0x2214, 0x2c08, 0x1078, 0x9e8c, 0x00c0, 0x91de, 0x2160, 0x6007,
+       0x0026, 0x6013, 0x1700, 0x2011, 0xa889, 0x2214, 0xa296, 0xffff,
+       0x00c0, 0x91e3, 0x6007, 0x0025, 0x0078, 0x91e3, 0x1078, 0x753d,
+       0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x1078, 0x5c45, 0x027f,
+       0x017f, 0x007c, 0x6106, 0x1078, 0x9363, 0x6007, 0x002b, 0x0078,
+       0x9195, 0x6007, 0x002c, 0x0078, 0x9195, 0x1078, 0xa0bf, 0x00c0,
+       0x9340, 0x1078, 0x9343, 0x00c0, 0x907b, 0x6106, 0x1078, 0x9368,
+       0x00c0, 0x9206, 0x6007, 0x002e, 0x0078, 0x9195, 0x6007, 0x002f,
+       0x0078, 0x9195, 0x0e7e, 0x0d7e, 0x0c7e, 0x6018, 0xa080, 0x0001,
+       0x200c, 0xa184, 0x00ff, 0xa086, 0x0006, 0x0040, 0x9223, 0xa184,
+       0xff00, 0x8007, 0xa086, 0x0006, 0x0040, 0x9223, 0x0c7f, 0x0d7f,
+       0x0e7f, 0x0078, 0x919a, 0x2001, 0xa371, 0x2004, 0xd0e4, 0x0040,
+       0x928d, 0x2071, 0xa88c, 0x7010, 0x6036, 0x7014, 0x603a, 0x7108,
+       0x720c, 0x2001, 0xa352, 0x2004, 0xd0a4, 0x0040, 0x9241, 0x6018,
+       0x2068, 0x6810, 0xa106, 0x00c0, 0x9241, 0x6814, 0xa206, 0x0040,
+       0x9265, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x00c0, 0x9281, 0x2069,
+       0xa300, 0x686c, 0xa206, 0x00c0, 0x9281, 0x6868, 0xa106, 0x00c0,
+       0x9281, 0x7210, 0x1078, 0x8a30, 0x0040, 0x9287, 0x1078, 0x9f31,
+       0x0040, 0x9287, 0x622a, 0x6007, 0x0036, 0x6003, 0x0001, 0x1078,
+       0x5bf8, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x7214, 0xa286, 0xffff,
+       0x0040, 0x9277, 0x1078, 0x8a30, 0x0040, 0x9287, 0xa280, 0x0002,
+       0x2004, 0x7110, 0xa106, 0x00c0, 0x9287, 0x0078, 0x9252, 0x7210,
+       0x2c08, 0x1078, 0x9e8c, 0x2c10, 0x2160, 0x0040, 0x9287, 0x0078,
+       0x9252, 0x6007, 0x0037, 0x6013, 0x1500, 0x0078, 0x925d, 0x6007,
+       0x0037, 0x6013, 0x1700, 0x0078, 0x925d, 0x6007, 0x0012, 0x0078,
+       0x925d, 0x6018, 0xa080, 0x0001, 0x2004, 0xa084, 0xff00, 0x8007,
+       0xa086, 0x0006, 0x00c0, 0x919a, 0x0e7e, 0x0d7e, 0x0c7e, 0x2001,
+       0xa371, 0x2004, 0xd0e4, 0x0040, 0x92fd, 0x2069, 0xa300, 0x2071,
+       0xa88c, 0x7008, 0x6036, 0x720c, 0x623a, 0xa286, 0xffff, 0x00c0,
+       0x92ba, 0x7208, 0x0c7e, 0x2c08, 0x1078, 0x9e8c, 0x2c10, 0x0c7f,
+       0x0040, 0x92f1, 0x1078, 0x8a30, 0x0040, 0x92f1, 0x0c7e, 0x027e,
+       0x2260, 0x1078, 0x874a, 0x027f, 0x0c7f, 0x7118, 0xa18c, 0xff00,
+       0x810f, 0xa186, 0x0001, 0x0040, 0x92db, 0xa186, 0x0005, 0x0040,
+       0x92d5, 0xa186, 0x0007, 0x00c0, 0x92e5, 0xa280, 0x0004, 0x2004,
+       0xa005, 0x0040, 0x92e5, 0x057e, 0x7510, 0x7614, 0x1078, 0x9f46,
+       0x057f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x6007, 0x003b, 0x602b,
+       0x0009, 0x6013, 0x2a00, 0x6003, 0x0001, 0x1078, 0x5bf8, 0x0078,
+       0x92e1, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013, 0x1700, 0x6003,
+       0x0001, 0x1078, 0x5bf8, 0x0078, 0x92e1, 0x6007, 0x003b, 0x602b,
+       0x000b, 0x6013, 0x0000, 0x0078, 0x925d, 0x0e7e, 0x027e, 0x1078,
+       0x4897, 0x0040, 0x933a, 0x1078, 0x4887, 0x1078, 0xa148, 0x00c0,
+       0x9338, 0x2071, 0xa300, 0x70c8, 0xc085, 0x70ca, 0x0f7e, 0x2079,
+       0x0100, 0x7294, 0xa284, 0x00ff, 0x706a, 0x78e6, 0xa284, 0xff00,
+       0x726c, 0xa205, 0x706e, 0x78ea, 0x0f7f, 0x70d3, 0x0000, 0x2001,
+       0xa352, 0x2004, 0xd0a4, 0x0040, 0x9331, 0x2011, 0xa5c4, 0x2013,
+       0x07d0, 0xd0ac, 0x00c0, 0x933a, 0x1078, 0x260d, 0x0078, 0x933a,
+       0x1078, 0xa178, 0x027f, 0x0e7f, 0x1078, 0x753d, 0x0078, 0x9199,
+       0x1078, 0x753d, 0x007c, 0x0d7e, 0x067e, 0x6618, 0x2668, 0x6e04,
+       0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x9360, 0xa686,
+       0x0004, 0x0040, 0x9360, 0x6e04, 0xa6b4, 0x00ff, 0xa686, 0x0006,
+       0x0040, 0x9360, 0xa686, 0x0004, 0x0040, 0x9360, 0xa085, 0x0001,
+       0x067f, 0x0d7f, 0x007c, 0x0d7e, 0x1078, 0x9397, 0x0d7f, 0x007c,
+       0x0d7e, 0x1078, 0x93a6, 0x00c0, 0x9390, 0x680c, 0xa08c, 0xff00,
+       0x6820, 0xa084, 0x00ff, 0xa115, 0x6212, 0x6824, 0x602a, 0xd1e4,
+       0x0040, 0x937e, 0x2009, 0x0001, 0x0078, 0x938c, 0xd1ec, 0x0040,
+       0x9390, 0x6920, 0xa18c, 0x00ff, 0x6824, 0x1078, 0x24e3, 0x00c0,
+       0x9390, 0x2110, 0x2009, 0x0000, 0x1078, 0x285b, 0x0078, 0x9394,
+       0xa085, 0x0001, 0x0078, 0x9395, 0xa006, 0x0d7f, 0x007c, 0x2069,
+       0xa88d, 0x6800, 0xa082, 0x0010, 0x00c8, 0x93a4, 0x6013, 0x0000,
+       0xa085, 0x0001, 0x0078, 0x93a5, 0xa006, 0x007c, 0x6013, 0x0000,
+       0x2069, 0xa88c, 0x6808, 0xa084, 0xff00, 0xa086, 0x0800, 0x00c0,
+       0x93ba, 0x6800, 0xa084, 0x00ff, 0xa08e, 0x0014, 0x0040, 0x93ba,
+       0xa08e, 0x0010, 0x007c, 0x6004, 0xa0b2, 0x0044, 0x10c8, 0x1328,
+       0xa1b6, 0x0013, 0x00c0, 0x93c7, 0x2008, 0x0079, 0x93da, 0xa1b6,
+       0x0027, 0x0040, 0x93cf, 0xa1b6, 0x0014, 0x10c0, 0x1328, 0x2001,
+       0x0007, 0x1078, 0x4472, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078,
+       0x6109, 0x007c, 0x941a, 0x941c, 0x941a, 0x941a, 0x941a, 0x941c,
+       0x9424, 0x94ae, 0x9471, 0x94ae, 0x9485, 0x94ae, 0x9424, 0x94ae,
+       0x94a6, 0x94ae, 0x94a6, 0x94ae, 0x94ae, 0x941a, 0x941a, 0x941a,
+       0x941a, 0x941a, 0x941a, 0x941a, 0x941a, 0x941a, 0x941a, 0x941a,
+       0x941c, 0x941a, 0x94ae, 0x941a, 0x941a, 0x94ae, 0x941a, 0x94ae,
+       0x94ae, 0x941a, 0x941a, 0x941a, 0x941a, 0x94ae, 0x94ae, 0x941a,
+       0x94ae, 0x94ae, 0x941a, 0x941a, 0x941a, 0x941a, 0x941a, 0x941c,
+       0x94ae, 0x94ae, 0x941a, 0x941a, 0x94ae, 0x94ae, 0x941a, 0x941a,
+       0x941a, 0x941a, 0x1078, 0x1328, 0x1078, 0x6010, 0x6003, 0x0002,
+       0x1078, 0x6109, 0x0078, 0x94b4, 0x0f7e, 0x2079, 0xa351, 0x7804,
+       0x0f7f, 0xd0ac, 0x00c0, 0x94ae, 0x2001, 0x0000, 0x1078, 0x442b,
+       0x6018, 0xa080, 0x0004, 0x2004, 0xa086, 0x00ff, 0x0040, 0x94ae,
+       0x0c7e, 0x6018, 0x2060, 0x6000, 0xd0f4, 0x00c0, 0x9448, 0x6010,
+       0xa005, 0x0040, 0x9448, 0x0c7f, 0x1078, 0x35f7, 0x0078, 0x94ae,
+       0x0c7f, 0x2001, 0xa300, 0x2004, 0xa086, 0x0002, 0x00c0, 0x9457,
+       0x0f7e, 0x2079, 0xa300, 0x788c, 0x8000, 0x788e, 0x0f7f, 0x2001,
+       0x0002, 0x1078, 0x443f, 0x1078, 0x6010, 0x601f, 0x0001, 0x6003,
+       0x0001, 0x6007, 0x0002, 0x1078, 0x5c45, 0x1078, 0x6109, 0x0c7e,
+       0x6118, 0x2160, 0x2009, 0x0001, 0x1078, 0x58e1, 0x0c7f, 0x0078,
+       0x94b4, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4, 0xff00,
+       0x8637, 0xa686, 0x0006, 0x0040, 0x94ae, 0xa686, 0x0004, 0x0040,
+       0x94ae, 0x2001, 0x0004, 0x0078, 0x94ac, 0x2001, 0xa300, 0x2004,
+       0xa086, 0x0003, 0x00c0, 0x948e, 0x1078, 0x35f7, 0x2001, 0x0006,
+       0x1078, 0x94b5, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4,
+       0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x94ae, 0x2001, 0x0006,
+       0x0078, 0x94ac, 0x2001, 0x0004, 0x0078, 0x94ac, 0x2001, 0x0006,
+       0x1078, 0x94b5, 0x0078, 0x94ae, 0x1078, 0x4472, 0x1078, 0x6010,
+       0x1078, 0x753d, 0x1078, 0x6109, 0x007c, 0x017e, 0x0d7e, 0x6118,
+       0x2168, 0x6900, 0xd184, 0x0040, 0x94d0, 0x6104, 0xa18e, 0x000a,
+       0x00c0, 0x94c8, 0x699c, 0xd1a4, 0x00c0, 0x94c8, 0x2001, 0x0007,
+       0x1078, 0x443f, 0x2001, 0x0000, 0x1078, 0x442b, 0x1078, 0x2839,
+       0x0d7f, 0x017f, 0x007c, 0x0d7e, 0x6618, 0x2668, 0x6804, 0xa084,
+       0xff00, 0x8007, 0x0d7f, 0xa0b2, 0x000c, 0x10c8, 0x1328, 0xa1b6,
+       0x0015, 0x00c0, 0x94e7, 0x1079, 0x94ee, 0x0078, 0x94ed, 0xa1b6,
+       0x0016, 0x10c0, 0x1328, 0x1079, 0x94fa, 0x007c, 0x7ad0, 0x7ad0,
+       0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x9547, 0x9506, 0x7ad0, 0x7ad0,
+       0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0,
+       0x9547, 0x954f, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x0f7e, 0x2079,
+       0xa351, 0x7804, 0xd0ac, 0x00c0, 0x952d, 0x6018, 0xa07d, 0x0040,
+       0x952d, 0x7800, 0xd0f4, 0x00c0, 0x9519, 0x7810, 0xa005, 0x00c0,
+       0x952d, 0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0002, 0x1078,
+       0x443f, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078,
+       0x5c45, 0x1078, 0x6109, 0x0078, 0x9545, 0x2011, 0xa883, 0x2204,
+       0x8211, 0x220c, 0x1078, 0x24e3, 0x00c0, 0x9545, 0x0c7e, 0x1078,
+       0x4501, 0x0040, 0x9540, 0x0c7f, 0x1078, 0x753d, 0x0078, 0x9545,
+       0x1078, 0x4235, 0x0c7f, 0x1078, 0x753d, 0x0f7f, 0x007c, 0x6604,
+       0xa6b6, 0x001e, 0x00c0, 0x954e, 0x1078, 0x753d, 0x007c, 0x1078,
+       0x7d0a, 0x00c0, 0x955b, 0x6003, 0x0001, 0x6007, 0x0001, 0x1078,
+       0x5c45, 0x0078, 0x955d, 0x1078, 0x753d, 0x007c, 0x6004, 0xa08a,
+       0x0044, 0x10c8, 0x1328, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078,
+       0x6109, 0x007c, 0xa182, 0x0040, 0x0079, 0x956e, 0x9581, 0x9581,
+       0x9581, 0x9581, 0x9583, 0x9581, 0x9581, 0x9581, 0x9581, 0x9581,
+       0x9581, 0x9581, 0x9581, 0x9581, 0x9581, 0x9581, 0x9581, 0x9581,
+       0x9581, 0x1078, 0x1328, 0x0d7e, 0x0e7e, 0x0f7e, 0x157e, 0x047e,
+       0x027e, 0x6218, 0xa280, 0x002b, 0x2004, 0xa005, 0x0040, 0x9594,
+       0x2021, 0x0000, 0x1078, 0xa111, 0x6106, 0x2071, 0xa880, 0x7444,
+       0xa4a4, 0xff00, 0x0040, 0x95eb, 0xa486, 0x2000, 0x00c0, 0x95a6,
+       0x2009, 0x0001, 0x2011, 0x0200, 0x1078, 0x5a6d, 0x1078, 0x1381,
+       0x1040, 0x1328, 0x6003, 0x0007, 0x2d00, 0x6837, 0x010d, 0x6803,
+       0x0000, 0x683b, 0x0000, 0x6c5a, 0x2c00, 0x685e, 0x6008, 0x68b2,
+       0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, 0x694a, 0x017e, 0xa084,
+       0xff00, 0x6846, 0x684f, 0x0000, 0x6857, 0x0036, 0x1078, 0x4982,
+       0x017f, 0xa486, 0x2000, 0x00c0, 0x95d3, 0x2019, 0x0017, 0x1078,
+       0x9e3b, 0x0078, 0x9645, 0xa486, 0x0400, 0x00c0, 0x95dd, 0x2019,
+       0x0002, 0x1078, 0x9dec, 0x0078, 0x9645, 0xa486, 0x0200, 0x00c0,
+       0x95e3, 0x1078, 0x9dd1, 0xa486, 0x1000, 0x00c0, 0x95e9, 0x1078,
+       0x9e20, 0x0078, 0x9645, 0x2069, 0xa62d, 0x6a00, 0xd284, 0x0040,
+       0x969b, 0xa284, 0x0300, 0x00c0, 0x9693, 0x6804, 0xa005, 0x0040,
+       0x9683, 0x2d78, 0x6003, 0x0007, 0x1078, 0x1366, 0x0040, 0x964c,
+       0x7800, 0xd08c, 0x00c0, 0x9607, 0x7804, 0x8001, 0x7806, 0x6013,
+       0x0000, 0x6803, 0x0000, 0x6837, 0x0116, 0x683b, 0x0000, 0x6008,
+       0x68b2, 0x2c00, 0x684a, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130,
+       0x6986, 0x6846, 0x6853, 0x003d, 0x7244, 0xa294, 0x0003, 0xa286,
+       0x0002, 0x00c0, 0x9627, 0x684f, 0x0040, 0x0078, 0x9631, 0xa286,
+       0x0001, 0x00c0, 0x962f, 0x684f, 0x0080, 0x0078, 0x9631, 0x684f,
+       0x0000, 0x20a9, 0x000a, 0x2001, 0xa890, 0xad90, 0x0015, 0x200c,
+       0x810f, 0x2112, 0x8000, 0x8210, 0x00f0, 0x9637, 0x200c, 0x6982,
+       0x8000, 0x200c, 0x697e, 0x1078, 0x4982, 0x027f, 0x047f, 0x157f,
+       0x0f7f, 0x0e7f, 0x0d7f, 0x007c, 0x6013, 0x0100, 0x6003, 0x0001,
+       0x6007, 0x0041, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0078, 0x9645,
+       0x2069, 0xa892, 0x2d04, 0xa084, 0xff00, 0xa086, 0x1200, 0x00c0,
+       0x9677, 0x2069, 0xa880, 0x686c, 0xa084, 0x00ff, 0x017e, 0x6110,
+       0xa18c, 0x0700, 0xa10d, 0x6112, 0x017f, 0x6003, 0x0001, 0x6007,
+       0x0043, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0078, 0x9645, 0x6013,
+       0x0200, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x5bf8, 0x1078,
+       0x6109, 0x0078, 0x9645, 0x6013, 0x0300, 0x0078, 0x9689, 0x6013,
+       0x0100, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x5bf8, 0x1078,
+       0x6109, 0x0078, 0x9645, 0x6013, 0x0500, 0x0078, 0x9689, 0x6013,
+       0x0600, 0x0078, 0x9658, 0x6013, 0x0200, 0x0078, 0x9658, 0xa186,
+       0x0013, 0x00c0, 0x96b1, 0x6004, 0xa08a, 0x0040, 0x1048, 0x1328,
+       0xa08a, 0x0053, 0x10c8, 0x1328, 0xa082, 0x0040, 0x2008, 0x0079,
+       0x9725, 0xa186, 0x0051, 0x0040, 0x96be, 0xa186, 0x0047, 0x00c0,
+       0x96d7, 0x6004, 0xa086, 0x0041, 0x0040, 0x96e5, 0x2001, 0x0109,
+       0x2004, 0xd084, 0x0040, 0x96e5, 0x127e, 0x2091, 0x2200, 0x007e,
+       0x017e, 0x027e, 0x1078, 0x5ad2, 0x027f, 0x017f, 0x007f, 0x127f,
+       0x6000, 0xa086, 0x0002, 0x00c0, 0x96e5, 0x0078, 0x976a, 0xa186,
+       0x0027, 0x0040, 0x96df, 0xa186, 0x0014, 0x10c0, 0x1328, 0x6004,
+       0xa082, 0x0040, 0x2008, 0x0079, 0x96e8, 0x1078, 0x7583, 0x007c,
+       0x96fb, 0x96fd, 0x96fd, 0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb,
+       0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb,
+       0x96fb, 0x96fb, 0x96fb, 0x1078, 0x1328, 0x1078, 0x6010, 0x1078,
+       0x6109, 0x037e, 0x0d7e, 0x6010, 0xa06d, 0x0040, 0x9722, 0xad84,
+       0xf000, 0x0040, 0x9722, 0x6003, 0x0002, 0x6018, 0x2004, 0xd0bc,
+       0x00c0, 0x9722, 0x2019, 0x0004, 0x1078, 0x9e70, 0x6013, 0x0000,
+       0x6014, 0xa005, 0x00c0, 0x9720, 0x2001, 0xa5a1, 0x2004, 0x6016,
+       0x6003, 0x0007, 0x0d7f, 0x037f, 0x007c, 0x9738, 0x9757, 0x9741,
+       0x9764, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738,
+       0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738,
+       0x1078, 0x1328, 0x6010, 0xa088, 0x0013, 0x2104, 0xa085, 0x0400,
+       0x200a, 0x1078, 0x6010, 0x6010, 0xa080, 0x0013, 0x2004, 0xd0b4,
+       0x0040, 0x9752, 0x6003, 0x0007, 0x2009, 0x0043, 0x1078, 0x756c,
+       0x0078, 0x9754, 0x6003, 0x0002, 0x1078, 0x6109, 0x007c, 0x1078,
+       0x6010, 0x1078, 0xa0c6, 0x00c0, 0x9761, 0x1078, 0x5a41, 0x1078,
+       0x753d, 0x1078, 0x6109, 0x007c, 0x1078, 0x6010, 0x2009, 0x0041,
+       0x0078, 0x98c1, 0xa182, 0x0040, 0x0079, 0x976e, 0x9781, 0x9783,
+       0x9781, 0x9781, 0x9781, 0x9781, 0x9781, 0x9784, 0x9781, 0x9781,
+       0x9781, 0x9781, 0x9781, 0x9781, 0x9781, 0x9781, 0x9781, 0x978f,
+       0x9781, 0x1078, 0x1328, 0x007c, 0x6003, 0x0004, 0x6110, 0x20e1,
+       0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x15ec, 0x007c, 0x0d7e,
+       0x1078, 0x5a41, 0x0d7f, 0x1078, 0xa134, 0x1078, 0x753d, 0x007c,
+       0xa182, 0x0040, 0x0079, 0x979c, 0x97af, 0x97af, 0x97af, 0x97af,
+       0x97af, 0x97af, 0x97af, 0x97b1, 0x97af, 0x97b4, 0x97df, 0x97af,
+       0x97af, 0x97af, 0x97af, 0x97df, 0x97af, 0x97af, 0x97af, 0x1078,
+       0x1328, 0x1078, 0x7583, 0x007c, 0x1078, 0x60b8, 0x1078, 0x61d3,
+       0x6010, 0x0d7e, 0x2068, 0x684c, 0xd0fc, 0x0040, 0x97ca, 0xa08c,
+       0x0003, 0xa18e, 0x0002, 0x0040, 0x97d2, 0x2009, 0x0041, 0x0d7f,
+       0x0078, 0x98c1, 0x6003, 0x0007, 0x6017, 0x0000, 0x1078, 0x5a41,
+       0x0d7f, 0x007c, 0x1078, 0xa0c6, 0x0040, 0x97d8, 0x0d7f, 0x007c,
+       0x1078, 0x5a41, 0x1078, 0x753d, 0x0d7f, 0x0078, 0x97d1, 0x037e,
+       0x1078, 0x60b8, 0x1078, 0x61d3, 0x6010, 0x0d7e, 0x2068, 0x6018,
+       0x2004, 0xd0bc, 0x0040, 0x97ff, 0x684c, 0xa084, 0x0003, 0xa086,
+       0x0002, 0x0040, 0x97fb, 0x687c, 0x632c, 0xa31a, 0x632e, 0x6880,
+       0x6328, 0xa31b, 0x632a, 0x6003, 0x0002, 0x0078, 0x9810, 0x2019,
+       0x0004, 0x1078, 0x9e70, 0x6014, 0xa005, 0x00c0, 0x980c, 0x2001,
+       0xa5a1, 0x2004, 0x8003, 0x6016, 0x6013, 0x0000, 0x6003, 0x0007,
+       0x0d7f, 0x037f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x9821, 0x6004,
+       0xa086, 0x0042, 0x10c0, 0x1328, 0x1078, 0x6010, 0x1078, 0x6109,
+       0x007c, 0xa186, 0x0027, 0x0040, 0x9829, 0xa186, 0x0014, 0x00c0,
+       0x9839, 0x6004, 0xa086, 0x0042, 0x10c0, 0x1328, 0x2001, 0x0007,
+       0x1078, 0x4472, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078, 0x6109,
+       0x007c, 0xa182, 0x0040, 0x0079, 0x983d, 0x9850, 0x9850, 0x9850,
+       0x9850, 0x9850, 0x9850, 0x9850, 0x9852, 0x985e, 0x9850, 0x9850,
+       0x9850, 0x9850, 0x9850, 0x9850, 0x9850, 0x9850, 0x9850, 0x9850,
+       0x1078, 0x1328, 0x037e, 0x047e, 0x20e1, 0x0005, 0x3d18, 0x3e20,
+       0x2c10, 0x1078, 0x15ec, 0x047f, 0x037f, 0x007c, 0x6010, 0x0d7e,
+       0x2068, 0x6810, 0x6a14, 0x6118, 0x210c, 0xd1bc, 0x0040, 0x987d,
+       0x6124, 0xd1f4, 0x00c0, 0x987d, 0x007e, 0x047e, 0x057e, 0x6c7c,
+       0xa422, 0x6d80, 0x2200, 0xa52b, 0x602c, 0xa420, 0x642e, 0x6028,
+       0xa529, 0x652a, 0x057f, 0x047f, 0x007f, 0xa20d, 0x00c0, 0x9891,
+       0x684c, 0xd0fc, 0x0040, 0x9889, 0x2009, 0x0041, 0x0d7f, 0x0078,
+       0x98c1, 0x6003, 0x0007, 0x6017, 0x0000, 0x1078, 0x5a41, 0x0d7f,
+       0x007c, 0x007e, 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x007f,
+       0x0040, 0x989e, 0x6003, 0x0002, 0x0d7f, 0x007c, 0x2009, 0xa30d,
+       0x210c, 0xd19c, 0x0040, 0x98a8, 0x6003, 0x0007, 0x0078, 0x98aa,
+       0x6003, 0x0006, 0x1078, 0x98b0, 0x1078, 0x5a43, 0x0d7f, 0x007c,
+       0xd2fc, 0x0040, 0x98bc, 0x8002, 0x8000, 0x8212, 0xa291, 0x0000,
+       0x2009, 0x0009, 0x0078, 0x98be, 0x2009, 0x0015, 0x6a6a, 0x6866,
+       0x007c, 0xa182, 0x0040, 0x0048, 0x98c7, 0x0079, 0x98d4, 0xa186,
+       0x0013, 0x0040, 0x98cf, 0xa186, 0x0014, 0x10c0, 0x1328, 0x6024,
+       0xd0dc, 0x1040, 0x1328, 0x007c, 0x98e7, 0x98ee, 0x98fa, 0x9906,
+       0x98e7, 0x98e7, 0x98e7, 0x9915, 0x98e7, 0x98e9, 0x98e9, 0x98e7,
+       0x98e7, 0x98e7, 0x98e7, 0x98e7, 0x98e7, 0x98e7, 0x98e7, 0x1078,
+       0x1328, 0x6024, 0xd0dc, 0x1040, 0x1328, 0x007c, 0x6003, 0x0001,
+       0x6106, 0x1078, 0x5bf8, 0x127e, 0x2091, 0x8000, 0x1078, 0x6109,
+       0x127f, 0x007c, 0x6003, 0x0001, 0x6106, 0x1078, 0x5bf8, 0x127e,
+       0x2091, 0x8000, 0x1078, 0x6109, 0x127f, 0x007c, 0x6003, 0x0003,
+       0x6106, 0x2c10, 0x1078, 0x1cab, 0x127e, 0x2091, 0x8000, 0x1078,
+       0x5c64, 0x1078, 0x61d3, 0x127f, 0x007c, 0xa016, 0x1078, 0x15ec,
+       0x007c, 0x127e, 0x2091, 0x8000, 0x037e, 0x0d7e, 0xa182, 0x0040,
+       0x1079, 0x9926, 0x0d7f, 0x037f, 0x127f, 0x007c, 0x9936, 0x9938,
+       0x994d, 0x996c, 0x9936, 0x9936, 0x9936, 0x9984, 0x9936, 0x9936,
+       0x9936, 0x9936, 0x9936, 0x9936, 0x9936, 0x9936, 0x1078, 0x1328,
+       0x6010, 0x2068, 0x684c, 0xd0fc, 0x0040, 0x9962, 0xa09c, 0x0003,
+       0xa39e, 0x0003, 0x0040, 0x9962, 0x6003, 0x0001, 0x6106, 0x1078,
+       0x5bf8, 0x1078, 0x6109, 0x0078, 0x9987, 0x6010, 0x2068, 0x684c,
+       0xd0fc, 0x0040, 0x9962, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0040,
+       0x9962, 0x6003, 0x0001, 0x6106, 0x1078, 0x5bf8, 0x1078, 0x6109,
+       0x0078, 0x9987, 0x6013, 0x0000, 0x6017, 0x0000, 0x2019, 0x0004,
+       0x1078, 0x9e70, 0x0078, 0x9987, 0x6010, 0x2068, 0x684c, 0xd0fc,
+       0x0040, 0x9962, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0040, 0x9962,
+       0x6003, 0x0003, 0x6106, 0x2c10, 0x1078, 0x1cab, 0x1078, 0x5c64,
+       0x1078, 0x61d3, 0x0078, 0x9987, 0xa016, 0x1078, 0x15ec, 0x007c,
+       0x1078, 0x6010, 0x6110, 0x81ff, 0x0040, 0x9999, 0x0d7e, 0x2168,
+       0x1078, 0xa181, 0x037e, 0x2019, 0x0029, 0x1078, 0x9e70, 0x037f,
+       0x0d7f, 0x1078, 0x8c01, 0x1078, 0x6109, 0x007c, 0x1078, 0x60b8,
+       0x6110, 0x81ff, 0x0040, 0x99af, 0x0d7e, 0x2168, 0x1078, 0xa181,
+       0x037e, 0x2019, 0x0029, 0x1078, 0x9e70, 0x037f, 0x0d7f, 0x1078,
+       0x8c01, 0x1078, 0x61d3, 0x007c, 0xa182, 0x0085, 0x0079, 0x99b8,
+       0x99c1, 0x99bf, 0x99bf, 0x99cd, 0x99bf, 0x99bf, 0x99bf, 0x1078,
+       0x1328, 0x6003, 0x000b, 0x6106, 0x1078, 0x5bf8, 0x127e, 0x2091,
+       0x8000, 0x1078, 0x6109, 0x127f, 0x007c, 0x027e, 0x0e7e, 0x1078,
+       0xa0bf, 0x0040, 0x99d7, 0x1078, 0x753d, 0x0078, 0x99f3, 0x2071,
+       0xa880, 0x7224, 0x6212, 0x7220, 0x1078, 0x9d10, 0x0040, 0x99e4,
+       0x6007, 0x0086, 0x0078, 0x99ed, 0x6007, 0x0087, 0x7224, 0xa296,
+       0xffff, 0x00c0, 0x99ed, 0x6007, 0x0086, 0x6003, 0x0001, 0x1078,
+       0x5bf8, 0x1078, 0x6109, 0x0e7f, 0x027f, 0x007c, 0xa186, 0x0013,
+       0x00c0, 0x9a07, 0x6004, 0xa08a, 0x0085, 0x1048, 0x1328, 0xa08a,
+       0x008c, 0x10c8, 0x1328, 0xa082, 0x0085, 0x0079, 0x9a1e, 0xa186,
+       0x0027, 0x0040, 0x9a13, 0xa186, 0x0014, 0x0040, 0x9a13, 0x1078,
+       0x7583, 0x0078, 0x9a1d, 0x2001, 0x0007, 0x1078, 0x4472, 0x1078,
+       0x6010, 0x1078, 0x8c01, 0x1078, 0x6109, 0x007c, 0x9a25, 0x9a27,
+       0x9a27, 0x9a25, 0x9a25, 0x9a25, 0x9a25, 0x1078, 0x1328, 0x1078,
+       0x6010, 0x1078, 0x8c01, 0x1078, 0x6109, 0x007c, 0xa182, 0x0085,
+       0x1048, 0x1328, 0xa182, 0x008c, 0x10c8, 0x1328, 0xa182, 0x0085,
+       0x0079, 0x9a3a, 0x9a41, 0x9a41, 0x9a41, 0x9a43, 0x9a41, 0x9a41,
+       0x9a41, 0x1078, 0x1328, 0x007c, 0xa186, 0x0013, 0x0040, 0x9a54,
+       0xa186, 0x0014, 0x0040, 0x9a54, 0xa186, 0x0027, 0x0040, 0x9a54,
+       0x1078, 0x7583, 0x0078, 0x9a5a, 0x1078, 0x6010, 0x1078, 0x8c01,
+       0x1078, 0x6109, 0x007c, 0x037e, 0x1078, 0xa134, 0x603f, 0x0000,
+       0x2019, 0x000b, 0x1078, 0x9a6a, 0x601f, 0x0006, 0x6003, 0x0007,
+       0x037f, 0x007c, 0x127e, 0x037e, 0x2091, 0x8000, 0x087e, 0x2c40,
+       0x097e, 0x2049, 0x0000, 0x1078, 0x7058, 0x097f, 0x087f, 0x00c0,
+       0x9aa5, 0x077e, 0x2c38, 0x1078, 0x7105, 0x077f, 0x00c0, 0x9aa5,
+       0x6000, 0xa086, 0x0000, 0x0040, 0x9aa5, 0x601c, 0xa086, 0x0007,
+       0x0040, 0x9aa5, 0x0d7e, 0x6000, 0xa086, 0x0004, 0x00c0, 0x9a96,
+       0x1078, 0xa134, 0x601f, 0x0007, 0x1078, 0x1749, 0x6010, 0x2068,
+       0x1078, 0x8a44, 0x0040, 0x9a9e, 0x1078, 0x9e70, 0x0d7f, 0x6013,
+       0x0000, 0x1078, 0xa134, 0x601f, 0x0007, 0x037f, 0x127f, 0x007c,
+       0x0f7e, 0x0c7e, 0x037e, 0x157e, 0x2079, 0xa880, 0x7938, 0x783c,
+       0x1078, 0x24e3, 0x00c0, 0x9af6, 0x017e, 0x0c7e, 0x1078, 0x4501,
+       0x00c0, 0x9af6, 0x2011, 0xa890, 0xac98, 0x000a, 0x20a9, 0x0004,
+       0x1078, 0x7e55, 0x00c0, 0x9af6, 0x017f, 0x027f, 0x027e, 0x017e,
+       0x2019, 0x0029, 0x1078, 0x71e0, 0x1078, 0x5d53, 0x077e, 0x2039,
+       0x0000, 0x1078, 0x5c78, 0x077f, 0x017f, 0x077e, 0x2039, 0x0000,
+       0x1078, 0x9c38, 0x077f, 0x1078, 0x471b, 0x027e, 0x6204, 0xa294,
+       0xff00, 0x8217, 0xa286, 0x0006, 0x0040, 0x9aea, 0xa286, 0x0004,
+       0x00c0, 0x9aed, 0x62a0, 0x1078, 0x28d5, 0x027f, 0x017f, 0x1078,
+       0x4235, 0x6612, 0x6516, 0xa006, 0x0078, 0x9af8, 0x0c7f, 0x017f,
+       0x157f, 0x037f, 0x0c7f, 0x0f7f, 0x007c, 0x0c7e, 0x0d7e, 0x0e7e,
+       0x017e, 0x2009, 0xa31f, 0x2104, 0xa086, 0x0074, 0x00c0, 0x9b60,
+       0x2069, 0xa88e, 0x690c, 0xa182, 0x0100, 0x0048, 0x9b50, 0x6908,
+       0xa184, 0x8000, 0x0040, 0x9b5c, 0x6018, 0x2070, 0x7010, 0xa084,
+       0x00ff, 0x0040, 0x9b1f, 0x7000, 0xd0f4, 0x0040, 0x9b23, 0xa184,
+       0x0800, 0x0040, 0x9b5c, 0x6910, 0xa18a, 0x0001, 0x0048, 0x9b54,
+       0x6914, 0x2069, 0xa8ae, 0x6904, 0x81ff, 0x00c0, 0x9b48, 0x690c,
+       0xa182, 0x0100, 0x0048, 0x9b50, 0x6908, 0x81ff, 0x00c0, 0x9b4c,
+       0x6910, 0xa18a, 0x0001, 0x0048, 0x9b54, 0x6918, 0xa18a, 0x0001,
+       0x0048, 0x9b5c, 0x0078, 0x9b66, 0x6013, 0x0100, 0x0078, 0x9b62,
+       0x6013, 0x0300, 0x0078, 0x9b62, 0x6013, 0x0500, 0x0078, 0x9b62,
+       0x6013, 0x0700, 0x0078, 0x9b62, 0x6013, 0x0900, 0x0078, 0x9b62,
+       0x6013, 0x0b00, 0x0078, 0x9b62, 0x6013, 0x0f00, 0x0078, 0x9b62,
+       0x6013, 0x2d00, 0xa085, 0x0001, 0x0078, 0x9b67, 0xa006, 0x017f,
+       0x0e7f, 0x0d7f, 0x0c7f, 0x007c, 0x0c7e, 0x0d7e, 0x027e, 0x037e,
+       0x157e, 0x6218, 0x2268, 0x6b04, 0xa394, 0x00ff, 0xa286, 0x0006,
+       0x0040, 0x9b90, 0xa286, 0x0004, 0x0040, 0x9b90, 0xa394, 0xff00,
+       0x8217, 0xa286, 0x0006, 0x0040, 0x9b90, 0xa286, 0x0004, 0x0040,
+       0x9b90, 0x0c7e, 0x2d60, 0x1078, 0x4513, 0x0c7f, 0x0078, 0x9bcb,
+       0x2011, 0xa896, 0xad98, 0x000a, 0x20a9, 0x0004, 0x1078, 0x7e55,
+       0x00c0, 0x9bcc, 0x2011, 0xa89a, 0xad98, 0x0006, 0x20a9, 0x0004,
+       0x1078, 0x7e55, 0x00c0, 0x9bcc, 0x047e, 0x017e, 0x6aa0, 0xa294,
+       0x00ff, 0x8227, 0xa006, 0x2009, 0xa352, 0x210c, 0xd1a4, 0x0040,
+       0x9bb8, 0x2009, 0x0029, 0x1078, 0x9ec0, 0x6800, 0xc0e5, 0x6802,
+       0x2019, 0x0029, 0x1078, 0x5d53, 0x077e, 0x2039, 0x0000, 0x1078,
+       0x5c78, 0x2c08, 0x1078, 0x9c38, 0x077f, 0x2001, 0x0007, 0x1078,
+       0x4472, 0x017f, 0x047f, 0xa006, 0x157f, 0x037f, 0x027f, 0x0d7f,
+       0x0c7f, 0x007c, 0x0d7e, 0x2069, 0xa88e, 0x6800, 0xa086, 0x0800,
+       0x0040, 0x9bde, 0x6013, 0x0000, 0x0078, 0x9bdf, 0xa006, 0x0d7f,
+       0x007c, 0x0c7e, 0x0f7e, 0x017e, 0x027e, 0x037e, 0x157e, 0x2079,
+       0xa88c, 0x7930, 0x7834, 0x1078, 0x24e3, 0x00c0, 0x9c05, 0x1078,
+       0x4501, 0x00c0, 0x9c05, 0x2011, 0xa890, 0xac98, 0x000a, 0x20a9,
+       0x0004, 0x1078, 0x7e55, 0x00c0, 0x9c05, 0x2011, 0xa894, 0xac98,
+       0x0006, 0x20a9, 0x0004, 0x1078, 0x7e55, 0x157f, 0x037f, 0x027f,
+       0x017f, 0x0f7f, 0x0c7f, 0x007c, 0x0c7e, 0x007e, 0x017e, 0x027e,
+       0x037e, 0x157e, 0x2011, 0xa883, 0x2204, 0x8211, 0x220c, 0x1078,
+       0x24e3, 0x00c0, 0x9c31, 0x1078, 0x4501, 0x00c0, 0x9c31, 0x2011,
+       0xa896, 0xac98, 0x000a, 0x20a9, 0x0004, 0x1078, 0x7e55, 0x00c0,
+       0x9c31, 0x2011, 0xa89a, 0xac98, 0x0006, 0x20a9, 0x0004, 0x1078,
+       0x7e55, 0x157f, 0x037f, 0x027f, 0x017f, 0x007f, 0x0c7f, 0x007c,
+       0x0e7e, 0x0c7e, 0x087e, 0x077e, 0x067e, 0x057e, 0x047e, 0x027e,
+       0x127e, 0x2091, 0x8000, 0x2740, 0x2029, 0xa5b4, 0x252c, 0x2021,
+       0xa5ba, 0x2424, 0x2061, 0xaa00, 0x2071, 0xa300, 0x7644, 0x7060,
+       0x81ff, 0x0040, 0x9c59, 0x8001, 0xa602, 0x00c8, 0x9cc3, 0x0078,
+       0x9c5c, 0xa606, 0x0040, 0x9cc3, 0x2100, 0xac06, 0x0040, 0x9cb9,
+       0x1078, 0x9ee5, 0x0040, 0x9cb9, 0x671c, 0xa786, 0x0001, 0x0040,
+       0x9cde, 0xa786, 0x0004, 0x0040, 0x9cde, 0xa786, 0x0007, 0x0040,
+       0x9cb9, 0x2500, 0xac06, 0x0040, 0x9cb9, 0x2400, 0xac06, 0x0040,
+       0x9cb9, 0x1078, 0x9ef9, 0x00c0, 0x9cb9, 0x88ff, 0x0040, 0x9c84,
+       0x6020, 0xa906, 0x00c0, 0x9cb9, 0x0d7e, 0x6000, 0xa086, 0x0004,
+       0x00c0, 0x9c8e, 0x017e, 0x1078, 0x1749, 0x017f, 0xa786, 0x0008,
+       0x00c0, 0x9c9d, 0x1078, 0x8c3b, 0x00c0, 0x9c9d, 0x1078, 0x7a05,
+       0x0d7f, 0x1078, 0x8c01, 0x0078, 0x9cb9, 0x6010, 0x2068, 0x1078,
+       0x8a44, 0x0040, 0x9cb6, 0xa786, 0x0003, 0x00c0, 0x9ccd, 0x6837,
+       0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0xa181, 0x017e, 0x1078,
+       0x8cb8, 0x1078, 0x4982, 0x017f, 0x1078, 0x8bf4, 0x0d7f, 0x1078,
+       0x8c01, 0xace0, 0x0010, 0x2001, 0xa315, 0x2004, 0xac02, 0x00c8,
+       0x9cc3, 0x0078, 0x9c4c, 0x127f, 0x027f, 0x047f, 0x057f, 0x067f,
+       0x077f, 0x087f, 0x0c7f, 0x0e7f, 0x007c, 0xa786, 0x0006, 0x00c0,
+       0x9ca7, 0xa386, 0x0005, 0x0040, 0x9cdb, 0x1078, 0xa181, 0x1078,
+       0x9e70, 0x0078, 0x9cb6, 0x0d7f, 0x0078, 0x9cb9, 0x1078, 0x9ef9,
+       0x00c0, 0x9cb9, 0x81ff, 0x0040, 0x9cb9, 0xa180, 0x0001, 0x2004,
+       0xa086, 0x0018, 0x0040, 0x9cf3, 0xa180, 0x0001, 0x2004, 0xa086,
+       0x002d, 0x00c0, 0x9cb9, 0x6000, 0xa086, 0x0002, 0x00c0, 0x9cb9,
+       0x1078, 0x8c27, 0x0040, 0x9d04, 0x1078, 0x8c3b, 0x00c0, 0x9cb9,
+       0x1078, 0x7a05, 0x0078, 0x9d0c, 0x1078, 0x2839, 0x1078, 0x8c3b,
+       0x00c0, 0x9d0c, 0x1078, 0x7a05, 0x1078, 0x8c01, 0x0078, 0x9cb9,
+       0x0c7e, 0x0e7e, 0x017e, 0x2c08, 0x2170, 0x1078, 0x9e8c, 0x017f,
+       0x0040, 0x9d1f, 0x601c, 0xa084, 0x000f, 0x1079, 0x9d22, 0x0e7f,
+       0x0c7f, 0x007c, 0x9d2a, 0x9d2a, 0x9d2a, 0x9d2a, 0x9d2a, 0x9d2a,
+       0x9d2c, 0x9d2a, 0xa006, 0x007c, 0x047e, 0x017e, 0x7018, 0xa080,
+       0x0028, 0x2024, 0xa4a4, 0x00ff, 0x8427, 0x2c00, 0x2009, 0x0020,
+       0x1078, 0x9ec0, 0x017f, 0x047f, 0x037e, 0x2019, 0x0002, 0x1078,
+       0x9a6a, 0x037f, 0xa085, 0x0001, 0x007c, 0x2001, 0x0001, 0x1078,
+       0x442b, 0x157e, 0x017e, 0x027e, 0x037e, 0x20a9, 0x0004, 0x2019,
+       0xa305, 0x2011, 0xa896, 0x1078, 0x7e55, 0x037f, 0x027f, 0x017f,
+       0x157f, 0xa005, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x087e, 0x077e,
+       0x067e, 0x027e, 0x127e, 0x2091, 0x8000, 0x2740, 0x2061, 0xaa00,
+       0x2079, 0x0001, 0x8fff, 0x0040, 0x9dc3, 0x2071, 0xa300, 0x7644,
+       0x7060, 0x8001, 0xa602, 0x00c8, 0x9dc3, 0x88ff, 0x0040, 0x9d7e,
+       0x2800, 0xac06, 0x00c0, 0x9db9, 0x2079, 0x0000, 0x1078, 0x9ee5,
+       0x0040, 0x9db9, 0x2400, 0xac06, 0x0040, 0x9db9, 0x671c, 0xa786,
+       0x0006, 0x00c0, 0x9db9, 0xa786, 0x0007, 0x0040, 0x9db9, 0x88ff,
+       0x00c0, 0x9d9d, 0x6018, 0xa206, 0x00c0, 0x9db9, 0x85ff, 0x0040,
+       0x9d9d, 0x6020, 0xa106, 0x00c0, 0x9db9, 0x0d7e, 0x6000, 0xa086,
+       0x0004, 0x00c0, 0x9da9, 0x1078, 0xa134, 0x601f, 0x0007, 0x1078,
+       0x1749, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x9db3, 0x047e,
+       0x1078, 0x9e70, 0x047f, 0x0d7f, 0x1078, 0x8c01, 0x88ff, 0x00c0,
+       0x9dcd, 0xace0, 0x0010, 0x2001, 0xa315, 0x2004, 0xac02, 0x00c8,
+       0x9dc3, 0x0078, 0x9d6a, 0xa006, 0x127f, 0x027f, 0x067f, 0x077f,
+       0x087f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0xa8c5, 0x0001, 0x0078,
+       0x9dc4, 0x077e, 0x057e, 0x087e, 0x2041, 0x0000, 0x2029, 0x0001,
+       0x2c20, 0x2019, 0x0002, 0x6218, 0x097e, 0x2049, 0x0000, 0x1078,
+       0x7058, 0x097f, 0x087f, 0x2039, 0x0000, 0x1078, 0x7105, 0x1078,
+       0x9d5b, 0x057f, 0x077f, 0x007c, 0x027e, 0x047e, 0x057e, 0x077e,
+       0x0c7e, 0x157e, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x2009, 0x0000,
+       0x017e, 0x037e, 0x1078, 0x4501, 0x00c0, 0x9e14, 0x2c10, 0x057e,
+       0x087e, 0x2041, 0x0000, 0x2508, 0x2029, 0x0001, 0x097e, 0x2049,
+       0x0000, 0x1078, 0x7058, 0x097f, 0x087f, 0x2039, 0x0000, 0x1078,
+       0x7105, 0x1078, 0x9d5b, 0x057f, 0x037f, 0x017f, 0x8108, 0x00f0,
+       0x9df8, 0x157f, 0x0c7f, 0x077f, 0x057f, 0x047f, 0x027f, 0x007c,
+       0x077e, 0x057e, 0x6218, 0x087e, 0x2041, 0x0000, 0x2029, 0x0001,
+       0x2019, 0x0048, 0x097e, 0x2049, 0x0000, 0x1078, 0x7058, 0x097f,
+       0x087f, 0x2039, 0x0000, 0x1078, 0x7105, 0x2c20, 0x1078, 0x9d5b,
+       0x057f, 0x077f, 0x007c, 0x027e, 0x047e, 0x057e, 0x077e, 0x0c7e,
+       0x157e, 0x2c20, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x037e,
+       0x1078, 0x4501, 0x00c0, 0x9e64, 0x2c10, 0x087e, 0x2041, 0x0000,
+       0x2828, 0x047e, 0x2021, 0x0001, 0x1078, 0xa111, 0x047f, 0x097e,
+       0x2049, 0x0000, 0x1078, 0x7058, 0x097f, 0x087f, 0x2039, 0x0000,
+       0x1078, 0x7105, 0x1078, 0x9d5b, 0x037f, 0x017f, 0x8108, 0x00f0,
+       0x9e46, 0x157f, 0x0c7f, 0x077f, 0x057f, 0x047f, 0x027f, 0x007c,
+       0x017e, 0x0f7e, 0xad82, 0xca00, 0x0048, 0x9e89, 0xad82, 0xffff,
+       0x00c8, 0x9e89, 0x6800, 0xa07d, 0x0040, 0x9e86, 0x6803, 0x0000,
+       0x6b52, 0x1078, 0x4982, 0x2f68, 0x0078, 0x9e7a, 0x6b52, 0x1078,
+       0x4982, 0x0f7f, 0x017f, 0x007c, 0x0e7e, 0x047e, 0x037e, 0x2061,
+       0xaa00, 0x2071, 0xa300, 0x7444, 0x7060, 0x8001, 0xa402, 0x00c8,
+       0x9ebb, 0x2100, 0xac06, 0x0040, 0x9ead, 0x6000, 0xa086, 0x0000,
+       0x0040, 0x9ead, 0x6008, 0xa206, 0x00c0, 0x9ead, 0x6018, 0xa1a0,
+       0x0006, 0x2424, 0xa406, 0x0040, 0x9eb7, 0xace0, 0x0010, 0x2001,
+       0xa315, 0x2004, 0xac02, 0x00c8, 0x9ebb, 0x0078, 0x9e91, 0xa085,
+       0x0001, 0x0078, 0x9ebc, 0xa006, 0x037f, 0x047f, 0x0e7f, 0x007c,
+       0x0d7e, 0x007e, 0x1078, 0x1381, 0x007f, 0x1040, 0x1328, 0x6837,
+       0x010d, 0x685e, 0x027e, 0x2010, 0x1078, 0x8a30, 0x2001, 0x0000,
+       0x0040, 0x9ed6, 0x2200, 0xa080, 0x0008, 0x2004, 0x027f, 0x684a,
+       0x6956, 0x6c46, 0x684f, 0x0000, 0xa006, 0x68b2, 0x6802, 0x683a,
+       0x685a, 0x1078, 0x4982, 0x0d7f, 0x007c, 0x6700, 0xa786, 0x0000,
+       0x0040, 0x9ef8, 0xa786, 0x0001, 0x0040, 0x9ef8, 0xa786, 0x000a,
+       0x0040, 0x9ef8, 0xa786, 0x0009, 0x0040, 0x9ef8, 0xa085, 0x0001,
+       0x007c, 0x0e7e, 0x6018, 0x2070, 0x70a0, 0xa206, 0x0e7f, 0x007c,
+       0x017e, 0x6004, 0xa08e, 0x001e, 0x00c0, 0x9f1a, 0x8007, 0x6130,
+       0xa18c, 0x00ff, 0xa105, 0x6032, 0x6007, 0x0085, 0x6003, 0x000b,
+       0x601f, 0x0005, 0x2001, 0xa5a1, 0x2004, 0x6016, 0x1078, 0x5bf8,
+       0x1078, 0x6109, 0x017f, 0x007c, 0x0005, 0x0005, 0x007c, 0x6024,
+       0xd0e4, 0x0040, 0x9f30, 0xd0cc, 0x0040, 0x9f2a, 0x1078, 0x8cfa,
+       0x0078, 0x9f30, 0x1078, 0xa134, 0x1078, 0x5a41, 0x1078, 0x753d,
+       0x007c, 0xa280, 0x0007, 0x2004, 0xa084, 0x000f, 0x0079, 0x9f38,
+       0x9f41, 0x9f41, 0x9f41, 0x9f43, 0x9f41, 0x9f43, 0x9f43, 0x9f41,
+       0x9f43, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c, 0xa280, 0x0007,
+       0x2004, 0xa084, 0x000f, 0x0079, 0x9f4d, 0x9f56, 0x9f56, 0x9f56,
+       0x9f56, 0x9f56, 0x9f56, 0x9f61, 0x9f56, 0x9f56, 0x6007, 0x003b,
+       0x602b, 0x0009, 0x6013, 0x2a00, 0x6003, 0x0001, 0x1078, 0x5bf8,
+       0x007c, 0x0c7e, 0x2260, 0x1078, 0xa134, 0x603f, 0x0000, 0x6024,
+       0xc0f4, 0xc0cc, 0x6026, 0x0c7f, 0x0d7e, 0x2268, 0xa186, 0x0007,
+       0x00c0, 0x9fc2, 0x6810, 0xa005, 0x0040, 0x9f7f, 0xa080, 0x0013,
+       0x2004, 0xd0fc, 0x00c0, 0x9f7f, 0x0d7f, 0x0078, 0x9f56, 0x6007,
+       0x003a, 0x6003, 0x0001, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0c7e,
+       0x2d60, 0x6100, 0xa186, 0x0002, 0x00c0, 0xa050, 0x6010, 0xa005,
+       0x00c0, 0x9f99, 0x6000, 0xa086, 0x0007, 0x10c0, 0x1328, 0x0078,
+       0xa050, 0xa08c, 0xf000, 0x00c0, 0x9fa5, 0x0078, 0x9fa5, 0x2068,
+       0x6800, 0xa005, 0x00c0, 0x9f9f, 0x2d00, 0xa080, 0x0013, 0x2004,
+       0xa084, 0x0003, 0xa086, 0x0002, 0x00c0, 0x9fbe, 0x6010, 0x2068,
+       0x684c, 0xc0dc, 0xc0f4, 0x684e, 0x6850, 0xc0f4, 0xc0fc, 0x6852,
+       0x2009, 0x0043, 0x1078, 0x98c1, 0x0078, 0xa050, 0x2009, 0x0041,
+       0x0078, 0xa04a, 0xa186, 0x0005, 0x00c0, 0xa009, 0x6810, 0xa080,
+       0x0013, 0x2004, 0xd0bc, 0x00c0, 0x9fd0, 0x0d7f, 0x0078, 0x9f56,
+       0xd0b4, 0x0040, 0x9fd8, 0xd0fc, 0x1040, 0x1328, 0x0078, 0x9f72,
+       0x6007, 0x003a, 0x6003, 0x0001, 0x1078, 0x5bf8, 0x1078, 0x6109,
+       0x0c7e, 0x2d60, 0x6100, 0xa186, 0x0002, 0x0040, 0x9feb, 0xa186,
+       0x0004, 0x00c0, 0xa050, 0x2071, 0xa5e1, 0x7000, 0xa086, 0x0003,
+       0x00c0, 0x9ff8, 0x7004, 0xac06, 0x00c0, 0x9ff8, 0x7003, 0x0000,
+       0x6810, 0xa080, 0x0013, 0x200c, 0xc1f4, 0xc1dc, 0x2102, 0x8000,
+       0x200c, 0xc1f4, 0xc1fc, 0xc1bc, 0x2102, 0x2009, 0x0042, 0x0078,
+       0xa04a, 0x037e, 0x0d7e, 0x0d7e, 0x1078, 0x1381, 0x037f, 0x1040,
+       0x1328, 0x6837, 0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x685b,
+       0x0000, 0x6b5e, 0x6857, 0x0045, 0x2c00, 0x6862, 0x6034, 0x6872,
+       0x2360, 0x6024, 0xc0dd, 0x6026, 0x6018, 0xa080, 0x0028, 0x2004,
+       0xa084, 0x00ff, 0x8007, 0x6320, 0x6b4a, 0x6846, 0x684f, 0x0000,
+       0x6d6a, 0x6e66, 0x686f, 0x0001, 0x1078, 0x4982, 0x2019, 0x0045,
+       0x6008, 0x2068, 0x1078, 0x9a6a, 0x2d00, 0x600a, 0x601f, 0x0006,
+       0x6003, 0x0007, 0x6017, 0x0000, 0x603f, 0x0000, 0x0d7f, 0x037f,
+       0x0078, 0xa051, 0x603f, 0x0000, 0x6003, 0x0007, 0x1078, 0x98c1,
+       0x0c7f, 0x0d7f, 0x007c, 0xa186, 0x0013, 0x00c0, 0xa05d, 0x6004,
+       0xa082, 0x0085, 0x2008, 0x0079, 0xa077, 0xa186, 0x0027, 0x00c0,
+       0xa070, 0x1078, 0x6010, 0x037e, 0x0d7e, 0x6010, 0x2068, 0x2019,
+       0x0004, 0x1078, 0x9e70, 0x0d7f, 0x037f, 0x1078, 0x6109, 0x007c,
+       0xa186, 0x0014, 0x0040, 0xa061, 0x1078, 0x7583, 0x007c, 0xa080,
+       0xa07e, 0xa07e, 0xa07e, 0xa07e, 0xa07e, 0xa080, 0x1078, 0x1328,
+       0x1078, 0x6010, 0x6003, 0x000c, 0x1078, 0x6109, 0x007c, 0xa182,
+       0x008c, 0x00c8, 0xa091, 0xa182, 0x0085, 0x0048, 0xa091, 0x0079,
+       0xa094, 0x1078, 0x7583, 0x007c, 0xa09b, 0xa09b, 0xa09b, 0xa09b,
+       0xa09d, 0xa0bc, 0xa09b, 0x1078, 0x1328, 0x0d7e, 0x2c68, 0x1078,
+       0x74d7, 0x0040, 0xa0b7, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009,
+       0xa88e, 0x210c, 0x6136, 0x2009, 0xa88f, 0x210c, 0x613a, 0x600b,
+       0xffff, 0x6918, 0x611a, 0x601f, 0x0004, 0x1078, 0x5bf8, 0x2d60,
+       0x1078, 0x753d, 0x0d7f, 0x007c, 0x1078, 0x753d, 0x007c, 0x0e7e,
+       0x6018, 0x2070, 0x7000, 0xd0ec, 0x0e7f, 0x007c, 0x6010, 0xa080,
+       0x0013, 0x200c, 0xd1ec, 0x0040, 0xa110, 0x2001, 0xa371, 0x2004,
+       0xd0ec, 0x0040, 0xa110, 0x6003, 0x0002, 0x6024, 0xc0e5, 0x6026,
+       0xd1ac, 0x0040, 0xa0ee, 0x0f7e, 0x2c78, 0x1078, 0x488f, 0x0f7f,
+       0x0040, 0xa0ee, 0x2001, 0xa5a2, 0x2004, 0x603e, 0x2009, 0xa371,
+       0x210c, 0xd1f4, 0x00c0, 0xa10e, 0x0078, 0xa100, 0x2009, 0xa371,
+       0x210c, 0xd1f4, 0x0040, 0xa0fa, 0x6024, 0xc0e4, 0x6026, 0xa006,
+       0x0078, 0xa110, 0x2001, 0xa5a2, 0x200c, 0x8103, 0xa100, 0x603e,
+       0x6018, 0xa088, 0x002b, 0x2104, 0xa005, 0x0040, 0xa10b, 0xa088,
+       0x0003, 0x0078, 0xa103, 0x2c0a, 0x600f, 0x0000, 0xa085, 0x0001,
+       0x007c, 0x017e, 0x0c7e, 0x0e7e, 0x6120, 0xa2f0, 0x002b, 0x2e04,
+       0x2060, 0x8cff, 0x0040, 0xa130, 0x84ff, 0x00c0, 0xa123, 0x6020,
+       0xa106, 0x00c0, 0xa12b, 0x600c, 0x2072, 0x1078, 0x5a41, 0x1078,
+       0x753d, 0x0078, 0xa12d, 0xacf0, 0x0003, 0x2e64, 0x0078, 0xa119,
+       0x0e7f, 0x0c7f, 0x017f, 0x007c, 0x0d7e, 0x6018, 0xa0e8, 0x002b,
+       0x2d04, 0xa005, 0x0040, 0xa146, 0xac06, 0x0040, 0xa144, 0x2d04,
+       0xa0e8, 0x0003, 0x0078, 0xa138, 0x600c, 0x206a, 0x0d7f, 0x007c,
+       0x027e, 0x037e, 0x157e, 0x2011, 0xa325, 0x2204, 0xa084, 0x00ff,
+       0x2019, 0xa88e, 0x2334, 0xa636, 0x00c0, 0xa174, 0x8318, 0x2334,
+       0x2204, 0xa084, 0xff00, 0xa636, 0x00c0, 0xa174, 0x2011, 0xa890,
+       0x6018, 0xa098, 0x000a, 0x20a9, 0x0004, 0x1078, 0x7e55, 0x00c0,
+       0xa174, 0x2011, 0xa894, 0x6018, 0xa098, 0x0006, 0x20a9, 0x0004,
+       0x1078, 0x7e55, 0x00c0, 0xa174, 0x157f, 0x037f, 0x027f, 0x007c,
+       0x0e7e, 0x2071, 0xa300, 0x1078, 0x41f5, 0x1078, 0x260d, 0x0e7f,
+       0x007c, 0x0e7e, 0x6018, 0x2070, 0x7000, 0xd0fc, 0x0040, 0xa18a,
+       0x1078, 0xa18c, 0x0e7f, 0x007c, 0x6850, 0xc0e5, 0x6852, 0x007c,
+       0x0e7e, 0x0c7e, 0x077e, 0x067e, 0x057e, 0x047e, 0x027e, 0x017e,
+       0x127e, 0x2091, 0x8000, 0x2029, 0xa5b4, 0x252c, 0x2021, 0xa5ba,
+       0x2424, 0x2061, 0xaa00, 0x2071, 0xa300, 0x7644, 0x7060, 0xa606,
+       0x0040, 0xa1e4, 0x671c, 0xa786, 0x0001, 0x0040, 0xa1b3, 0xa786,
+       0x0008, 0x00c0, 0xa1da, 0x2500, 0xac06, 0x0040, 0xa1da, 0x2400,
+       0xac06, 0x0040, 0xa1da, 0x1078, 0x9ee5, 0x0040, 0xa1da, 0x1078,
+       0x9ef9, 0x00c0, 0xa1da, 0x6000, 0xa086, 0x0004, 0x00c0, 0xa1cc,
+       0x017e, 0x1078, 0x1749, 0x017f, 0x1078, 0x8c27, 0x00c0, 0xa1d2,
+       0x1078, 0x2839, 0x1078, 0x8c3b, 0x00c0, 0xa1d8, 0x1078, 0x7a05,
+       0x1078, 0x8c01, 0xace0, 0x0010, 0x2001, 0xa315, 0x2004, 0xac02,
+       0x00c8, 0xa1e4, 0x0078, 0xa1a3, 0x127f, 0x017f, 0x027f, 0x047f,
+       0x057f, 0x067f, 0x077f, 0x0c7f, 0x0e7f, 0x007c, 0x127e, 0x007e,
+       0x0e7e, 0x2091, 0x8000, 0x2071, 0xa340, 0xd5a4, 0x0040, 0xa1fb,
+       0x7034, 0x8000, 0x7036, 0xd5b4, 0x0040, 0xa201, 0x7030, 0x8000,
+       0x7032, 0xd5ac, 0x0040, 0xa208, 0x2071, 0xa34a, 0x1078, 0xa237,
+       0x0e7f, 0x007f, 0x127f, 0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091,
+       0x8000, 0x2071, 0xa340, 0xd5a4, 0x0040, 0xa219, 0x7034, 0x8000,
+       0x7036, 0xd5b4, 0x0040, 0xa21f, 0x7030, 0x8000, 0x7032, 0xd5ac,
+       0x0040, 0xa226, 0x2071, 0xa34a, 0x1078, 0xa237, 0x0e7f, 0x007f,
+       0x127f, 0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091, 0x8000, 0x2071,
+       0xa342, 0x1078, 0xa237, 0x0e7f, 0x007f, 0x127f, 0x007c, 0x2e04,
+       0x8000, 0x2072, 0x00c8, 0xa240, 0x8e70, 0x2e04, 0x8000, 0x2072,
+       0x007c, 0x0e7e, 0x2071, 0xa340, 0x1078, 0xa237, 0x0e7f, 0x007c,
+       0x0e7e, 0x2071, 0xa344, 0x1078, 0xa237, 0x0e7f, 0x007c, 0x0001,
+       0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100,
+       0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x6286
+};
+
+/************************************************************************
+ *                                                                     *
+ *               --- ISP2200 Initiator/Target Firmware ---              *
+ *             with Fabric (Public Loop), Point-point, and              *
+ *             expanded LUN addressing for FCTAPE                       *
+ *                                                                     *
+ ************************************************************************
+  Copyright (C) 2000 and 2100 Qlogic Corporation 
+  (www.qlogic.com)
+
+  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.
+************************************************************************/
+
+/*
+ *     Firmware Version 2.01.27 (11:07 Dec 18, 2000)
+ */
+
+unsigned short risc_code_length2200 = 0x9cbf;
+unsigned short risc_code2200[] = { 
+       0x0470, 0x0000, 0x0000, 0x9cbf, 0x0000, 0x0002, 0x0001, 0x001b,
+       0x0017, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2031, 0x3939,
+       0x3920, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241,
+       0x5449, 0x4f4e, 0x2049, 0x5350, 0x3232, 0x3030, 0x2046, 0x6972,
+       0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030,
+       0x322e, 0x3031, 0x2e32, 0x3720, 0x2020, 0x2020, 0x2400, 0x20c1,
+       0x0005, 0x2001, 0x017f, 0x2003, 0x0000, 0x20c9, 0xb1ff, 0x2091,
+       0x2000, 0x2059, 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x27b5,
+       0x2051, 0xad00, 0x2a70, 0x2029, 0xe400, 0x2031, 0xffff, 0x2039,
+       0xe3e9, 0x2021, 0x0200, 0x0804, 0x1449, 0x20a1, 0xacbf, 0xa00e,
+       0x20a9, 0x0741, 0x41a4, 0x3400, 0x755e, 0x7662, 0x775a, 0x7466,
+       0x746a, 0x20a1, 0xb400, 0x7160, 0x810d, 0x810d, 0x810d, 0x810d,
+       0xa18c, 0x000f, 0x2001, 0x000b, 0xa112, 0xa00e, 0x21a8, 0x41a4,
+       0x3400, 0x8211, 0x1dd8, 0x7160, 0x3400, 0xa102, 0x0120, 0x0218,
+       0x20a8, 0xa00e, 0x41a4, 0x3800, 0xd08c, 0x01d8, 0x2009, 0xad00,
+       0x810d, 0x810d, 0x810d, 0x810d, 0xa18c, 0x000f, 0x2001, 0x0001,
+       0xa112, 0x20a1, 0x1000, 0xa00e, 0x21a8, 0x41a4, 0x8211, 0x1de0,
+       0x2009, 0xad00, 0x3400, 0xa102, 0x0120, 0x0218, 0x20a8, 0xa00e,
+       0x41a4, 0x080c, 0x13fc, 0x080c, 0x1613, 0x080c, 0x17ac, 0x080c,
+       0x1e67, 0x080c, 0x492e, 0x080c, 0x801a, 0x080c, 0x159c, 0x080c,
+       0x2ce6, 0x080c, 0x5a01, 0x080c, 0x5045, 0x080c, 0x6487, 0x080c,
+       0x236a, 0x080c, 0x6686, 0x080c, 0x5fae, 0x080c, 0x226b, 0x080c,
+       0x2338, 0x2091, 0x3009, 0x7823, 0x0000, 0x1004, 0x10c5, 0x7820,
+       0xa086, 0x0002, 0x1150, 0x7823, 0x4000, 0x0e04, 0x10bd, 0x781b,
+       0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2a70, 0x7003, 0x0000,
+       0x2a70, 0x7000, 0xa08e, 0x0003, 0x1158, 0x080c, 0x3c98, 0x080c,
+       0x2d0d, 0x080c, 0x5a4f, 0x080c, 0x51f4, 0x080c, 0x64a2, 0x0c80,
+       0x000b, 0x0c98, 0x10e4, 0x10e5, 0x1203, 0x10e2, 0x12cc, 0x13f9,
+       0x13fa, 0x13fb, 0x080c, 0x14f6, 0x0005, 0x0126, 0x00f6, 0x2091,
+       0x8000, 0x7000, 0xa086, 0x0001, 0x1904, 0x11d1, 0x080c, 0x1569,
+       0x080c, 0x574f, 0x0150, 0x080c, 0x5775, 0x1580, 0x2079, 0x0100,
+       0x7828, 0xa085, 0x1800, 0x782a, 0x0448, 0x080c, 0x569a, 0x7000,
+       0xa086, 0x0001, 0x1904, 0x11d1, 0x7088, 0xa086, 0x0028, 0x1904,
+       0x11d1, 0x2079, 0x0100, 0x7827, 0xffff, 0x7a28, 0xa295, 0x1e2f,
+       0x7a2a, 0x2011, 0x566e, 0x080c, 0x650d, 0x2011, 0x567b, 0x080c,
+       0x650d, 0x2011, 0x481b, 0x080c, 0x650d, 0x2011, 0x8030, 0x2019,
+       0x0000, 0x7087, 0x0000, 0x080c, 0x1d0f, 0x00e8, 0x080c, 0x41d1,
+       0x2079, 0x0100, 0x7844, 0xa005, 0x1904, 0x11d1, 0x2011, 0x481b,
+       0x080c, 0x650d, 0x2011, 0x567b, 0x080c, 0x650d, 0x080c, 0x1d0f,
+       0x2001, 0xaf8c, 0x2004, 0x780e, 0x7840, 0xa084, 0xfffb, 0x7842,
+       0x2011, 0x8010, 0x73c8, 0x080c, 0x3c5c, 0x7238, 0xc284, 0x723a,
+       0x2001, 0xad0c, 0x200c, 0xc1ac, 0x2102, 0x080c, 0x79bd, 0x2011,
+       0x0004, 0x080c, 0x959c, 0x080c, 0x4f71, 0x080c, 0x574f, 0x0158,
+       0x080c, 0x4917, 0x0140, 0x7087, 0x0001, 0x70c3, 0x0000, 0x080c,
+       0x436e, 0x0804, 0x11d1, 0x080c, 0x502d, 0x0120, 0x7a0c, 0xc2b4,
+       0x7a0e, 0x0050, 0x080c, 0x9937, 0x70d0, 0xd09c, 0x1128, 0x709c,
+       0xa005, 0x0110, 0x080c, 0x48f5, 0x70db, 0x0000, 0x70d7, 0x0000,
+       0x72d0, 0x080c, 0x574f, 0x1178, 0x2011, 0x0000, 0x0016, 0x080c,
+       0x2744, 0x2019, 0xaf8e, 0x211a, 0x001e, 0x704f, 0xffff, 0x7053,
+       0x00ef, 0x7073, 0x0000, 0x2079, 0xad51, 0x7804, 0xd0ac, 0x0108,
+       0xc295, 0x72d2, 0x080c, 0x574f, 0x0118, 0xa296, 0x0004, 0x0508,
+       0x2011, 0x0001, 0x080c, 0x959c, 0x7097, 0x0000, 0x709b, 0xffff,
+       0x7003, 0x0002, 0x00fe, 0x080c, 0x28fa, 0x2011, 0x0005, 0x080c,
+       0x7adf, 0x080c, 0x6c50, 0x080c, 0x574f, 0x0148, 0x00c6, 0x2061,
+       0x0100, 0x0016, 0x080c, 0x2744, 0x61e2, 0x001e, 0x00ce, 0x012e,
+       0x00d0, 0x7097, 0x0000, 0x709b, 0xffff, 0x7003, 0x0002, 0x2011,
+       0x0005, 0x080c, 0x7adf, 0x080c, 0x6c50, 0x080c, 0x574f, 0x0148,
+       0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, 0x2744, 0x61e2, 0x001e,
+       0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6, 0x080c, 0x574f, 0x1118,
+       0x20a9, 0x0100, 0x0010, 0x20a9, 0x0082, 0x080c, 0x574f, 0x1118,
+       0x2009, 0x0000, 0x0010, 0x2009, 0x007e, 0x0016, 0x0026, 0x0036,
+       0x2110, 0x0026, 0x2019, 0x0029, 0x080c, 0x7cf4, 0x002e, 0x080c,
+       0xac07, 0x003e, 0x002e, 0x001e, 0x080c, 0x2bc9, 0x8108, 0x1f04,
+       0x11e5, 0x00ce, 0x706f, 0x0000, 0x7070, 0xa084, 0x00ff, 0x7072,
+       0x709f, 0x0000, 0x0005, 0x0126, 0x2091, 0x8000, 0x7000, 0xa086,
+       0x0002, 0x1904, 0x12ca, 0x7098, 0xa086, 0xffff, 0x0130, 0x080c,
+       0x28fa, 0x080c, 0x6c50, 0x0804, 0x12ca, 0x70d0, 0xd0ac, 0x1110,
+       0xd09c, 0x0540, 0xd084, 0x0530, 0x0006, 0x0016, 0x2001, 0x0103,
+       0x2009, 0xaf8c, 0x210c, 0x2102, 0x001e, 0x000e, 0xd08c, 0x01d0,
+       0x70d4, 0xa086, 0xffff, 0x0190, 0x080c, 0x2a56, 0x080c, 0x6c50,
+       0x70d0, 0xd094, 0x1904, 0x12ca, 0x2011, 0x0001, 0x2019, 0x0000,
+       0x080c, 0x2a8c, 0x080c, 0x6c50, 0x0804, 0x12ca, 0x70d8, 0xa005,
+       0x1904, 0x12ca, 0x7094, 0xa005, 0x1904, 0x12ca, 0x70d0, 0xd0a4,
+       0x0118, 0xd0b4, 0x0904, 0x12ca, 0x080c, 0x502d, 0x1904, 0x12ca,
+       0x2001, 0xad52, 0x2004, 0xd0ac, 0x01c8, 0x0156, 0x00c6, 0x20a9,
+       0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x4cdc, 0x1118, 0x6000,
+       0xd0ec, 0x1138, 0x001e, 0x8108, 0x1f04, 0x125b, 0x00ce, 0x015e,
+       0x0028, 0x001e, 0x00ce, 0x015e, 0x0804, 0x12ca, 0x0006, 0x0016,
+       0x2001, 0x0103, 0x2009, 0xaf8c, 0x210c, 0x2102, 0x001e, 0x000e,
+       0xa006, 0x2009, 0x0700, 0x20a9, 0x0002, 0x20a1, 0xafb5, 0x40a1,
+       0x706c, 0x8007, 0x7170, 0x810f, 0x20a9, 0x0002, 0x40a1, 0x2009,
+       0x0000, 0x080c, 0x14dc, 0x2001, 0x0000, 0x810f, 0x20a9, 0x0002,
+       0x40a1, 0xa006, 0x2009, 0x0200, 0x20a9, 0x0002, 0x20a1, 0xafc5,
+       0x40a1, 0x7030, 0xc08c, 0x7032, 0x7003, 0x0003, 0x709b, 0xffff,
+       0x080c, 0x1562, 0xa006, 0x080c, 0x261e, 0x080c, 0x3cce, 0x00f6,
+       0x2079, 0x0100, 0x080c, 0x5775, 0x0150, 0x080c, 0x574f, 0x7828,
+       0x0118, 0xa084, 0xe1ff, 0x0010, 0xa084, 0xffdf, 0x782a, 0x00fe,
+       0x2001, 0xafc8, 0x2004, 0xa086, 0x0005, 0x1120, 0x2011, 0x0000,
+       0x080c, 0x7adf, 0x2011, 0x0000, 0x080c, 0x7ae9, 0x080c, 0x6c50,
+       0x080c, 0x6d0d, 0x012e, 0x0005, 0x0016, 0x0046, 0x00f6, 0x0126,
+       0x2091, 0x8000, 0x2079, 0x0100, 0x2009, 0xad33, 0x2104, 0xa005,
+       0x1110, 0x080c, 0x2770, 0x2009, 0x00f7, 0x080c, 0x48de, 0x7940,
+       0xa18c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0110, 0x7827, 0x0040,
+       0xd19c, 0x0110, 0x7827, 0x0008, 0x0006, 0x0036, 0x0156, 0x7954,
+       0xd1ac, 0x1904, 0x133a, 0x080c, 0x5761, 0x0158, 0x080c, 0x5775,
+       0x1128, 0x2001, 0xaf9d, 0x2003, 0x0000, 0x0070, 0x080c, 0x5757,
+       0x0dc0, 0x2001, 0xaf9d, 0x2003, 0xaaaa, 0x2001, 0xaf9e, 0x2003,
+       0x0001, 0x080c, 0x569a, 0x0058, 0x080c, 0x574f, 0x0140, 0x2009,
+       0x00f8, 0x080c, 0x48de, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9,
+       0x09c4, 0x7820, 0xd09c, 0x1138, 0x080c, 0x574f, 0x0138, 0x7824,
+       0xd0ac, 0x1904, 0x13e0, 0x1f04, 0x1319, 0x0070, 0x7824, 0x080c,
+       0x576b, 0x0118, 0xd0ac, 0x1904, 0x13e0, 0xa084, 0x1800, 0x0d98,
+       0x7003, 0x0001, 0x0804, 0x13e0, 0x2001, 0x0001, 0x080c, 0x261e,
+       0x0804, 0x13ef, 0x7850, 0xa084, 0x0180, 0x7852, 0x782f, 0x0020,
+       0x20a9, 0x0046, 0x1d04, 0x1342, 0x2091, 0x6000, 0x1f04, 0x1342,
+       0x7850, 0xa084, 0x0180, 0xa085, 0x0400, 0x7852, 0x782f, 0x0000,
+       0x080c, 0x5761, 0x0158, 0x080c, 0x5775, 0x1128, 0x2001, 0xaf9d,
+       0x2003, 0x0000, 0x0070, 0x080c, 0x5757, 0x0dc0, 0x2001, 0xaf9d,
+       0x2003, 0xaaaa, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x080c, 0x569a,
+       0x0020, 0x2009, 0x00f8, 0x080c, 0x48de, 0x20a9, 0x000e, 0xe000,
+       0x1f04, 0x136f, 0x7850, 0xa084, 0x0180, 0xa085, 0x1400, 0x7852,
+       0x080c, 0x574f, 0x0120, 0x7843, 0x0090, 0x7843, 0x0010, 0x2021,
+       0xe678, 0x2019, 0xea60, 0x7820, 0xd09c, 0x1558, 0x080c, 0x574f,
+       0x05b8, 0x7824, 0xd0ac, 0x1904, 0x13e0, 0x080c, 0x5775, 0x1508,
+       0x0046, 0x2021, 0x0190, 0x8421, 0x1df0, 0x004e, 0x8421, 0x11c8,
+       0x7827, 0x0048, 0x20a9, 0x01f4, 0x1d04, 0x139c, 0x2091, 0x6000,
+       0x1f04, 0x139c, 0x7824, 0xa084, 0x0068, 0x15a8, 0x2001, 0xaf9d,
+       0x2003, 0xaaaa, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x7003, 0x0001,
+       0x0478, 0x8319, 0x1980, 0x2009, 0xad33, 0x2104, 0x8000, 0x200a,
+       0xa084, 0xfff0, 0x0120, 0x200b, 0x0000, 0x080c, 0x2770, 0x00d8,
+       0x080c, 0x5761, 0x1140, 0xa4a2, 0x0064, 0x1128, 0x080c, 0x5726,
+       0x7003, 0x0001, 0x00a8, 0x7827, 0x1800, 0xe000, 0xe000, 0x7824,
+       0x080c, 0x576b, 0x0110, 0xd0ac, 0x1158, 0xa084, 0x1800, 0x09c8,
+       0x7003, 0x0001, 0x0028, 0x2001, 0x0001, 0x080c, 0x261e, 0x0048,
+       0x2001, 0xad33, 0x2003, 0x0000, 0x7827, 0x0048, 0x7828, 0xc09d,
+       0x782a, 0x7850, 0xa084, 0x0180, 0xa085, 0x0400, 0x7852, 0x015e,
+       0x003e, 0x000e, 0x080c, 0x1539, 0x012e, 0x00fe, 0x004e, 0x001e,
+       0x0005, 0x0005, 0x0005, 0x0005, 0x2a70, 0x2001, 0xaf9d, 0x2003,
+       0x0000, 0x7087, 0x0000, 0x2009, 0x0100, 0x2104, 0xa082, 0x0002,
+       0x0218, 0x704f, 0xffff, 0x0010, 0x704f, 0x0000, 0x7057, 0xffff,
+       0x706f, 0x0000, 0x7073, 0x0000, 0x080c, 0x9937, 0x2061, 0xaf8d,
+       0x6003, 0x0909, 0x6007, 0x0000, 0x600b, 0x8800, 0x600f, 0x0200,
+       0x6013, 0x00ff, 0x6017, 0x0003, 0x601b, 0x0000, 0x601f, 0x07d0,
+       0x2061, 0xaf95, 0x6003, 0x8000, 0x6007, 0x0000, 0x600b, 0x0000,
+       0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x0000, 0x601b, 0x0001,
+       0x601f, 0x0000, 0x2061, 0xafa6, 0x6003, 0x514c, 0x6007, 0x4f47,
+       0x600b, 0x4943, 0x600f, 0x2020, 0x2001, 0xad27, 0x2003, 0x0000,
+       0x0005, 0x04a0, 0x2011, 0x0000, 0x81ff, 0x0570, 0xa186, 0x0001,
+       0x1148, 0x2031, 0x8fff, 0x2039, 0xcc01, 0x2021, 0x0100, 0x2029,
+       0xcc00, 0x00e8, 0xa186, 0x0002, 0x1118, 0x2011, 0x0000, 0x00b8,
+       0xa186, 0x0005, 0x1118, 0x2011, 0x0001, 0x0088, 0xa186, 0x0009,
+       0x1118, 0x2011, 0x0002, 0x0058, 0xa186, 0x000a, 0x1118, 0x2011,
+       0x0002, 0x0028, 0xa186, 0x0055, 0x1110, 0x2011, 0x0003, 0x3800,
+       0xa084, 0xfffc, 0xa205, 0x20c0, 0x0804, 0x104d, 0xa00e, 0x2011,
+       0x0003, 0x2019, 0x1485, 0x0804, 0x14d6, 0x2019, 0xaaaa, 0x2061,
+       0xffff, 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c04, 0xa306, 0x2262,
+       0x1110, 0xc1b5, 0xc1a5, 0x2011, 0x0000, 0x2019, 0x1498, 0x04f0,
+       0x2019, 0xaaaa, 0x2061, 0xffff, 0x2c14, 0x2362, 0xe000, 0xe000,
+       0x2c1c, 0x2061, 0x7fff, 0xe000, 0xe000, 0x2c04, 0x2061, 0xffff,
+       0x2262, 0xa306, 0x0110, 0xc18d, 0x0008, 0xc185, 0x2011, 0x0002,
+       0x2019, 0x14b3, 0x0418, 0x2061, 0xffff, 0x2019, 0xaaaa, 0x2c14,
+       0x2362, 0xe000, 0xe000, 0x2c04, 0x2262, 0xa306, 0x1180, 0x2c14,
+       0x2362, 0xe000, 0xe000, 0x2c1c, 0x2061, 0x7fff, 0x2c04, 0x2061,
+       0xffff, 0x2262, 0xa306, 0x1110, 0xc195, 0x0008, 0xc19d, 0x2011,
+       0x0001, 0x2019, 0x14d4, 0x0010, 0x0804, 0x144a, 0x3800, 0xa084,
+       0xfffc, 0xa205, 0x20c0, 0x0837, 0x2011, 0x0000, 0x080c, 0x4cdc,
+       0x1178, 0x6004, 0xa0c4, 0x00ff, 0xa8c6, 0x0006, 0x0128, 0xa0c4,
+       0xff00, 0xa8c6, 0x0600, 0x1120, 0xa186, 0x0080, 0x0108, 0x8210,
+       0x8108, 0xa186, 0x0100, 0x1d50, 0x2208, 0x0005, 0x2091, 0x8000,
+       0x0e04, 0x14f8, 0x0006, 0x0016, 0x2079, 0x0000, 0x7818, 0xd084,
+       0x1de8, 0x001e, 0x792e, 0x000e, 0x782a, 0x000e, 0x7826, 0x3900,
+       0x783a, 0x7823, 0x8002, 0x781b, 0x0001, 0x2091, 0x5000, 0x0126,
+       0x0156, 0x0146, 0x20a9, 0x0010, 0x20a1, 0xb0c8, 0x2091, 0x2000,
+       0x40a1, 0x20a9, 0x0010, 0x2091, 0x2200, 0x40a1, 0x20a9, 0x0010,
+       0x2091, 0x2400, 0x40a1, 0x20a9, 0x0010, 0x2091, 0x2600, 0x40a1,
+       0x20a9, 0x0010, 0x2091, 0x2800, 0x40a1, 0x014e, 0x015e, 0x012e,
+       0x2079, 0xad00, 0x7803, 0x0005, 0x2091, 0x4080, 0x04c9, 0x0cf8,
+       0x0005, 0x0006, 0x080c, 0x1584, 0x1518, 0x00f6, 0x2079, 0xad23,
+       0x2f04, 0x8000, 0x207a, 0xa082, 0x000f, 0x0258, 0xa006, 0x207a,
+       0x2079, 0xad25, 0x2f04, 0xa084, 0x0001, 0xa086, 0x0001, 0x207a,
+       0x0070, 0x2079, 0xad25, 0x2f7c, 0x8fff, 0x1128, 0x2001, 0x0c03,
+       0x2003, 0x0040, 0x0020, 0x2001, 0x0c03, 0x2003, 0x00c0, 0x00fe,
+       0x000e, 0x0005, 0x0409, 0x1120, 0x2001, 0x0c03, 0x2003, 0x0080,
+       0x0005, 0x00d1, 0x1120, 0x2001, 0x0c03, 0x2003, 0x0040, 0x0005,
+       0x0006, 0x0091, 0x1178, 0x2001, 0x0c03, 0x2003, 0x0040, 0x2009,
+       0x0fff, 0x00a1, 0x2001, 0x0c03, 0x2003, 0x0080, 0x2009, 0x0fff,
+       0x0069, 0x0c88, 0x000e, 0x0005, 0x00c6, 0x2061, 0x0c00, 0x2c04,
+       0xa084, 0x00ff, 0xa086, 0x00aa, 0x00ce, 0x0005, 0x0156, 0x0126,
+       0xa18c, 0x0fff, 0x21a8, 0x1d04, 0x1593, 0x2091, 0x6000, 0x1f04,
+       0x1593, 0x012e, 0x015e, 0x0005, 0x2071, 0xad00, 0x715c, 0x712e,
+       0x2021, 0x0001, 0xa190, 0x0030, 0xa298, 0x0030, 0x0240, 0x7060,
+       0xa302, 0x1228, 0x220a, 0x2208, 0x2310, 0x8420, 0x0ca8, 0x3800,
+       0xd08c, 0x0148, 0x7060, 0xa086, 0xad00, 0x0128, 0x7063, 0xad00,
+       0x2011, 0x1000, 0x0c48, 0x200b, 0x0000, 0x74ae, 0x74b2, 0x0005,
+       0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0xad00, 0x70b0, 0xa0ea,
+       0x0010, 0x0268, 0x8001, 0x70b2, 0x702c, 0x2068, 0x2d04, 0x702e,
+       0x206b, 0x0000, 0x6807, 0x0000, 0x012e, 0x00ee, 0x0005, 0xa06e,
+       0x0cd8, 0x00e6, 0x2071, 0xad00, 0x0126, 0x2091, 0x8000, 0x70b0,
+       0x8001, 0x0260, 0x70b2, 0x702c, 0x2068, 0x2d04, 0x702e, 0x206b,
+       0x0000, 0x6807, 0x0000, 0x012e, 0x00ee, 0x0005, 0xa06e, 0x0cd8,
+       0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0xad00, 0x702c, 0x206a,
+       0x2d00, 0x702e, 0x70b0, 0x8000, 0x70b2, 0x012e, 0x00ee, 0x0005,
+       0x8dff, 0x0138, 0x6804, 0x6807, 0x0000, 0x0006, 0x0c49, 0x00de,
+       0x0cb8, 0x0005, 0x00e6, 0x2071, 0xad00, 0x70b0, 0xa08a, 0x0010,
+       0xa00d, 0x00ee, 0x0005, 0x00e6, 0x2071, 0xafec, 0x7007, 0x0000,
+       0x701b, 0x0000, 0x701f, 0x0000, 0x2071, 0x0000, 0x7010, 0xa085,
+       0x8004, 0x7012, 0x00ee, 0x0005, 0x00e6, 0x2270, 0x700b, 0x0000,
+       0x2071, 0xafec, 0x7018, 0xa088, 0xaff5, 0x220a, 0x8000, 0xa084,
+       0x0007, 0x701a, 0x7004, 0xa005, 0x1128, 0x00f6, 0x2079, 0x0010,
+       0x0081, 0x00fe, 0x00ee, 0x0005, 0x00e6, 0x2071, 0xafec, 0x7004,
+       0xa005, 0x1128, 0x00f6, 0x2079, 0x0010, 0x0019, 0x00fe, 0x00ee,
+       0x0005, 0x7000, 0x0002, 0x164f, 0x16b3, 0x16d0, 0x16d0, 0x7018,
+       0x711c, 0xa106, 0x1118, 0x7007, 0x0000, 0x0005, 0x00d6, 0xa180,
+       0xaff5, 0x2004, 0x700a, 0x2068, 0x8108, 0xa18c, 0x0007, 0x711e,
+       0x7803, 0x0026, 0x6824, 0x7832, 0x6828, 0x7836, 0x682c, 0x783a,
+       0x6830, 0x783e, 0x6810, 0x700e, 0x680c, 0x7016, 0x6804, 0x00de,
+       0xd084, 0x0120, 0x7007, 0x0001, 0x0029, 0x0005, 0x7007, 0x0002,
+       0x00b1, 0x0005, 0x0016, 0x0026, 0x710c, 0x2011, 0x0040, 0xa182,
+       0x0040, 0x1210, 0x2110, 0xa006, 0x700e, 0x7212, 0x8203, 0x7822,
+       0x7803, 0x0020, 0x7803, 0x0041, 0x002e, 0x001e, 0x0005, 0x0016,
+       0x0026, 0x0136, 0x0146, 0x0156, 0x7014, 0x2098, 0x20a1, 0x0014,
+       0x7803, 0x0026, 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x1210,
+       0x2110, 0xa006, 0x700e, 0x22a8, 0x53a6, 0x8203, 0x7822, 0x7803,
+       0x0020, 0x3300, 0x7016, 0x7803, 0x0001, 0x015e, 0x014e, 0x013e,
+       0x002e, 0x001e, 0x0005, 0x0136, 0x0146, 0x0156, 0x2099, 0xadf9,
+       0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x0126,
+       0x2091, 0x8000, 0x7803, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084,
+       0x7002, 0x700b, 0xadf4, 0x012e, 0x015e, 0x014e, 0x013e, 0x0005,
+       0x0136, 0x0146, 0x0156, 0x2001, 0xae28, 0x209c, 0x20a1, 0x0014,
+       0x7803, 0x0026, 0x2001, 0xae29, 0x20ac, 0x53a6, 0x2099, 0xae2a,
+       0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x0126,
+       0x2091, 0x8000, 0x7803, 0x0001, 0x7007, 0x0004, 0x7000, 0xc08c,
+       0x7002, 0x700b, 0xae25, 0x012e, 0x015e, 0x014e, 0x013e, 0x0005,
+       0x0016, 0x00e6, 0x2071, 0xafec, 0x00f6, 0x2079, 0x0010, 0x7904,
+       0x7803, 0x0002, 0xd1fc, 0x0120, 0xa18c, 0x0700, 0x7004, 0x0023,
+       0x00fe, 0x00ee, 0x001e, 0x0005, 0x1649, 0x1713, 0x1741, 0x176b,
+       0x179b, 0x1712, 0x0cf8, 0xa18c, 0x0700, 0x1528, 0x0136, 0x0146,
+       0x0156, 0x7014, 0x20a0, 0x2099, 0x0014, 0x7803, 0x0040, 0x7010,
+       0x20a8, 0x53a5, 0x3400, 0x7016, 0x015e, 0x014e, 0x013e, 0x700c,
+       0xa005, 0x0570, 0x7830, 0x7832, 0x7834, 0x7836, 0x080c, 0x167a,
+       0x0005, 0x7008, 0xa080, 0x0002, 0x2003, 0x0100, 0x7007, 0x0000,
+       0x080c, 0x1649, 0x0005, 0x7008, 0xa080, 0x0002, 0x2003, 0x0200,
+       0x0ca8, 0xa18c, 0x0700, 0x1150, 0x700c, 0xa005, 0x0188, 0x7830,
+       0x7832, 0x7834, 0x7836, 0x080c, 0x168f, 0x0005, 0x7008, 0xa080,
+       0x0002, 0x2003, 0x0200, 0x7007, 0x0000, 0x080c, 0x1649, 0x0005,
+       0x00d6, 0x7008, 0x2068, 0x7830, 0x6826, 0x7834, 0x682a, 0x7838,
+       0x682e, 0x783c, 0x6832, 0x680b, 0x0100, 0x00de, 0x7007, 0x0000,
+       0x080c, 0x1649, 0x0005, 0xa18c, 0x0700, 0x1540, 0x0136, 0x0146,
+       0x0156, 0x2001, 0xadf7, 0x2004, 0xa080, 0x000d, 0x20a0, 0x2099,
+       0x0014, 0x7803, 0x0040, 0x20a9, 0x0020, 0x53a5, 0x2001, 0xadf9,
+       0x2004, 0xd0bc, 0x0148, 0x2001, 0xae02, 0x2004, 0xa080, 0x000d,
+       0x20a0, 0x20a9, 0x0020, 0x53a5, 0x015e, 0x014e, 0x013e, 0x7007,
+       0x0000, 0x080c, 0x5ae6, 0x080c, 0x1649, 0x0005, 0x2011, 0x8003,
+       0x080c, 0x3c5c, 0x0cf8, 0xa18c, 0x0700, 0x1148, 0x2001, 0xae27,
+       0x2003, 0x0100, 0x7007, 0x0000, 0x080c, 0x1649, 0x0005, 0x2011,
+       0x8004, 0x080c, 0x3c5c, 0x0cf8, 0x0126, 0x2091, 0x2200, 0x2079,
+       0x0030, 0x2071, 0xaffd, 0x7003, 0x0000, 0x700f, 0xb003, 0x7013,
+       0xb003, 0x780f, 0x00f6, 0x7803, 0x0004, 0x012e, 0x0005, 0x6934,
+       0xa184, 0x0007, 0x0002, 0x17cb, 0x1809, 0x17cb, 0x17cb, 0x17cb,
+       0x17f1, 0x17d8, 0x17cf, 0xa085, 0x0001, 0x0804, 0x1823, 0x684c,
+       0xd0bc, 0x0dc8, 0x6860, 0x682e, 0x685c, 0x682a, 0x6858, 0x04c8,
+       0xa18c, 0x00ff, 0xa186, 0x001e, 0x1d70, 0x684c, 0xd0bc, 0x0d58,
+       0x6860, 0x682e, 0x685c, 0x682a, 0x6804, 0x681a, 0xa080, 0x000d,
+       0x2004, 0xa084, 0x000f, 0xa080, 0x2186, 0x2005, 0x6832, 0x6858,
+       0x0440, 0xa18c, 0x00ff, 0xa186, 0x0015, 0x19a8, 0x684c, 0xd0ac,
+       0x0990, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f,
+       0xa080, 0x2186, 0x2005, 0x6832, 0xa006, 0x682e, 0x682a, 0x6858,
+       0x0080, 0x684c, 0xd0ac, 0x0904, 0x17cb, 0xa006, 0x682e, 0x682a,
+       0x6858, 0xa18c, 0x000f, 0xa188, 0x2186, 0x210d, 0x6932, 0x2d08,
+       0x691a, 0x6826, 0x684c, 0xc0dd, 0x684e, 0xa006, 0x680a, 0x697c,
+       0x6912, 0x6980, 0x6916, 0x0005, 0x20e1, 0x0007, 0x20e1, 0x2000,
+       0x2001, 0x020a, 0x2004, 0x82ff, 0x01a8, 0xa280, 0x0004, 0x00d6,
+       0x206c, 0x684c, 0xd0dc, 0x1150, 0x080c, 0x17bf, 0x0138, 0x00de,
+       0xa280, 0x0000, 0x2003, 0x0002, 0xa016, 0x0020, 0x6808, 0x8000,
+       0x680a, 0x00de, 0x0126, 0x0046, 0x0036, 0x0026, 0x2091, 0x2200,
+       0x002e, 0x003e, 0x004e, 0x7000, 0xa005, 0x01d0, 0x710c, 0x220a,
+       0x8108, 0x230a, 0x8108, 0x240a, 0x8108, 0xa182, 0xb01e, 0x0210,
+       0x2009, 0xb003, 0x710e, 0x7010, 0xa102, 0xa082, 0x0009, 0x0118,
+       0xa080, 0x001b, 0x1118, 0x2009, 0x0138, 0x200a, 0x012e, 0x0005,
+       0x7206, 0x2001, 0x1866, 0x0006, 0x2260, 0x0804, 0x197a, 0x0126,
+       0x0026, 0x0036, 0x00c6, 0x0006, 0x2091, 0x2200, 0x000e, 0x004e,
+       0x003e, 0x002e, 0x00d6, 0x00c6, 0x2460, 0x6110, 0x2168, 0x6a62,
+       0x6b5e, 0xa005, 0x0904, 0x18c8, 0x6808, 0xa005, 0x0904, 0x18ff,
+       0x7000, 0xa005, 0x1108, 0x0488, 0x700c, 0x7110, 0xa106, 0x1904,
+       0x1907, 0x7004, 0xa406, 0x1548, 0x2001, 0x0005, 0x2004, 0xd08c,
+       0x0168, 0x0046, 0x080c, 0x1a6c, 0x004e, 0x2460, 0x6010, 0xa080,
+       0x0002, 0x2004, 0xa005, 0x0904, 0x18ff, 0x0c10, 0x2001, 0x0207,
+       0x2004, 0xd09c, 0x1d48, 0x7804, 0xa084, 0x6000, 0x0120, 0xa086,
+       0x6000, 0x0108, 0x0c08, 0x7818, 0x6812, 0x781c, 0x6816, 0x7803,
+       0x0004, 0x7003, 0x0000, 0x7004, 0x2060, 0x6100, 0xa18e, 0x0004,
+       0x1904, 0x1907, 0x2009, 0x0048, 0x080c, 0x80a7, 0x0804, 0x1907,
+       0x6808, 0xa005, 0x05a0, 0x7000, 0xa005, 0x0588, 0x700c, 0x7110,
+       0xa106, 0x1118, 0x7004, 0xa406, 0x1550, 0x2001, 0x0005, 0x2004,
+       0xd08c, 0x0160, 0x0046, 0x080c, 0x1a6c, 0x004e, 0x2460, 0x6010,
+       0xa080, 0x0002, 0x2004, 0xa005, 0x01d0, 0x0c28, 0x2001, 0x0207,
+       0x2004, 0xd09c, 0x1d50, 0x2001, 0x0005, 0x2004, 0xd08c, 0x1d50,
+       0x7804, 0xa084, 0x6000, 0x0118, 0xa086, 0x6000, 0x19f0, 0x7818,
+       0x6812, 0x781c, 0x6816, 0x7803, 0x0004, 0x7003, 0x0000, 0x6100,
+       0xa18e, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0x80a7, 0x00ce,
+       0x00de, 0x012e, 0x0005, 0x00f6, 0x00e6, 0x0026, 0x0036, 0x0046,
+       0x0056, 0x080c, 0x1d86, 0x0026, 0x0056, 0x2071, 0xaffd, 0x7000,
+       0xa086, 0x0000, 0x0580, 0x7004, 0xac06, 0x11f8, 0x2079, 0x0030,
+       0x7000, 0xa086, 0x0003, 0x01c8, 0x7804, 0xd0fc, 0x1198, 0x2001,
+       0x0207, 0x2004, 0xd09c, 0x1dc0, 0x7803, 0x0004, 0x7804, 0xd0ac,
+       0x1de8, 0x7803, 0x0002, 0x7803, 0x0009, 0x7003, 0x0003, 0x7007,
+       0x0000, 0x0018, 0x080c, 0x1a6c, 0x08d0, 0x0156, 0x20a9, 0x0009,
+       0x2009, 0xb003, 0x2104, 0xac06, 0x1108, 0x200a, 0xa188, 0x0003,
+       0x1f04, 0x1942, 0x015e, 0x005e, 0x002e, 0x2001, 0x015d, 0x201c,
+       0x831a, 0x2302, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202,
+       0x005e, 0x004e, 0x003e, 0x002e, 0x00ee, 0x00fe, 0x0005, 0x700c,
+       0x7110, 0xa106, 0x0904, 0x19dd, 0x2104, 0x7006, 0x2060, 0x8108,
+       0x211c, 0x8108, 0x2124, 0x8108, 0xa182, 0xb01e, 0x0210, 0x2009,
+       0xb003, 0x7112, 0x700c, 0xa106, 0x1128, 0x080c, 0x2744, 0x2001,
+       0x0138, 0x2102, 0x8cff, 0x0588, 0x6010, 0x2068, 0x2d58, 0x6828,
+       0xa406, 0x1580, 0x682c, 0xa306, 0x1568, 0x7004, 0x2060, 0x6020,
+       0xc0d4, 0x6022, 0x684c, 0xd0f4, 0x0128, 0x6817, 0xffff, 0x6813,
+       0xffff, 0x00d8, 0x6850, 0xd0f4, 0x1130, 0x7803, 0x0004, 0x6810,
+       0x781a, 0x6814, 0x781e, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830,
+       0x2040, 0x6034, 0xa0cc, 0x000f, 0x2009, 0x0011, 0x04c9, 0x0118,
+       0x2009, 0x0001, 0x04a9, 0x2d58, 0x0005, 0x080c, 0x1ced, 0x0904,
+       0x195f, 0x0cd0, 0x6020, 0xd0d4, 0x01b8, 0x6038, 0xa402, 0x6034,
+       0xa303, 0x0108, 0x1288, 0x643a, 0x6336, 0x6c2a, 0x6b2e, 0x0046,
+       0x0036, 0x2400, 0x6c7c, 0xa402, 0x6812, 0x2300, 0x6b80, 0xa303,
+       0x6816, 0x003e, 0x004e, 0x0018, 0x080c, 0x98cb, 0x09f0, 0x601c,
+       0xa08e, 0x0008, 0x0904, 0x1985, 0xa08e, 0x000a, 0x0904, 0x1985,
+       0x080c, 0x21a6, 0x1990, 0x0804, 0x1985, 0x7003, 0x0000, 0x0005,
+       0x8aff, 0x0904, 0x1a46, 0xa03e, 0x2730, 0x6850, 0xd0fc, 0x11b8,
+       0xd0f4, 0x1528, 0x00d6, 0x2805, 0xac68, 0x2900, 0x0002, 0x1a30,
+       0x1a15, 0x1a15, 0x1a30, 0x1a30, 0x1a29, 0x1a30, 0x1a15, 0x1a30,
+       0x1a1a, 0x1a1a, 0x1a30, 0x1a30, 0x1a30, 0x1a21, 0x1a1a, 0x7803,
+       0x0004, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0x00d6,
+       0xd99c, 0x0548, 0x2805, 0xac68, 0x6f08, 0x6e0c, 0x0420, 0xc0f4,
+       0x6852, 0x6b6c, 0x6a70, 0x00d6, 0x0428, 0x6b08, 0x6a0c, 0x6d00,
+       0x6c04, 0x00c8, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c,
+       0x0090, 0x00de, 0x00d6, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e,
+       0x1138, 0x00de, 0x080c, 0x2148, 0x1904, 0x19e0, 0xa00e, 0x00b0,
+       0x00de, 0x080c, 0x14f6, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a,
+       0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x00de, 0x6828, 0xa300,
+       0x682a, 0x682c, 0xa201, 0x682e, 0x080c, 0x2148, 0x0005, 0x080c,
+       0x14f6, 0x080c, 0x1e1a, 0x7004, 0x2060, 0x00d6, 0x6010, 0x2068,
+       0x7003, 0x0000, 0x080c, 0x1d22, 0x080c, 0x9596, 0x0170, 0x6808,
+       0x8001, 0x680a, 0x697c, 0x6912, 0x6980, 0x6916, 0x682b, 0xffff,
+       0x682f, 0xffff, 0x6850, 0xc0bd, 0x6852, 0x00de, 0x080c, 0x929c,
+       0x0804, 0x1c5e, 0x080c, 0x14f6, 0x0126, 0x2091, 0x2200, 0x0006,
+       0x0016, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184,
+       0x0700, 0x1978, 0xa184, 0x0003, 0xa086, 0x0003, 0x0d58, 0x7000,
+       0x0002, 0x1a89, 0x1a8f, 0x1b92, 0x1c39, 0x1c4d, 0x1a89, 0x1a89,
+       0x1a89, 0x7804, 0xd09c, 0x1904, 0x1c5e, 0x080c, 0x14f6, 0x8001,
+       0x7002, 0xa184, 0x0880, 0x1190, 0xd19c, 0x1904, 0x1b20, 0x8aff,
+       0x0904, 0x1b20, 0x2009, 0x0001, 0x080c, 0x19e0, 0x0904, 0x1c5e,
+       0x2009, 0x0001, 0x080c, 0x19e0, 0x0804, 0x1c5e, 0x7803, 0x0004,
+       0x7003, 0x0000, 0xd1bc, 0x1904, 0x1b00, 0x0026, 0x0036, 0x7c20,
+       0x7d24, 0x7e30, 0x7f34, 0x7818, 0x6812, 0x781c, 0x6816, 0x2001,
+       0x0201, 0x2004, 0xa005, 0x0140, 0x7808, 0xd0ec, 0x1128, 0x7803,
+       0x0009, 0x7003, 0x0004, 0x0010, 0x080c, 0x1c62, 0x6b28, 0x6a2c,
+       0x2400, 0x686e, 0xa31a, 0x2500, 0x6872, 0xa213, 0x6b2a, 0x6a2e,
+       0x00c6, 0x7004, 0x2060, 0x6020, 0xd0f4, 0x1110, 0x633a, 0x6236,
+       0x00ce, 0x003e, 0x002e, 0x6e1e, 0x6f22, 0x080c, 0x215e, 0x2a00,
+       0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x6850, 0xc0fd, 0x6852,
+       0x6808, 0x8001, 0x680a, 0x1148, 0x684c, 0xd0e4, 0x0130, 0x7004,
+       0x2060, 0x2009, 0x0048, 0x080c, 0x80a7, 0x7000, 0xa086, 0x0004,
+       0x0904, 0x1c5e, 0x7003, 0x0000, 0x080c, 0x195f, 0x0804, 0x1c5e,
+       0x0056, 0x7d0c, 0xd5bc, 0x1110, 0x080c, 0xac73, 0x005e, 0x080c,
+       0x1d22, 0x00f6, 0x7004, 0x2078, 0x080c, 0x5029, 0x0118, 0x7820,
+       0xc0f5, 0x7822, 0x00fe, 0x682b, 0xffff, 0x682f, 0xffff, 0x6808,
+       0x8001, 0x680a, 0x697c, 0x791a, 0x6980, 0x791e, 0x0804, 0x1c5e,
+       0x7004, 0x00c6, 0x2060, 0x6020, 0x00ce, 0xd0f4, 0x0128, 0x6808,
+       0x8001, 0x680a, 0x0804, 0x1c5e, 0x7818, 0x6812, 0x7a1c, 0x6a16,
+       0xd19c, 0x0160, 0xa205, 0x0150, 0x7004, 0xa080, 0x0007, 0x2004,
+       0xa084, 0xfffd, 0xa086, 0x0008, 0x1904, 0x1aa6, 0x684c, 0xc0f5,
+       0x684e, 0x7814, 0xa005, 0x1180, 0x7003, 0x0000, 0x6808, 0x8001,
+       0x680a, 0x1130, 0x7004, 0x2060, 0x2009, 0x0048, 0x080c, 0x80a7,
+       0x080c, 0x195f, 0x0804, 0x1c5e, 0x7818, 0x6812, 0x781c, 0x6816,
+       0x7814, 0x7908, 0xa18c, 0x0fff, 0xa188, 0x0007, 0x8114, 0x8214,
+       0x8214, 0xa10a, 0x8104, 0x8004, 0x8004, 0xa20a, 0x810b, 0x810b,
+       0x810b, 0x080c, 0x1da5, 0x7803, 0x0004, 0x780f, 0xffff, 0x7803,
+       0x0001, 0x7804, 0xd0fc, 0x0de8, 0x7803, 0x0002, 0x7803, 0x0004,
+       0x780f, 0x00f6, 0x7004, 0x7007, 0x0000, 0x2060, 0x2009, 0x0048,
+       0x080c, 0x80a7, 0x080c, 0x1dd7, 0x0958, 0x7908, 0xd1ec, 0x1118,
+       0x2009, 0x0009, 0x0010, 0x2009, 0x0019, 0x7902, 0x7003, 0x0003,
+       0x0804, 0x1c5e, 0x8001, 0x7002, 0xd194, 0x01a8, 0x7804, 0xd0fc,
+       0x1904, 0x1c2c, 0xd09c, 0x0130, 0x7804, 0xd0fc, 0x1904, 0x1a74,
+       0xd09c, 0x11a8, 0x8aff, 0x0904, 0x1c5e, 0x2009, 0x0001, 0x080c,
+       0x19e0, 0x0804, 0x1c5e, 0xa184, 0x0888, 0x1148, 0x8aff, 0x0904,
+       0x1c5e, 0x2009, 0x0001, 0x080c, 0x19e0, 0x0804, 0x1c5e, 0x7818,
+       0x6812, 0x7a1c, 0x6a16, 0xa205, 0x0904, 0x1b3e, 0x7803, 0x0004,
+       0x7003, 0x0000, 0xd1bc, 0x1904, 0x1c0f, 0x6834, 0xa084, 0x00ff,
+       0xa086, 0x0029, 0x1118, 0xd19c, 0x1904, 0x1b3e, 0x0026, 0x0036,
+       0x7c20, 0x7d24, 0x7e30, 0x7f34, 0x7818, 0x6812, 0x781c, 0x6816,
+       0x2001, 0x0201, 0x2004, 0xa005, 0x0140, 0x7808, 0xd0ec, 0x1128,
+       0x7803, 0x0009, 0x7003, 0x0004, 0x0020, 0x0016, 0x080c, 0x1c62,
+       0x001e, 0x6b28, 0x6a2c, 0x080c, 0x215e, 0x00d6, 0x2805, 0xac68,
+       0x6034, 0xd09c, 0x1128, 0x6808, 0xa31a, 0x680c, 0xa213, 0x0020,
+       0x6810, 0xa31a, 0x6814, 0xa213, 0x00de, 0xd194, 0x0904, 0x1ac8,
+       0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x6808, 0x8001,
+       0x680a, 0x6b2a, 0x6a2e, 0x003e, 0x002e, 0x0804, 0x1b50, 0x0056,
+       0x7d0c, 0x080c, 0xac73, 0x005e, 0x080c, 0x1d22, 0x00f6, 0x7004,
+       0x2078, 0x080c, 0x5029, 0x0118, 0x7820, 0xc0f5, 0x7822, 0x00fe,
+       0x682b, 0xffff, 0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c,
+       0x791a, 0x6980, 0x791e, 0x0490, 0x7804, 0xd09c, 0x0904, 0x1a74,
+       0x7c20, 0x7824, 0xa405, 0x1904, 0x1a74, 0x7803, 0x0002, 0x0804,
+       0x1bb7, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0xa00d, 0x0150,
+       0x6808, 0x8001, 0x680a, 0x1130, 0x7004, 0x2060, 0x2009, 0x0048,
+       0x080c, 0x80a7, 0x080c, 0x195f, 0x0088, 0x7803, 0x0004, 0x7003,
+       0x0000, 0x7004, 0x2060, 0x6010, 0xa005, 0x0da0, 0x2068, 0x6808,
+       0x8000, 0x680a, 0x6c28, 0x6b2c, 0x080c, 0x197a, 0x001e, 0x000e,
+       0x012e, 0x0005, 0x700c, 0x7110, 0xa106, 0x0904, 0x1ce1, 0x7004,
+       0x0016, 0x210c, 0xa106, 0x001e, 0x0904, 0x1ce1, 0x00d6, 0x00c6,
+       0x216c, 0x2d00, 0xa005, 0x0904, 0x1cdf, 0x6820, 0xd0d4, 0x1904,
+       0x1cdf, 0x6810, 0x2068, 0x6850, 0xd0fc, 0x0558, 0x8108, 0x2104,
+       0x6b2c, 0xa306, 0x1904, 0x1cdf, 0x8108, 0x2104, 0x6a28, 0xa206,
+       0x1904, 0x1cdf, 0x6850, 0xc0fc, 0xc0f5, 0x6852, 0x686c, 0x7822,
+       0x6870, 0x7826, 0x681c, 0x7832, 0x6820, 0x7836, 0x6818, 0x2060,
+       0x6034, 0xd09c, 0x0150, 0x6830, 0x2005, 0x00d6, 0xac68, 0x6808,
+       0x783a, 0x680c, 0x783e, 0x00de, 0x04a0, 0xa006, 0x783a, 0x783e,
+       0x0480, 0x8108, 0x2104, 0xa005, 0x1590, 0x8108, 0x2104, 0xa005,
+       0x1570, 0x6850, 0xc0f5, 0x6852, 0x6830, 0x2005, 0x6918, 0xa160,
+       0xa180, 0x000d, 0x2004, 0xd09c, 0x1170, 0x6008, 0x7822, 0x686e,
+       0x600c, 0x7826, 0x6872, 0x6000, 0x7832, 0x6004, 0x7836, 0xa006,
+       0x783a, 0x783e, 0x0070, 0x6010, 0x7822, 0x686e, 0x6014, 0x7826,
+       0x6872, 0x6000, 0x7832, 0x6004, 0x7836, 0x6008, 0x783a, 0x600c,
+       0x783e, 0x6810, 0x781a, 0x6814, 0x781e, 0x7803, 0x0011, 0x00ce,
+       0x00de, 0x0005, 0x2011, 0x0201, 0x2009, 0x003c, 0x2204, 0xa005,
+       0x1118, 0x8109, 0x1dd8, 0x0005, 0x0005, 0x0ca1, 0x01e0, 0x7908,
+       0xd1ec, 0x1160, 0x080c, 0x1dd7, 0x0148, 0x7803, 0x0009, 0x7904,
+       0xd1fc, 0x0de8, 0x7803, 0x0006, 0x0c29, 0x0168, 0x780c, 0xd0a4,
+       0x1150, 0x7007, 0x0000, 0x080c, 0x1dd7, 0x0140, 0x7803, 0x0019,
+       0x7003, 0x0003, 0x0018, 0x00b1, 0xa085, 0x0001, 0x0005, 0x0126,
+       0x2091, 0x2200, 0x7000, 0xa086, 0x0003, 0x1150, 0x700c, 0x7110,
+       0xa106, 0x0130, 0x20e1, 0x9028, 0x700f, 0xb003, 0x7013, 0xb003,
+       0x012e, 0x0005, 0x00c6, 0x080c, 0x574f, 0x1550, 0x2001, 0x0160,
+       0x2003, 0x0000, 0x2001, 0x0138, 0x2003, 0x0000, 0x2011, 0x00c8,
+       0xe000, 0xe000, 0x8211, 0x1de0, 0x080c, 0x1d7e, 0x700c, 0x7110,
+       0xa106, 0x0190, 0x2104, 0xa005, 0x0130, 0x2060, 0x6010, 0x2060,
+       0x6008, 0x8001, 0x600a, 0xa188, 0x0003, 0xa182, 0xb01e, 0x0210,
+       0x2009, 0xb003, 0x7112, 0x0c50, 0x080c, 0x57d1, 0x00ce, 0x0005,
+       0x04a9, 0x20e1, 0x9028, 0x700c, 0x7110, 0xa106, 0x01d0, 0x2104,
+       0xa005, 0x0130, 0x2060, 0x6010, 0x2060, 0x6008, 0x8001, 0x600a,
+       0xa188, 0x0003, 0xa182, 0xb01e, 0x0210, 0x2009, 0xb003, 0x7112,
+       0x700c, 0xa106, 0x1d40, 0x080c, 0x2744, 0x2001, 0x0138, 0x2102,
+       0x0c10, 0x2001, 0x015d, 0x200c, 0x810a, 0x2102, 0x2001, 0x0160,
+       0x2502, 0x2001, 0x0138, 0x2202, 0x00ce, 0x0005, 0x20e1, 0x9028,
+       0x2001, 0x015d, 0x200c, 0x810a, 0x2102, 0x0005, 0x2001, 0x0138,
+       0x2014, 0x2003, 0x0000, 0x2001, 0x0160, 0x202c, 0x2003, 0x0000,
+       0x2021, 0xb015, 0x2001, 0x0141, 0x201c, 0xd3dc, 0x1168, 0x2001,
+       0x0109, 0x201c, 0xa39c, 0x0048, 0x1138, 0x2001, 0x0111, 0x201c,
+       0x83ff, 0x1110, 0x8421, 0x1d70, 0x0005, 0x00e6, 0x2071, 0x0200,
+       0x7808, 0xa084, 0xf000, 0xa10d, 0x08c9, 0x2019, 0x5000, 0x8319,
+       0x0168, 0x2001, 0xb01e, 0x2004, 0xa086, 0x0000, 0x0138, 0x2001,
+       0x0021, 0xd0fc, 0x0da0, 0x080c, 0x1ff4, 0x0c78, 0x20e1, 0x7000,
+       0x7324, 0x7420, 0x7028, 0x7028, 0x7426, 0x7037, 0x0001, 0x810f,
+       0x712e, 0x702f, 0x0100, 0x7037, 0x0008, 0x7326, 0x7422, 0x2001,
+       0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x00ee, 0x0005, 0x7908,
+       0xa18c, 0x0fff, 0xa182, 0x0009, 0x0218, 0xa085, 0x0001, 0x0088,
+       0x2001, 0x020a, 0x81ff, 0x0130, 0x20e1, 0x6000, 0x200c, 0x200c,
+       0x200c, 0x200c, 0x20e1, 0x7000, 0x200c, 0x200c, 0x7003, 0x0000,
+       0xa006, 0x0005, 0x00f6, 0x00e6, 0x0016, 0x0026, 0x2071, 0xaffd,
+       0x2079, 0x0030, 0x2011, 0x0050, 0x7000, 0xa086, 0x0000, 0x01a8,
+       0x8211, 0x0188, 0x2001, 0x0005, 0x2004, 0xd08c, 0x0dc8, 0x7904,
+       0xa18c, 0x0780, 0x0016, 0x080c, 0x1a6c, 0x001e, 0x81ff, 0x1118,
+       0x2011, 0x0050, 0x0c48, 0xa085, 0x0001, 0x002e, 0x001e, 0x00ee,
+       0x00fe, 0x0005, 0x7803, 0x0004, 0x2009, 0x0064, 0x7804, 0xd0ac,
+       0x0904, 0x1e66, 0x8109, 0x1dd0, 0x2009, 0x0100, 0x210c, 0xa18a,
+       0x0003, 0x0a0c, 0x14f6, 0x080c, 0x20f2, 0x00e6, 0x00f6, 0x2071,
+       0xafec, 0x2079, 0x0010, 0x7004, 0xa086, 0x0000, 0x0538, 0x7800,
+       0x0006, 0x7820, 0x0006, 0x7830, 0x0006, 0x7834, 0x0006, 0x7838,
+       0x0006, 0x783c, 0x0006, 0x7803, 0x0004, 0xe000, 0xe000, 0x2079,
+       0x0030, 0x7804, 0xd0ac, 0x190c, 0x14f6, 0x2079, 0x0010, 0x000e,
+       0x783e, 0x000e, 0x783a, 0x000e, 0x7836, 0x000e, 0x7832, 0x000e,
+       0x7822, 0x000e, 0x7802, 0x00fe, 0x00ee, 0x0030, 0x00fe, 0x00ee,
+       0x7804, 0xd0ac, 0x190c, 0x14f6, 0x080c, 0x6d0d, 0x0005, 0x00e6,
+       0x2071, 0xb01e, 0x7003, 0x0000, 0x00ee, 0x0005, 0x00d6, 0xa280,
+       0x0004, 0x206c, 0x694c, 0xd1dc, 0x1904, 0x1ee4, 0x6934, 0xa184,
+       0x0007, 0x0002, 0x1e82, 0x1ecf, 0x1e82, 0x1e82, 0x1e82, 0x1eb6,
+       0x1e95, 0x1e84, 0x080c, 0x14f6, 0x684c, 0xd0b4, 0x0904, 0x1fcc,
+       0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a,
+       0x6880, 0x680e, 0x6958, 0x0804, 0x1ed7, 0x6834, 0xa084, 0x00ff,
+       0xa086, 0x001e, 0x1d38, 0x684c, 0xd0b4, 0x0904, 0x1fcc, 0x6860,
+       0x682e, 0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a, 0x6880,
+       0x680e, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f,
+       0xa080, 0x2186, 0x2005, 0x6832, 0x6958, 0x0450, 0xa18c, 0x00ff,
+       0xa186, 0x0015, 0x1548, 0x684c, 0xd0b4, 0x0904, 0x1fcc, 0x6804,
+       0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x2186,
+       0x2005, 0x6832, 0x6958, 0xa006, 0x682e, 0x682a, 0x0088, 0x684c,
+       0xd0b4, 0x0904, 0x1a47, 0x6958, 0xa006, 0x682e, 0x682a, 0x2d00,
+       0x681a, 0x6834, 0xa084, 0x000f, 0xa080, 0x2186, 0x2005, 0x6832,
+       0x6926, 0x684c, 0xc0dd, 0x684e, 0x00de, 0x0005, 0x00f6, 0x2079,
+       0x0020, 0x7804, 0xd0fc, 0x190c, 0x1ff4, 0x00e6, 0x00d6, 0x2071,
+       0xb01e, 0x7000, 0xa005, 0x1904, 0x1f4c, 0x00c6, 0x7206, 0xa280,
+       0x0004, 0x205c, 0x7004, 0x2068, 0x7803, 0x0004, 0x6818, 0x00d6,
+       0x2068, 0x686c, 0x7812, 0x6890, 0x00f6, 0x20e1, 0x9040, 0x2079,
+       0x0200, 0x781a, 0x2079, 0x0100, 0x8004, 0x78d6, 0x00fe, 0x00de,
+       0x2b68, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034,
+       0xa0cc, 0x000f, 0x6908, 0x791a, 0x7116, 0x680c, 0x781e, 0x701a,
+       0xa006, 0x700e, 0x7012, 0x7004, 0x692c, 0x6814, 0xa106, 0x1120,
+       0x6928, 0x6810, 0xa106, 0x0158, 0x0036, 0x0046, 0x6b14, 0x6c10,
+       0x080c, 0x21a6, 0x004e, 0x003e, 0x0110, 0x00ce, 0x00a8, 0x8aff,
+       0x1120, 0x00ce, 0xa085, 0x0001, 0x0078, 0x0126, 0x2091, 0x8000,
+       0x2079, 0x0020, 0x2009, 0x0001, 0x0059, 0x0118, 0x2009, 0x0001,
+       0x0039, 0x012e, 0x00ce, 0xa006, 0x00de, 0x00ee, 0x00fe, 0x0005,
+       0x0076, 0x0066, 0x0056, 0x0046, 0x0036, 0x0026, 0x8aff, 0x0904,
+       0x1fc5, 0x700c, 0x7214, 0xa23a, 0x7010, 0x7218, 0xa203, 0x0a04,
+       0x1fc4, 0xa705, 0x0904, 0x1fc4, 0xa03e, 0x2730, 0x6850, 0xd0fc,
+       0x11a8, 0x00d6, 0x2805, 0xac68, 0x2900, 0x0002, 0x1fa7, 0x1f8c,
+       0x1f8c, 0x1fa7, 0x1fa7, 0x1fa0, 0x1fa7, 0x1f8c, 0x1fa7, 0x1f91,
+       0x1f91, 0x1fa7, 0x1fa7, 0x1fa7, 0x1f98, 0x1f91, 0xc0fc, 0x6852,
+       0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0xd99c, 0x0528, 0x00d6, 0x2805,
+       0xac68, 0x6f08, 0x6e0c, 0x00f0, 0x6b08, 0x6a0c, 0x6d00, 0x6c04,
+       0x00c8, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0090,
+       0x00de, 0x00d6, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x1138,
+       0x00de, 0x080c, 0x2148, 0x1904, 0x1f56, 0xa00e, 0x00f0, 0x00de,
+       0x080c, 0x14f6, 0x00de, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a,
+       0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x6828, 0xa300, 0x682a,
+       0x682c, 0xa201, 0x682e, 0x700c, 0xa300, 0x700e, 0x7010, 0xa201,
+       0x7012, 0x080c, 0x2148, 0x0008, 0xa006, 0x002e, 0x003e, 0x004e,
+       0x005e, 0x006e, 0x007e, 0x0005, 0x080c, 0x14f6, 0x0026, 0x2001,
+       0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003,
+       0x0000, 0x7004, 0x2060, 0x00d6, 0x6010, 0x2068, 0x080c, 0x9596,
+       0x0118, 0x6850, 0xc0bd, 0x6852, 0x00de, 0x080c, 0x929c, 0x20e1,
+       0x9040, 0x080c, 0x7cb8, 0x2011, 0x0000, 0x080c, 0x7ae9, 0x080c,
+       0x6d0d, 0x002e, 0x0804, 0x20ad, 0x0126, 0x2091, 0x2400, 0x0006,
+       0x0016, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x2079, 0x0020, 0x2071,
+       0xb01e, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184,
+       0x0700, 0x1920, 0x7000, 0x0002, 0x20ad, 0x2010, 0x2080, 0x20ab,
+       0x8001, 0x7002, 0xd19c, 0x1170, 0x8aff, 0x05d0, 0x2009, 0x0001,
+       0x080c, 0x1f50, 0x0904, 0x20ad, 0x2009, 0x0001, 0x080c, 0x1f50,
+       0x0804, 0x20ad, 0x7803, 0x0004, 0xd194, 0x0148, 0x6850, 0xc0fc,
+       0x6852, 0x8aff, 0x11d8, 0x684c, 0xc0f5, 0x684e, 0x00b8, 0x0026,
+       0x0036, 0x6b28, 0x6a2c, 0x7820, 0x686e, 0xa31a, 0x7824, 0x6872,
+       0xa213, 0x7830, 0x681e, 0x7834, 0x6822, 0x6b2a, 0x6a2e, 0x003e,
+       0x002e, 0x080c, 0x215e, 0x6850, 0xc0fd, 0x6852, 0x2a00, 0x6826,
+       0x2c00, 0x681a, 0x2800, 0x6832, 0x7003, 0x0000, 0x0804, 0x20ad,
+       0x00f6, 0x0026, 0x781c, 0x0006, 0x7818, 0x0006, 0x2079, 0x0100,
+       0x7a14, 0xa284, 0x0184, 0xa085, 0x0012, 0x7816, 0x0036, 0x2019,
+       0x1000, 0x8319, 0x090c, 0x14f6, 0x7820, 0xd0bc, 0x1dd0, 0x003e,
+       0x79c8, 0x000e, 0xa102, 0x001e, 0x0006, 0x0016, 0x79c4, 0x000e,
+       0xa103, 0x78c6, 0x000e, 0x78ca, 0xa284, 0x0184, 0xa085, 0x0012,
+       0x7816, 0x002e, 0x00fe, 0x7803, 0x0008, 0x7003, 0x0000, 0x0468,
+       0x8001, 0x7002, 0xd194, 0x0168, 0x7804, 0xd0fc, 0x1904, 0x2004,
+       0xd19c, 0x11f8, 0x8aff, 0x0508, 0x2009, 0x0001, 0x080c, 0x1f50,
+       0x00e0, 0x0026, 0x0036, 0x6b28, 0x6a2c, 0x080c, 0x215e, 0x00d6,
+       0x2805, 0xac68, 0x6034, 0xd09c, 0x1128, 0x6808, 0xa31a, 0x680c,
+       0xa213, 0x0020, 0x6810, 0xa31a, 0x6814, 0xa213, 0x00de, 0x0804,
+       0x2033, 0x0804, 0x202f, 0x080c, 0x14f6, 0x00ce, 0x00de, 0x00ee,
+       0x00fe, 0x001e, 0x000e, 0x012e, 0x0005, 0x00f6, 0x00e6, 0x2071,
+       0xb01e, 0x7000, 0xa086, 0x0000, 0x0590, 0x2079, 0x0020, 0x0016,
+       0x2009, 0x0207, 0x210c, 0xd194, 0x0158, 0x2009, 0x020c, 0x210c,
+       0xa184, 0x0003, 0x0128, 0x20e1, 0x9040, 0x2001, 0x020c, 0x2102,
+       0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0xa106, 0x1110,
+       0x20e1, 0x9040, 0x7804, 0xd0fc, 0x0d18, 0x080c, 0x1ff4, 0x7000,
+       0xa086, 0x0000, 0x19e8, 0x001e, 0x7803, 0x0004, 0x7804, 0xd0ac,
+       0x1de8, 0x20e1, 0x9040, 0x7803, 0x0002, 0x7003, 0x0000, 0x00ee,
+       0x00fe, 0x0005, 0x0026, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2071,
+       0xb01e, 0x2079, 0x0020, 0x7000, 0xa086, 0x0000, 0x0540, 0x7004,
+       0x2060, 0x6010, 0x2068, 0x080c, 0x9596, 0x0158, 0x6850, 0xc0b5,
+       0x6852, 0x680c, 0x7a1c, 0xa206, 0x1120, 0x6808, 0x7a18, 0xa206,
+       0x01e0, 0x2001, 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803,
+       0x0004, 0x7003, 0x0000, 0x7004, 0x2060, 0x080c, 0x929c, 0x20e1,
+       0x9040, 0x080c, 0x7cb8, 0x2011, 0x0000, 0x080c, 0x7ae9, 0x00fe,
+       0x00ee, 0x00de, 0x00ce, 0x002e, 0x0005, 0x6810, 0x6a14, 0xa205,
+       0x1d00, 0x684c, 0xc0dc, 0x684e, 0x2c10, 0x080c, 0x1e6e, 0x2001,
+       0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003,
+       0x0000, 0x2069, 0xafc7, 0x6833, 0x0000, 0x683f, 0x0000, 0x08f8,
+       0x8840, 0x2805, 0xa005, 0x1170, 0x6004, 0xa005, 0x0168, 0x681a,
+       0x2060, 0x6034, 0xa084, 0x000f, 0xa080, 0x2186, 0x2045, 0x88ff,
+       0x090c, 0x14f6, 0x8a51, 0x0005, 0x2050, 0x0005, 0x8a50, 0x8841,
+       0x2805, 0xa005, 0x1190, 0x2c00, 0xad06, 0x0120, 0x6000, 0xa005,
+       0x1108, 0x2d00, 0x2060, 0x681a, 0x6034, 0xa084, 0x000f, 0xa080,
+       0x2196, 0x2045, 0x88ff, 0x090c, 0x14f6, 0x0005, 0x0000, 0x0011,
+       0x0015, 0x0019, 0x001d, 0x0021, 0x0025, 0x0029, 0x0000, 0x000f,
+       0x0015, 0x001b, 0x0021, 0x0027, 0x0000, 0x0000, 0x0000, 0x217b,
+       0x2177, 0x0000, 0x0000, 0x2185, 0x0000, 0x217b, 0x0000, 0x2182,
+       0x217f, 0x0000, 0x0000, 0x0000, 0x2185, 0x2182, 0x0000, 0x217d,
+       0x217d, 0x0000, 0x0000, 0x2185, 0x0000, 0x217d, 0x0000, 0x2183,
+       0x2183, 0x0000, 0x0000, 0x0000, 0x2185, 0x2183, 0x00a6, 0x0096,
+       0x0086, 0x6b2e, 0x6c2a, 0x6858, 0xa055, 0x0904, 0x2237, 0x2d60,
+       0x6034, 0xa0cc, 0x000f, 0xa9c0, 0x2186, 0xa986, 0x0007, 0x0130,
+       0xa986, 0x000e, 0x0118, 0xa986, 0x000f, 0x1120, 0x605c, 0xa422,
+       0x6060, 0xa31a, 0x2805, 0xa045, 0x1140, 0x0310, 0x0804, 0x2237,
+       0x6004, 0xa065, 0x0904, 0x2237, 0x0c18, 0x2805, 0xa005, 0x01a8,
+       0xac68, 0xd99c, 0x1128, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0020,
+       0x6810, 0xa422, 0x6814, 0xa31b, 0x0620, 0x2300, 0xa405, 0x0150,
+       0x8a51, 0x0904, 0x2237, 0x8840, 0x0c40, 0x6004, 0xa065, 0x0904,
+       0x2237, 0x0830, 0x8a51, 0x0904, 0x2237, 0x8840, 0x2805, 0xa005,
+       0x1158, 0x6004, 0xa065, 0x0904, 0x2237, 0x6034, 0xa0cc, 0x000f,
+       0xa9c0, 0x2186, 0x2805, 0x2040, 0x2b68, 0x6850, 0xc0fc, 0x6852,
+       0x0458, 0x8422, 0x8420, 0x831a, 0xa399, 0x0000, 0x00d6, 0x2b68,
+       0x6c6e, 0x6b72, 0x00de, 0xd99c, 0x1168, 0x6908, 0x2400, 0xa122,
+       0x690c, 0x2300, 0xa11b, 0x0a0c, 0x14f6, 0x6800, 0xa420, 0x6804,
+       0xa319, 0x0060, 0x6910, 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b,
+       0x0a0c, 0x14f6, 0x6800, 0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e,
+       0x6b22, 0x6850, 0xc0fd, 0x6852, 0x2c00, 0x681a, 0x2800, 0x6832,
+       0x2a00, 0x6826, 0x000e, 0x000e, 0x000e, 0xa006, 0x0028, 0x008e,
+       0x009e, 0x00ae, 0xa085, 0x0001, 0x0005, 0x2001, 0x0005, 0x2004,
+       0xa084, 0x0007, 0x0002, 0x224b, 0x224c, 0x224f, 0x2252, 0x2257,
+       0x225a, 0x225f, 0x2264, 0x0005, 0x080c, 0x1ff4, 0x0005, 0x080c,
+       0x1a6c, 0x0005, 0x080c, 0x1a6c, 0x080c, 0x1ff4, 0x0005, 0x080c,
+       0x16f8, 0x0005, 0x080c, 0x1ff4, 0x080c, 0x16f8, 0x0005, 0x080c,
+       0x1a6c, 0x080c, 0x16f8, 0x0005, 0x080c, 0x1a6c, 0x080c, 0x1ff4,
+       0x080c, 0x16f8, 0x0005, 0x0126, 0x2091, 0x2600, 0x2079, 0x0200,
+       0x2071, 0xb280, 0x2069, 0xad00, 0x2009, 0x0004, 0x7912, 0x7817,
+       0x0004, 0x080c, 0x2651, 0x781b, 0x0002, 0x20e1, 0x9080, 0x20e1,
+       0x4000, 0x20a9, 0x0080, 0x782f, 0x0000, 0x1f04, 0x2283, 0x20e1,
+       0x9080, 0x783b, 0x001f, 0x20e1, 0x8700, 0x012e, 0x0005, 0x0126,
+       0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c, 0x2335, 0xa084, 0x0007,
+       0x0002, 0x22b3, 0x22a1, 0x22a4, 0x22a7, 0x22ac, 0x22ae, 0x22b0,
+       0x22b2, 0x080c, 0x5fb7, 0x0078, 0x080c, 0x5ff0, 0x0060, 0x080c,
+       0x5fb7, 0x080c, 0x5ff0, 0x0038, 0x0041, 0x0028, 0x0031, 0x0018,
+       0x0021, 0x0008, 0x0011, 0x012e, 0x0005, 0x0006, 0x0016, 0x0026,
+       0x7930, 0xa184, 0x0003, 0x0118, 0x20e1, 0x9040, 0x04a0, 0xa184,
+       0x0030, 0x01e0, 0x6a00, 0xa286, 0x0003, 0x1108, 0x00a0, 0x080c,
+       0x574f, 0x1178, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00,
+       0x2003, 0x0001, 0xa085, 0x0001, 0x080c, 0x5793, 0x080c, 0x569a,
+       0x0010, 0x080c, 0x485e, 0x20e1, 0x9010, 0x00a8, 0xa184, 0x00c0,
+       0x0168, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0xaffd, 0x080c,
+       0x1d22, 0x005e, 0x004e, 0x003e, 0x00ee, 0x0028, 0xa184, 0x0300,
+       0x0110, 0x20e1, 0x9020, 0x7932, 0x002e, 0x001e, 0x000e, 0x0005,
+       0x0016, 0x00e6, 0x00f6, 0x2071, 0xad00, 0x7128, 0x2001, 0xaf90,
+       0x2102, 0x2001, 0xaf98, 0x2102, 0xa182, 0x0211, 0x1218, 0x2009,
+       0x0008, 0x0400, 0xa182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0,
+       0xa182, 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0, 0xa182, 0x0349,
+       0x1218, 0x2009, 0x0005, 0x0070, 0xa182, 0x0421, 0x1218, 0x2009,
+       0x0004, 0x0040, 0xa182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010,
+       0x2009, 0x0002, 0x2079, 0x0200, 0x7912, 0x7817, 0x0004, 0x080c,
+       0x2651, 0x00fe, 0x00ee, 0x001e, 0x0005, 0x7938, 0x080c, 0x14f6,
+       0x0126, 0x2091, 0x2800, 0x2061, 0x0100, 0x2071, 0xad00, 0x6024,
+       0x6026, 0x6053, 0x0030, 0x080c, 0x2690, 0x6050, 0xa084, 0xfe7f,
+       0x6052, 0x2009, 0x00ef, 0x6132, 0x6136, 0x080c, 0x26a0, 0x60e7,
+       0x0000, 0x61ea, 0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043, 0x0000,
+       0x602f, 0x0080, 0x602f, 0x0000, 0x6007, 0x0e9f, 0x601b, 0x001e,
+       0x600f, 0x00ff, 0x2001, 0xaf8c, 0x2003, 0x00ff, 0x602b, 0x002f,
+       0x012e, 0x0005, 0x2001, 0xad31, 0x2003, 0x0000, 0x2001, 0xad30,
+       0x2003, 0x0001, 0x0005, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016,
+       0x0026, 0x6124, 0xa184, 0x1e2c, 0x1118, 0xa184, 0x0007, 0x002a,
+       0xa195, 0x0004, 0xa284, 0x0007, 0x0002, 0x23a7, 0x238d, 0x2390,
+       0x2393, 0x2398, 0x239a, 0x239e, 0x23a2, 0x080c, 0x6699, 0x00b8,
+       0x080c, 0x6774, 0x00a0, 0x080c, 0x6774, 0x080c, 0x6699, 0x0078,
+       0x0099, 0x0068, 0x080c, 0x6699, 0x0079, 0x0048, 0x080c, 0x6774,
+       0x0059, 0x0028, 0x080c, 0x6774, 0x080c, 0x6699, 0x0029, 0x002e,
+       0x001e, 0x000e, 0x012e, 0x0005, 0x6124, 0xd19c, 0x1904, 0x25bf,
+       0x080c, 0x574f, 0x0578, 0x7000, 0xa086, 0x0003, 0x0198, 0x6024,
+       0xa084, 0x1800, 0x0178, 0x080c, 0x5775, 0x0118, 0x080c, 0x5761,
+       0x1148, 0x6027, 0x0020, 0x6043, 0x0000, 0x2001, 0xaf9d, 0x2003,
+       0xaaaa, 0x0458, 0x080c, 0x5775, 0x15d0, 0x6024, 0xa084, 0x1800,
+       0x1108, 0x04a8, 0x2001, 0xaf9d, 0x2003, 0xaaaa, 0x2001, 0xaf9e,
+       0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0x080c, 0x569a,
+       0x0804, 0x25bf, 0xd1ac, 0x1518, 0x6024, 0xd0dc, 0x1170, 0xd0e4,
+       0x1188, 0xd0d4, 0x11a0, 0xd0cc, 0x0130, 0x7088, 0xa086, 0x0028,
+       0x1110, 0x080c, 0x58da, 0x0804, 0x25bf, 0x2001, 0xaf9e, 0x2003,
+       0x0000, 0x0048, 0x2001, 0xaf9e, 0x2003, 0x0002, 0x0020, 0x080c,
+       0x584d, 0x0804, 0x25bf, 0x080c, 0x597a, 0x0804, 0x25bf, 0xd1ac,
+       0x0904, 0x2507, 0x080c, 0x574f, 0x11d8, 0x6027, 0x0020, 0x0006,
+       0x0026, 0x0036, 0x080c, 0x576b, 0x1170, 0x2001, 0xaf9e, 0x2003,
+       0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0x080c, 0x569a, 0x003e,
+       0x002e, 0x000e, 0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x5726,
+       0x0016, 0x0046, 0x00c6, 0x644c, 0xa486, 0xf0f0, 0x1138, 0x2061,
+       0x0100, 0x644a, 0x6043, 0x0090, 0x6043, 0x0010, 0x74ca, 0xa48c,
+       0xff00, 0x7034, 0xd084, 0x0178, 0xa186, 0xf800, 0x1160, 0x7038,
+       0xd084, 0x1148, 0xc085, 0x703a, 0x0036, 0x2418, 0x2011, 0x8016,
+       0x080c, 0x3c5c, 0x003e, 0xa196, 0xff00, 0x05b8, 0x7050, 0xa084,
+       0x00ff, 0x810f, 0xa116, 0x0588, 0x7130, 0xd184, 0x1570, 0x2011,
+       0xad52, 0x2214, 0xd2ec, 0x0138, 0xc18d, 0x7132, 0x2011, 0xad52,
+       0x2214, 0xd2ac, 0x1510, 0x6240, 0xa294, 0x0010, 0x0130, 0x6248,
+       0xa294, 0xff00, 0xa296, 0xff00, 0x01c0, 0x7030, 0xd08c, 0x0904,
+       0x24d2, 0x7034, 0xd08c, 0x1140, 0x2001, 0xad0c, 0x200c, 0xd1ac,
+       0x1904, 0x24d2, 0xc1ad, 0x2102, 0x0036, 0x73c8, 0x2011, 0x8013,
+       0x080c, 0x3c5c, 0x003e, 0x0804, 0x24d2, 0x7034, 0xd08c, 0x1140,
+       0x2001, 0xad0c, 0x200c, 0xd1ac, 0x1904, 0x24d2, 0xc1ad, 0x2102,
+       0x0036, 0x73c8, 0x2011, 0x8013, 0x080c, 0x3c5c, 0x003e, 0x7130,
+       0xc185, 0x7132, 0x2011, 0xad52, 0x220c, 0xd1a4, 0x01d0, 0x0016,
+       0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x663f, 0x2019, 0x000e,
+       0x080c, 0xa8eb, 0xa484, 0x00ff, 0xa080, 0x2be6, 0x200d, 0xa18c,
+       0xff00, 0x810f, 0x8127, 0xa006, 0x2009, 0x000e, 0x080c, 0xa96c,
+       0x001e, 0xd1ac, 0x1148, 0x0016, 0x2009, 0x0000, 0x2019, 0x0004,
+       0x080c, 0x2aac, 0x001e, 0x0070, 0x0156, 0x20a9, 0x007f, 0x2009,
+       0x0000, 0x080c, 0x4cdc, 0x1110, 0x080c, 0x493a, 0x8108, 0x1f04,
+       0x24c9, 0x015e, 0x00ce, 0x004e, 0x2011, 0x0003, 0x080c, 0x7adf,
+       0x2011, 0x0002, 0x080c, 0x7ae9, 0x080c, 0x79e1, 0x080c, 0x6581,
+       0x0036, 0x2019, 0x0000, 0x080c, 0x7a64, 0x003e, 0x60e3, 0x0000,
+       0x001e, 0x2001, 0xad00, 0x2014, 0xa296, 0x0004, 0x1128, 0xd19c,
+       0x1118, 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0xad22,
+       0x2003, 0x0000, 0x6027, 0x0020, 0x080c, 0x5775, 0x1140, 0x0016,
+       0x2009, 0x07d0, 0x2011, 0x567b, 0x080c, 0x6593, 0x001e, 0xd194,
+       0x0904, 0x25bf, 0x0016, 0x6220, 0xd2b4, 0x0904, 0x2570, 0x080c,
+       0x6581, 0x080c, 0x7834, 0x6027, 0x0004, 0x00f6, 0x2019, 0xafd0,
+       0x2304, 0xa07d, 0x0570, 0x7804, 0xa086, 0x0032, 0x1550, 0x00d6,
+       0x00c6, 0x00e6, 0x2069, 0x0140, 0x618c, 0x6288, 0x7818, 0x608e,
+       0x7808, 0x608a, 0x6043, 0x0002, 0x2001, 0x0003, 0x8001, 0x1df0,
+       0x6043, 0x0000, 0x6803, 0x1000, 0x6803, 0x0000, 0x618e, 0x628a,
+       0x080c, 0x6b73, 0x080c, 0x6c50, 0x7810, 0x2070, 0x7037, 0x0103,
+       0x2f60, 0x080c, 0x8078, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e,
+       0x0005, 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000,
+       0x0120, 0x6803, 0x1000, 0x6803, 0x0000, 0x00de, 0x00c6, 0x2061,
+       0xafc7, 0x6028, 0xa09a, 0x00c8, 0x1238, 0x8000, 0x602a, 0x00ce,
+       0x080c, 0x7827, 0x0804, 0x25be, 0x2019, 0xafd0, 0x2304, 0xa065,
+       0x0120, 0x2009, 0x0027, 0x080c, 0x80a7, 0x00ce, 0x0804, 0x25be,
+       0xd2bc, 0x0904, 0x25be, 0x080c, 0x658e, 0x6014, 0xa084, 0x0184,
+       0xa085, 0x0010, 0x6016, 0x6027, 0x0004, 0x00d6, 0x2069, 0x0140,
+       0x6804, 0xa084, 0x4000, 0x0120, 0x6803, 0x1000, 0x6803, 0x0000,
+       0x00de, 0x00c6, 0x2061, 0xafc7, 0x6044, 0xa09a, 0x00c8, 0x12f0,
+       0x8000, 0x6046, 0x603c, 0x00ce, 0xa005, 0x0540, 0x2009, 0x07d0,
+       0x080c, 0x6586, 0xa080, 0x0007, 0x2004, 0xa086, 0x0006, 0x1138,
+       0x6114, 0xa18c, 0x0184, 0xa18d, 0x0012, 0x6116, 0x00b8, 0x6114,
+       0xa18c, 0x0184, 0xa18d, 0x0016, 0x6116, 0x0080, 0x0036, 0x2019,
+       0x0001, 0x080c, 0x7a64, 0x003e, 0x2019, 0xafd6, 0x2304, 0xa065,
+       0x0120, 0x2009, 0x004f, 0x080c, 0x80a7, 0x00ce, 0x001e, 0xd19c,
+       0x0904, 0x261a, 0x7034, 0xd0ac, 0x1560, 0x0016, 0x0156, 0x6027,
+       0x0008, 0x602f, 0x0020, 0x20a9, 0x0006, 0x1d04, 0x25cd, 0x2091,
+       0x6000, 0x1f04, 0x25cd, 0x602f, 0x0000, 0x6150, 0xa185, 0x1400,
+       0x6052, 0x20a9, 0x0366, 0x1d04, 0x25db, 0x2091, 0x6000, 0x6020,
+       0xd09c, 0x1130, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x0490,
+       0x080c, 0x2760, 0x1f04, 0x25db, 0x015e, 0x6152, 0x001e, 0x6027,
+       0x0008, 0x0016, 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x080c,
+       0x7adf, 0x2011, 0x0002, 0x080c, 0x7ae9, 0x080c, 0x79e1, 0x080c,
+       0x6581, 0x0036, 0x2019, 0x0000, 0x080c, 0x7a64, 0x003e, 0x60e3,
+       0x0000, 0x080c, 0xac8d, 0x080c, 0xaca8, 0xa085, 0x0001, 0x080c,
+       0x5793, 0x2001, 0xad00, 0x2003, 0x0004, 0x6027, 0x0008, 0x080c,
+       0x12cc, 0x001e, 0xa18c, 0xffd0, 0x6126, 0x0005, 0x0006, 0x0016,
+       0x0026, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2071, 0xad00,
+       0x71c0, 0x70c2, 0xa116, 0x01f0, 0x81ff, 0x0128, 0x2011, 0x8011,
+       0x080c, 0x3c5c, 0x00b8, 0x2011, 0x8012, 0x080c, 0x3c5c, 0x2001,
+       0xad71, 0x2004, 0xd0fc, 0x1170, 0x0036, 0x00c6, 0x080c, 0x26eb,
+       0x2061, 0x0100, 0x2019, 0x0028, 0x2009, 0x0000, 0x080c, 0x2aac,
+       0x00ce, 0x003e, 0x012e, 0x00fe, 0x00ee, 0x002e, 0x001e, 0x000e,
+       0x0005, 0x00c6, 0x00f6, 0x0006, 0x0026, 0x2061, 0x0100, 0xa190,
+       0x2664, 0x2205, 0x60f2, 0x2011, 0x2671, 0x2205, 0x60ee, 0x002e,
+       0x000e, 0x00fe, 0x00ce, 0x0005, 0x0840, 0x0840, 0x0840, 0x0580,
+       0x0420, 0x0348, 0x02c0, 0x0258, 0x0210, 0x01a8, 0x01a8, 0x01a8,
+       0x01a8, 0x0140, 0x00f8, 0x00d0, 0x00b0, 0x00a0, 0x2028, 0xa18c,
+       0x00ff, 0x2130, 0xa094, 0xff00, 0x1110, 0x81ff, 0x0118, 0x080c,
+       0x6278, 0x0038, 0xa080, 0x2be6, 0x200d, 0xa18c, 0xff00, 0x810f,
+       0xa006, 0x0005, 0xa080, 0x2be6, 0x200d, 0xa18c, 0x00ff, 0x0005,
+       0x00d6, 0x2069, 0x0140, 0x2001, 0xad14, 0x2003, 0x00ef, 0x20a9,
+       0x0010, 0xa006, 0x6852, 0x6856, 0x1f04, 0x269b, 0x00de, 0x0005,
+       0x0006, 0x00d6, 0x0026, 0x2069, 0x0140, 0x2001, 0xad14, 0x2102,
+       0x8114, 0x8214, 0x8214, 0x8214, 0x20a9, 0x0010, 0x6853, 0x0000,
+       0xa006, 0x82ff, 0x1128, 0xa184, 0x000f, 0xa080, 0xacae, 0x2005,
+       0x6856, 0x8211, 0x1f04, 0x26b0, 0x002e, 0x00de, 0x000e, 0x0005,
+       0x00c6, 0x2061, 0xad00, 0x6030, 0x0110, 0xc09d, 0x0008, 0xc09c,
+       0x6032, 0x00ce, 0x0005, 0x0156, 0x00d6, 0x0026, 0x0016, 0x0006,
+       0x2069, 0x0140, 0x6980, 0xa116, 0x0180, 0xa112, 0x1230, 0x8212,
+       0x8210, 0x22a8, 0x2001, 0x0402, 0x0018, 0x22a8, 0x2001, 0x0404,
+       0x680e, 0x1f04, 0x26e0, 0x680f, 0x0000, 0x000e, 0x001e, 0x002e,
+       0x00de, 0x015e, 0x0005, 0x2001, 0xad52, 0x2004, 0xd0c4, 0x0150,
+       0xd0a4, 0x0140, 0xa006, 0x0046, 0x2020, 0x2009, 0x002e, 0x080c,
+       0xa96c, 0x004e, 0x0005, 0x00f6, 0x0016, 0x0026, 0x2079, 0x0140,
+       0x78c4, 0xd0dc, 0x0548, 0xa084, 0x0700, 0xa08e, 0x0300, 0x1520,
+       0x2011, 0x0000, 0x2009, 0x0002, 0x2300, 0xa080, 0x0020, 0x2018,
+       0x2300, 0x080c, 0x6665, 0x2011, 0x0030, 0x2200, 0x8007, 0xa085,
+       0x004c, 0x78c2, 0x2009, 0x0204, 0x210c, 0x2200, 0xa100, 0x2009,
+       0x0138, 0x200a, 0x080c, 0x574f, 0x1118, 0x2009, 0xaf8e, 0x200a,
+       0x002e, 0x001e, 0x00fe, 0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126,
+       0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x2001, 0x0170, 0x200c,
+       0x8000, 0x2014, 0xa184, 0x0003, 0x0110, 0x0804, 0x1a6a, 0x002e,
+       0x001e, 0x000e, 0x012e, 0x0005, 0x0006, 0x2001, 0x0100, 0x2004,
+       0xa082, 0x0005, 0x000e, 0x0268, 0x2001, 0x0170, 0x200c, 0xa18c,
+       0x00ff, 0xa18e, 0x004c, 0x1128, 0x200c, 0xa18c, 0xff00, 0x810f,
+       0x0010, 0x2009, 0x0000, 0x2001, 0x0204, 0x2004, 0xa108, 0x0005,
+       0x0006, 0x0156, 0x00f6, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854,
+       0xd08c, 0x1110, 0x1f04, 0x2767, 0x00fe, 0x015e, 0x000e, 0x0005,
+       0x0016, 0x00c6, 0x0006, 0x2061, 0x0100, 0x6030, 0x0006, 0x6048,
+       0x0006, 0x60e4, 0x0006, 0x60e8, 0x0006, 0x6050, 0x0006, 0x60f0,
+       0x0006, 0x60ec, 0x0006, 0x600c, 0x0006, 0x6004, 0x0006, 0x6028,
+       0x0006, 0x60e0, 0x0006, 0x602f, 0x0100, 0x602f, 0x0000, 0xe000,
+       0xe000, 0xe000, 0xe000, 0x602f, 0x0040, 0x602f, 0x0000, 0x000e,
+       0x60e2, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e,
+       0x60ee, 0x000e, 0x60f2, 0x000e, 0x6052, 0x000e, 0x60ea, 0x000e,
+       0x60e6, 0x000e, 0x604a, 0x000e, 0x6032, 0x6036, 0x2008, 0x080c,
+       0x26a0, 0x000e, 0x00ce, 0x001e, 0x0005, 0x2845, 0x2849, 0x284d,
+       0x2853, 0x2859, 0x285f, 0x2865, 0x286d, 0x2875, 0x287b, 0x2881,
+       0x2889, 0x2891, 0x2899, 0x28a1, 0x28ab, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b7, 0x28b7, 0x28bc,
+       0x28bc, 0x28c3, 0x28c3, 0x28ca, 0x28ca, 0x28d3, 0x28d3, 0x28da,
+       0x28da, 0x28e3, 0x28e3, 0x28ec, 0x28ec, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+       0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x0106, 0x0006, 0x0804,
+       0x28f7, 0x0106, 0x0006, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c,
+       0x2373, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x0804,
+       0x28f7, 0x0106, 0x0006, 0x080c, 0x223d, 0x0804, 0x28f7, 0x0106,
+       0x0006, 0x080c, 0x223d, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c,
+       0x2373, 0x080c, 0x223d, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c,
+       0x2373, 0x080c, 0x223d, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c,
+       0x228f, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c, 0x228f, 0x0804,
+       0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x080c, 0x228f, 0x0804,
+       0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x080c, 0x228f, 0x0804,
+       0x28f7, 0x0106, 0x0006, 0x080c, 0x223d, 0x080c, 0x228f, 0x0804,
+       0x28f7, 0x0106, 0x0006, 0x080c, 0x223d, 0x080c, 0x228f, 0x0804,
+       0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x080c, 0x223d, 0x080c,
+       0x228f, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x080c,
+       0x223d, 0x080c, 0x228f, 0x0804, 0x28f7, 0xe000, 0x0cf0, 0x0106,
+       0x0006, 0x080c, 0x272f, 0x04d8, 0x0106, 0x0006, 0x080c, 0x272f,
+       0x080c, 0x2373, 0x04a0, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c,
+       0x223d, 0x0468, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c, 0x2373,
+       0x080c, 0x223d, 0x0420, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c,
+       0x228f, 0x00e8, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c, 0x2373,
+       0x080c, 0x228f, 0x00a0, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c,
+       0x223d, 0x080c, 0x228f, 0x0058, 0x0106, 0x0006, 0x080c, 0x272f,
+       0x080c, 0x2373, 0x080c, 0x223d, 0x080c, 0x228f, 0x0000, 0x000e,
+       0x010e, 0x000d, 0x00c6, 0x0026, 0x0046, 0x2021, 0x0000, 0x080c,
+       0x502d, 0x1904, 0x29d4, 0x72d0, 0x2001, 0xaf9d, 0x2004, 0xa005,
+       0x1110, 0xd29c, 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x29d4,
+       0x080c, 0x29d8, 0x0804, 0x29d4, 0x080c, 0x574f, 0x1120, 0x709b,
+       0xffff, 0x0804, 0x29d4, 0xd294, 0x0120, 0x709b, 0xffff, 0x0804,
+       0x29d4, 0x2001, 0xad14, 0x203c, 0x7284, 0xd284, 0x0904, 0x2976,
+       0xd28c, 0x1904, 0x2976, 0x0036, 0x7398, 0xa38e, 0xffff, 0x1110,
+       0x2019, 0x0001, 0x8314, 0xa2e0, 0xb3c0, 0x2c04, 0xa38c, 0x0001,
+       0x0120, 0xa084, 0xff00, 0x8007, 0x0010, 0xa084, 0x00ff, 0xa70e,
+       0x0560, 0xa08e, 0x0000, 0x0548, 0xa08e, 0x00ff, 0x1150, 0x7230,
+       0xd284, 0x1538, 0x7284, 0xc28d, 0x7286, 0x709b, 0xffff, 0x003e,
+       0x0428, 0x2009, 0x0000, 0x080c, 0x2676, 0x080c, 0x4c80, 0x11b8,
+       0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1150, 0x7030, 0xd08c,
+       0x0118, 0x6000, 0xd0bc, 0x0120, 0x080c, 0x29eb, 0x0140, 0x0028,
+       0x080c, 0x2b1a, 0x080c, 0x2a19, 0x0110, 0x8318, 0x0818, 0x739a,
+       0x0010, 0x709b, 0xffff, 0x003e, 0x0804, 0x29d4, 0xa780, 0x2be6,
+       0x203d, 0xa7bc, 0xff00, 0x873f, 0x2041, 0x007e, 0x7098, 0xa096,
+       0xffff, 0x1120, 0x2009, 0x0000, 0x28a8, 0x0050, 0xa812, 0x0220,
+       0x2008, 0xa802, 0x20a8, 0x0020, 0x709b, 0xffff, 0x0804, 0x29d4,
+       0x2700, 0x0156, 0x0016, 0xa106, 0x05a0, 0xc484, 0x080c, 0x4cdc,
+       0x0120, 0x080c, 0x4c80, 0x15a8, 0x0008, 0xc485, 0x6004, 0xa084,
+       0x00ff, 0xa086, 0x0006, 0x1130, 0x7030, 0xd08c, 0x01e8, 0x6000,
+       0xd0bc, 0x11d0, 0x7284, 0xd28c, 0x0188, 0x6004, 0xa084, 0x00ff,
+       0xa082, 0x0006, 0x02b0, 0xd484, 0x1118, 0x080c, 0x4c9f, 0x0028,
+       0x080c, 0x2b9c, 0x0170, 0x080c, 0x2bc9, 0x0058, 0x080c, 0x2b1a,
+       0x080c, 0x2a19, 0x0170, 0x0028, 0x080c, 0x2b9c, 0x0110, 0x0419,
+       0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, 0x2990, 0x709b, 0xffff,
+       0x0018, 0x001e, 0x015e, 0x719a, 0x004e, 0x002e, 0x00ce, 0x0005,
+       0x00c6, 0x0016, 0x709b, 0x0000, 0x2009, 0x007e, 0x080c, 0x4c80,
+       0x1138, 0x080c, 0x2b1a, 0x04a9, 0x0118, 0x70d0, 0xc0bd, 0x70d2,
+       0x001e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68,
+       0x2001, 0xad56, 0x2004, 0xa084, 0x00ff, 0x6842, 0x080c, 0x9807,
+       0x01d8, 0x2d00, 0x601a, 0x080c, 0x9956, 0x601f, 0x0001, 0x2001,
+       0x0000, 0x080c, 0x4c1e, 0x2001, 0x0000, 0x080c, 0x4c30, 0x0126,
+       0x2091, 0x8000, 0x7094, 0x8000, 0x7096, 0x012e, 0x2009, 0x0004,
+       0x080c, 0x80a7, 0xa085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e,
+       0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68, 0x2001, 0xad56,
+       0x2004, 0xa084, 0x00ff, 0x6842, 0x080c, 0x9807, 0x0550, 0x2d00,
+       0x601a, 0x6800, 0xc0c4, 0x6802, 0x68a0, 0xa086, 0x007e, 0x0140,
+       0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1110, 0x080c, 0x2ad9,
+       0x080c, 0x9956, 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x4c1e,
+       0x2001, 0x0002, 0x080c, 0x4c30, 0x0126, 0x2091, 0x8000, 0x7094,
+       0x8000, 0x7096, 0x012e, 0x2009, 0x0002, 0x080c, 0x80a7, 0xa085,
+       0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x0026,
+       0x2009, 0x0080, 0x080c, 0x4c80, 0x1120, 0x0031, 0x0110, 0x70d7,
+       0xffff, 0x002e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6,
+       0x2c68, 0x080c, 0x8022, 0x01d8, 0x2d00, 0x601a, 0x080c, 0x9956,
+       0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x2001, 0x0002,
+       0x080c, 0x4c30, 0x0126, 0x2091, 0x8000, 0x70d8, 0x8000, 0x70da,
+       0x012e, 0x2009, 0x0002, 0x080c, 0x80a7, 0xa085, 0x0001, 0x00ce,
+       0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091,
+       0x8000, 0x2009, 0x007f, 0x080c, 0x4c80, 0x1190, 0x2c68, 0x080c,
+       0x8022, 0x0170, 0x2d00, 0x601a, 0x6312, 0x601f, 0x0001, 0x620a,
+       0x080c, 0x9956, 0x2009, 0x0022, 0x080c, 0x80a7, 0xa085, 0x0001,
+       0x012e, 0x00de, 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0066, 0x0036,
+       0x0026, 0x080c, 0x68f3, 0x080c, 0x689d, 0x080c, 0x8a15, 0x2130,
+       0x81ff, 0x0128, 0x20a9, 0x007e, 0x2009, 0x0000, 0x0020, 0x20a9,
+       0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x4cdc, 0x1120, 0x080c,
+       0x4ecf, 0x080c, 0x493a, 0x001e, 0x8108, 0x1f04, 0x2ac3, 0x86ff,
+       0x1110, 0x080c, 0x11d4, 0x002e, 0x003e, 0x006e, 0x00ce, 0x00ee,
+       0x0005, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x6218, 0x2270,
+       0x72a0, 0x0026, 0x2019, 0x0029, 0x080c, 0x68e7, 0x0076, 0x2039,
+       0x0000, 0x080c, 0x681d, 0x2c08, 0x080c, 0xa712, 0x007e, 0x001e,
+       0x2e60, 0x080c, 0x4ecf, 0x6210, 0x6314, 0x080c, 0x493a, 0x6212,
+       0x6316, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6,
+       0x0006, 0x6018, 0xa080, 0x0028, 0x2004, 0xa086, 0x0080, 0x0150,
+       0x2071, 0xad00, 0x7094, 0xa005, 0x0110, 0x8001, 0x7096, 0x000e,
+       0x00ee, 0x0005, 0x2071, 0xad00, 0x70d8, 0xa005, 0x0dc0, 0x8001,
+       0x70da, 0x0ca8, 0x6000, 0xc08c, 0x6002, 0x0005, 0x00f6, 0x00e6,
+       0x00c6, 0x0036, 0x0026, 0x0016, 0x0156, 0x2178, 0x81ff, 0x1118,
+       0x20a9, 0x0001, 0x0098, 0x2001, 0xad52, 0x2004, 0xd0c4, 0x0150,
+       0xd0a4, 0x0140, 0xa006, 0x0046, 0x2020, 0x2009, 0x002d, 0x080c,
+       0xa96c, 0x004e, 0x20a9, 0x00ff, 0x2011, 0x0000, 0x0026, 0xa28e,
+       0x007e, 0x05c8, 0xa28e, 0x007f, 0x05b0, 0xa28e, 0x0080, 0x0598,
+       0xa288, 0xae34, 0x210c, 0x81ff, 0x0570, 0x8fff, 0x05c1, 0x00c6,
+       0x2160, 0x2001, 0x0001, 0x080c, 0x5037, 0x00ce, 0x2019, 0x0029,
+       0x080c, 0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x00c6,
+       0x0026, 0x2160, 0x6204, 0xa294, 0x00ff, 0xa286, 0x0006, 0x1118,
+       0x6007, 0x0404, 0x0028, 0x2001, 0x0004, 0x8007, 0xa215, 0x6206,
+       0x002e, 0x00ce, 0x0016, 0x2c08, 0x080c, 0xa712, 0x001e, 0x007e,
+       0x2160, 0x080c, 0x4ecf, 0x002e, 0x8210, 0x1f04, 0x2b3e, 0x015e,
+       0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0046,
+       0x0026, 0x0016, 0x2001, 0xad52, 0x2004, 0xd0c4, 0x0148, 0xd0a4,
+       0x0138, 0xa006, 0x2220, 0x8427, 0x2009, 0x0029, 0x080c, 0xa96c,
+       0x001e, 0x002e, 0x004e, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6,
+       0x7284, 0x82ff, 0x01f8, 0x2011, 0xad52, 0x2214, 0xd2ac, 0x11d0,
+       0x2100, 0x080c, 0x268a, 0x81ff, 0x01b8, 0x2019, 0x0001, 0x8314,
+       0xa2e0, 0xb3c0, 0x2c04, 0xd384, 0x0120, 0xa084, 0xff00, 0x8007,
+       0x0010, 0xa084, 0x00ff, 0xa116, 0x0138, 0xa096, 0x00ff, 0x0110,
+       0x8318, 0x0c68, 0xa085, 0x0001, 0x00ce, 0x003e, 0x002e, 0x001e,
+       0x0005, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0xa180, 0xae34,
+       0x2004, 0xa065, 0x0178, 0x0016, 0x00c6, 0x080c, 0x9807, 0x001e,
+       0x090c, 0x14f6, 0x611a, 0x080c, 0x2ad9, 0x080c, 0x8078, 0x001e,
+       0x080c, 0x4c9f, 0x012e, 0x00ce, 0x001e, 0x0005, 0x7eef, 0x7de8,
+       0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc, 0x80da, 0x7ad9, 0x80d6,
+       0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1, 0x79ce, 0x78cd, 0x80cc,
+       0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6, 0x77c5, 0x76c3, 0x80bc,
+       0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4, 0x72b3, 0x80b2, 0x80b1,
+       0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa, 0x6ea9, 0x80a7, 0x6da6,
+       0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d, 0x809b, 0x8098, 0x6797,
+       0x6690, 0x658f, 0x6488, 0x6384, 0x6282, 0x8081, 0x8080, 0x617c,
+       0x607a, 0x8079, 0x5f76, 0x8075, 0x8074, 0x8073, 0x8072, 0x8071,
+       0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a, 0x5b69, 0x8067, 0x5a66,
+       0x5965, 0x5863, 0x575c, 0x565a, 0x5559, 0x8056, 0x8055, 0x5454,
+       0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d, 0x804c, 0x804b, 0x4e4a,
+       0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043, 0x803c, 0x803a, 0x8039,
+       0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932, 0x4831, 0x802e, 0x472d,
+       0x462c, 0x452b, 0x442a, 0x4329, 0x4227, 0x8026, 0x8025, 0x4123,
+       0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18, 0x8017, 0x8010, 0x3b0f,
+       0x3a08, 0x8004, 0x3902, 0x8001, 0x8000, 0x8000, 0x3800, 0x3700,
+       0x3600, 0x8000, 0x3500, 0x8000, 0x8000, 0x8000, 0x3400, 0x8000,
+       0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3300, 0x3200, 0x8000,
+       0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3100, 0x3000, 0x8000,
+       0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00, 0x2c00, 0x8000, 0x8000,
+       0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900, 0x2800, 0x8000, 0x2700,
+       0x2600, 0x2500, 0x2400, 0x2300, 0x2200, 0x8000, 0x8000, 0x2100,
+       0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, 0x8000, 0x8000, 0x1b00,
+       0x1a00, 0x8000, 0x1900, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+       0x8000, 0x1800, 0x8000, 0x1700, 0x1600, 0x1500, 0x8000, 0x1400,
+       0x1300, 0x1200, 0x1100, 0x1000, 0x0f00, 0x8000, 0x8000, 0x0e00,
+       0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900, 0x8000, 0x8000, 0x0800,
+       0x0700, 0x8000, 0x0600, 0x8000, 0x8000, 0x8000, 0x0500, 0x0400,
+       0x0300, 0x8000, 0x0200, 0x8000, 0x8000, 0x8000, 0x0100, 0x8000,
+       0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x8000, 0x8000,
+       0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+       0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x2071, 0xad81,
+       0x7003, 0x0002, 0xa006, 0x7012, 0x7016, 0x703a, 0x703e, 0x7033,
+       0xad91, 0x7037, 0xad91, 0x7007, 0x0001, 0x2061, 0xadd1, 0x6003,
+       0x0002, 0x0005, 0x1004, 0x2d0c, 0x0e04, 0x2d0c, 0x2071, 0xad81,
+       0x2b78, 0x7818, 0xd084, 0x1140, 0x2a60, 0x7820, 0xa08e, 0x0069,
+       0x1904, 0x2df1, 0x0804, 0x2d8a, 0x0005, 0x2071, 0xad81, 0x7004,
+       0x0002, 0x2d15, 0x2d16, 0x2d1f, 0x2d30, 0x0005, 0x1004, 0x2d1e,
+       0x0e04, 0x2d1e, 0x2b78, 0x7818, 0xd084, 0x01e8, 0x0005, 0x2b78,
+       0x2061, 0xadd1, 0x6008, 0xa08e, 0x0100, 0x0128, 0xa086, 0x0200,
+       0x0904, 0x2deb, 0x0005, 0x7014, 0x2068, 0x2a60, 0x7018, 0x0807,
+       0x7010, 0x2068, 0x6834, 0xa086, 0x0103, 0x0108, 0x0005, 0x2a60,
+       0x2b78, 0x7018, 0x0807, 0x2a60, 0x7820, 0xa08a, 0x0040, 0x1210,
+       0x61c0, 0x0042, 0x2100, 0xa08a, 0x003f, 0x1a04, 0x2de8, 0x61c0,
+       0x0804, 0x2d8a, 0x2dcc, 0x2df7, 0x2dff, 0x2e03, 0x2e0b, 0x2e11,
+       0x2e15, 0x2e21, 0x2e24, 0x2e2e, 0x2e31, 0x2de8, 0x2de8, 0x2de8,
+       0x2e34, 0x2de8, 0x2e43, 0x2e5a, 0x2e71, 0x2ee8, 0x2eed, 0x2f16,
+       0x2f67, 0x2f78, 0x2f96, 0x2fcd, 0x2fd7, 0x2fe4, 0x2ff7, 0x3018,
+       0x3021, 0x3057, 0x305d, 0x2de8, 0x3086, 0x2de8, 0x2de8, 0x2de8,
+       0x2de8, 0x2de8, 0x308d, 0x3097, 0x2de8, 0x2de8, 0x2de8, 0x2de8,
+       0x2de8, 0x2de8, 0x2de8, 0x2de8, 0x309f, 0x2de8, 0x2de8, 0x2de8,
+       0x2de8, 0x2de8, 0x30b1, 0x30b9, 0x2de8, 0x2de8, 0x2de8, 0x2de8,
+       0x2de8, 0x2de8, 0x0002, 0x30cb, 0x311f, 0x317a, 0x318a, 0x2de8,
+       0x31a4, 0x35cb, 0x3fbb, 0x2de8, 0x2de8, 0x2de8, 0x2de8, 0x2de8,
+       0x2de8, 0x2de8, 0x2de8, 0x2e2e, 0x2e31, 0x35cd, 0x2de8, 0x35da,
+       0x403c, 0x4097, 0x40fb, 0x2de8, 0x415a, 0x4180, 0x419f, 0x2de8,
+       0x2de8, 0x2de8, 0x2de8, 0x35de, 0x376b, 0x3785, 0x37a3, 0x3804,
+       0x3858, 0x3863, 0x389a, 0x38a9, 0x38b8, 0x38bb, 0x38de, 0x3928,
+       0x398e, 0x399b, 0x3a9c, 0x3bb3, 0x3bdc, 0x3cda, 0x3cfc, 0x3d08,
+       0x3d41, 0x3e05, 0x2de8, 0x2de8, 0x2de8, 0x2de8, 0x3e6d, 0x3e88,
+       0x3efa, 0x3fac, 0x713c, 0x0000, 0x2021, 0x4000, 0x080c, 0x3c39,
+       0x0126, 0x2091, 0x8000, 0x0e04, 0x2dd8, 0x7818, 0xd084, 0x0110,
+       0x012e, 0x0cb0, 0x7c22, 0x7926, 0x7a2a, 0x7b2e, 0x781b, 0x0001,
+       0x2091, 0x4080, 0x7007, 0x0001, 0x2091, 0x5000, 0x012e, 0x0005,
+       0x2021, 0x4001, 0x0c18, 0x2021, 0x4002, 0x0c00, 0x2021, 0x4003,
+       0x08e8, 0x2021, 0x4005, 0x08d0, 0x2021, 0x4006, 0x08b8, 0xa02e,
+       0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0804, 0x3c46, 0x7823,
+       0x0004, 0x7824, 0x0807, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824,
+       0x7930, 0x0804, 0x3c49, 0x7924, 0x7828, 0x2114, 0x200a, 0x0804,
+       0x2dcc, 0x7924, 0x2114, 0x0804, 0x2dcc, 0x2099, 0x0009, 0x20a1,
+       0x0009, 0x20a9, 0x0007, 0x53a3, 0x7924, 0x7a28, 0x7b2c, 0x0804,
+       0x2dcc, 0x7824, 0x2060, 0x0090, 0x2009, 0x0002, 0x2011, 0x0001,
+       0x2019, 0x001b, 0x783b, 0x0017, 0x0804, 0x2dcc, 0x7d38, 0x7c3c,
+       0x0840, 0x7d38, 0x7c3c, 0x0888, 0x2061, 0x1000, 0xe10c, 0xa006,
+       0x2c15, 0xa200, 0x8c60, 0x8109, 0x1dd8, 0x2010, 0xa005, 0x0904,
+       0x2dcc, 0x0804, 0x2dee, 0x2069, 0xad51, 0x7824, 0x7930, 0xa11a,
+       0x1a04, 0x2df4, 0x8019, 0x0904, 0x2df4, 0x684a, 0x6942, 0x782c,
+       0x6852, 0x7828, 0x6856, 0xa006, 0x685a, 0x685e, 0x080c, 0x5a1c,
+       0x0804, 0x2dcc, 0x2069, 0xad51, 0x7824, 0x7934, 0xa11a, 0x1a04,
+       0x2df4, 0x8019, 0x0904, 0x2df4, 0x684e, 0x6946, 0x782c, 0x6862,
+       0x7828, 0x6866, 0xa006, 0x686a, 0x686e, 0x080c, 0x50d9, 0x0804,
+       0x2dcc, 0xa02e, 0x2520, 0x81ff, 0x1904, 0x2df1, 0x7924, 0x7b28,
+       0x7a2c, 0x20a9, 0x0005, 0x20a1, 0xad88, 0x41a1, 0x080c, 0x3c05,
+       0x0904, 0x2df1, 0x2009, 0x0020, 0x080c, 0x3c46, 0x701b, 0x2e89,
+       0x0005, 0x6834, 0x2008, 0xa084, 0x00ff, 0xa096, 0x0011, 0x0120,
+       0xa096, 0x0019, 0x1904, 0x2df1, 0x810f, 0xa18c, 0x00ff, 0x0904,
+       0x2df1, 0x710e, 0x700c, 0x8001, 0x0528, 0x700e, 0x080c, 0x3c05,
+       0x0904, 0x2df1, 0x2009, 0x0020, 0x2061, 0xadd1, 0x6224, 0x6328,
+       0x642c, 0x6530, 0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000,
+       0xa5a9, 0x0000, 0x080c, 0x3c46, 0x701b, 0x2eb7, 0x0005, 0x6834,
+       0xa084, 0x00ff, 0xa096, 0x0002, 0x0120, 0xa096, 0x000a, 0x1904,
+       0x2df1, 0x08c0, 0x7010, 0x2068, 0x6838, 0xc0fd, 0x683a, 0x080c,
+       0x4b7c, 0x1128, 0x7007, 0x0003, 0x701b, 0x2ed1, 0x0005, 0x080c,
+       0x51df, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x2099, 0xad88,
+       0x530a, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9,
+       0x0000, 0xad80, 0x000d, 0x2009, 0x0020, 0x012e, 0x0804, 0x3c49,
+       0x61a8, 0x7824, 0x60aa, 0x0804, 0x2dcc, 0x2091, 0x8000, 0x7823,
+       0x4000, 0x7827, 0x4953, 0x782b, 0x5020, 0x782f, 0x2020, 0x2009,
+       0x017f, 0x2104, 0x7832, 0x3f00, 0x7836, 0x2061, 0x0100, 0x6200,
+       0x2061, 0x0200, 0x603c, 0x8007, 0xa205, 0x783a, 0x2009, 0x04fd,
+       0x2104, 0x783e, 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080,
+       0x2071, 0x0010, 0x20c1, 0x00f0, 0x0804, 0x0427, 0x81ff, 0x1904,
+       0x2df1, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x080c, 0x4cdc, 0x1904,
+       0x2df4, 0x7e38, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0210, 0x0804,
+       0x2df4, 0x7c28, 0x7d2c, 0x080c, 0x4e96, 0xd28c, 0x1118, 0x080c,
+       0x4e41, 0x0010, 0x080c, 0x4e6f, 0x1518, 0x2061, 0xb400, 0x0126,
+       0x2091, 0x8000, 0x6000, 0xa086, 0x0000, 0x0148, 0x6010, 0xa06d,
+       0x0130, 0x683c, 0xa406, 0x1118, 0x6840, 0xa506, 0x0150, 0x012e,
+       0xace0, 0x0018, 0x2001, 0xad16, 0x2004, 0xac02, 0x1a04, 0x2df1,
+       0x0c30, 0x080c, 0x929c, 0x012e, 0x0904, 0x2df1, 0x0804, 0x2dcc,
+       0xa00e, 0x2001, 0x0005, 0x080c, 0x51df, 0x0126, 0x2091, 0x8000,
+       0x080c, 0x9803, 0x080c, 0x510c, 0x012e, 0x0804, 0x2dcc, 0x81ff,
+       0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4d96,
+       0x0904, 0x2df1, 0x080c, 0x4ea2, 0x0904, 0x2df1, 0x0804, 0x2dcc,
+       0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x080c,
+       0x4f0d, 0x0904, 0x2df1, 0x2019, 0x0005, 0x080c, 0x4ebd, 0x0904,
+       0x2df1, 0x7828, 0xa08a, 0x1000, 0x1a04, 0x2df4, 0x8003, 0x800b,
+       0x810b, 0xa108, 0x080c, 0x6519, 0x0804, 0x2dcc, 0x0126, 0x2091,
+       0x8000, 0x81ff, 0x0118, 0x2009, 0x0001, 0x0448, 0x2029, 0x00ff,
+       0x644c, 0x2400, 0xa506, 0x01f0, 0x2508, 0x080c, 0x4cdc, 0x11d0,
+       0x080c, 0x4f0d, 0x1128, 0x2009, 0x0002, 0x62b0, 0x2518, 0x00b8,
+       0x2019, 0x0004, 0x080c, 0x4ebd, 0x1118, 0x2009, 0x0006, 0x0078,
+       0x7824, 0xa08a, 0x1000, 0x1270, 0x8003, 0x800b, 0x810b, 0xa108,
+       0x080c, 0x6519, 0x8529, 0x1ae8, 0x012e, 0x0804, 0x2dcc, 0x012e,
+       0x0804, 0x2df1, 0x012e, 0x0804, 0x2df4, 0x080c, 0x3c1a, 0x0904,
+       0x2df4, 0x080c, 0x4dfc, 0x080c, 0x4e96, 0x0804, 0x2dcc, 0x81ff,
+       0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4ded,
+       0x080c, 0x4e96, 0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x080c,
+       0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4e71, 0x0904, 0x2df1, 0x080c,
+       0x4bc0, 0x080c, 0x4e3a, 0x080c, 0x4e96, 0x0804, 0x2dcc, 0x080c,
+       0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4d96, 0x0904, 0x2df1, 0x62a0,
+       0x2019, 0x0005, 0x00c6, 0x080c, 0x4ecf, 0x2061, 0x0000, 0x080c,
+       0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x2009, 0x0000,
+       0x080c, 0xa712, 0x007e, 0x00ce, 0x080c, 0x4e96, 0x0804, 0x2dcc,
+       0x080c, 0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4e96, 0x2208, 0x0804,
+       0x2dcc, 0x0156, 0x00d6, 0x00e6, 0x2069, 0xae13, 0x6810, 0x6914,
+       0xa10a, 0x1210, 0x2009, 0x0000, 0x6816, 0x2011, 0x0000, 0x2019,
+       0x0000, 0x20a9, 0x007e, 0x2069, 0xae34, 0x2d04, 0xa075, 0x0130,
+       0x704c, 0x0071, 0xa210, 0x7080, 0x0059, 0xa318, 0x8d68, 0x1f04,
+       0x3035, 0x2300, 0xa218, 0x00ee, 0x00de, 0x015e, 0x0804, 0x2dcc,
+       0x00f6, 0x0016, 0xa07d, 0x0140, 0x2001, 0x0000, 0x8000, 0x2f0c,
+       0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069,
+       0xae13, 0x6910, 0x62ac, 0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1,
+       0x614c, 0xa190, 0x2be6, 0x2215, 0xa294, 0x00ff, 0x636c, 0x83ff,
+       0x0108, 0x6270, 0x67d0, 0xd79c, 0x0118, 0x2031, 0x0001, 0x0090,
+       0xd7ac, 0x0118, 0x2031, 0x0003, 0x0068, 0xd7a4, 0x0118, 0x2031,
+       0x0002, 0x0040, 0x080c, 0x574f, 0x1118, 0x2031, 0x0004, 0x0010,
+       0x2031, 0x0000, 0x7e3a, 0x7f3e, 0x0804, 0x2dcc, 0x613c, 0x6240,
+       0x2019, 0xafa3, 0x231c, 0x0804, 0x2dcc, 0x0126, 0x2091, 0x8000,
+       0x6134, 0xa006, 0x2010, 0x2018, 0x012e, 0x0804, 0x2dcc, 0x080c,
+       0x3c2a, 0x0904, 0x2df4, 0x6244, 0x6338, 0x0804, 0x2dcc, 0x613c,
+       0x6240, 0x7824, 0x603e, 0x7b28, 0x6342, 0x2069, 0xad51, 0x831f,
+       0xa305, 0x6816, 0x782c, 0x2069, 0xafa3, 0x2d1c, 0x206a, 0x0804,
+       0x2dcc, 0x0126, 0x2091, 0x8000, 0x7824, 0x6036, 0x012e, 0x0804,
+       0x2dcc, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x7828, 0xa00d, 0x0904,
+       0x2df4, 0x782c, 0xa005, 0x0904, 0x2df4, 0x6244, 0x6146, 0x6338,
+       0x603a, 0x0804, 0x2dcc, 0x2001, 0xad00, 0x2004, 0xa086, 0x0003,
+       0x1904, 0x2df1, 0x00c6, 0x2061, 0x0100, 0x7924, 0x810f, 0xa18c,
+       0x00ff, 0xa196, 0x00ff, 0x1130, 0x2001, 0xad14, 0x2004, 0xa085,
+       0xff00, 0x0078, 0xa182, 0x007f, 0x16a0, 0xa188, 0x2be6, 0x210d,
+       0xa18c, 0x00ff, 0x2001, 0xad14, 0x2004, 0xa116, 0x0550, 0x810f,
+       0xa105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c, 0x8022, 0x000e,
+       0x01e0, 0x601a, 0x600b, 0xbc09, 0x601f, 0x0001, 0x080c, 0x3c05,
+       0x01d8, 0x6837, 0x0000, 0x7007, 0x0003, 0x6833, 0x0000, 0x6838,
+       0xc0fd, 0x683a, 0x701b, 0x3173, 0x2d00, 0x6012, 0x2009, 0x0032,
+       0x080c, 0x80a7, 0x012e, 0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804,
+       0x2df1, 0x00ce, 0x0804, 0x2df4, 0x080c, 0x8078, 0x0cb0, 0x2001,
+       0xad00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2df1, 0x00c6, 0x2061,
+       0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196, 0x00ff, 0x1130,
+       0x2001, 0xad14, 0x2004, 0xa085, 0xff00, 0x0078, 0xa182, 0x007f,
+       0x16a0, 0xa188, 0x2be6, 0x210d, 0xa18c, 0x00ff, 0x2001, 0xad14,
+       0x2004, 0xa116, 0x0550, 0x810f, 0xa105, 0x0126, 0x2091, 0x8000,
+       0x0006, 0x080c, 0x8022, 0x000e, 0x01e0, 0x601a, 0x600b, 0xbc05,
+       0x601f, 0x0001, 0x080c, 0x3c05, 0x01d8, 0x6837, 0x0000, 0x7007,
+       0x0003, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x701b, 0x3173,
+       0x2d00, 0x6012, 0x2009, 0x0032, 0x080c, 0x80a7, 0x012e, 0x00ce,
+       0x0005, 0x012e, 0x00ce, 0x0804, 0x2df1, 0x00ce, 0x0804, 0x2df4,
+       0x080c, 0x8078, 0x0cb0, 0x6830, 0xa086, 0x0100, 0x0904, 0x2df1,
+       0x0804, 0x2dcc, 0x2061, 0xb048, 0x0126, 0x2091, 0x8000, 0x6000,
+       0xd084, 0x0128, 0x6104, 0x6208, 0x012e, 0x0804, 0x2dcc, 0x012e,
+       0x0804, 0x2df4, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x574f, 0x0904,
+       0x2df1, 0x0126, 0x2091, 0x8000, 0x6244, 0x6064, 0xa202, 0x0248,
+       0xa085, 0x0001, 0x080c, 0x26c0, 0x080c, 0x436e, 0x012e, 0x0804,
+       0x2dcc, 0x012e, 0x0804, 0x2df4, 0x0126, 0x2091, 0x8000, 0x7824,
+       0xa084, 0x0007, 0x0002, 0x31b6, 0x31bf, 0x31c6, 0x31b3, 0x31b3,
+       0x31b3, 0x31b3, 0x31b3, 0x012e, 0x0804, 0x2df4, 0x2009, 0x0114,
+       0x2104, 0xa085, 0x0800, 0x200a, 0x080c, 0x332f, 0x0070, 0x2009,
+       0x010b, 0x200b, 0x0010, 0x080c, 0x332f, 0x0038, 0x81ff, 0x0128,
+       0x012e, 0x2021, 0x400b, 0x0804, 0x2dce, 0x0086, 0x0096, 0x00a6,
+       0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2009, 0x0101, 0x210c,
+       0x0016, 0x2001, 0x0138, 0x200c, 0x2003, 0x0001, 0x0016, 0x2001,
+       0x007a, 0x2034, 0x2001, 0x007b, 0x202c, 0xa006, 0x2048, 0x2050,
+       0x2058, 0x080c, 0x3570, 0x080c, 0x34da, 0xa03e, 0x2720, 0x00f6,
+       0x00e6, 0x00c6, 0x2d60, 0x2071, 0xb01e, 0x2079, 0x0020, 0x00d6,
+       0x2069, 0x0000, 0x6824, 0xd0b4, 0x0140, 0x2001, 0x007d, 0x2004,
+       0x783e, 0x2001, 0x007c, 0x2004, 0x783a, 0x00de, 0x2011, 0x0001,
+       0x080c, 0x3486, 0x080c, 0x3486, 0x00ce, 0x00ee, 0x00fe, 0x080c,
+       0x33d5, 0x080c, 0x34ae, 0x080c, 0x342b, 0x080c, 0x3394, 0x080c,
+       0x33c5, 0x00f6, 0x2079, 0x0100, 0x7824, 0xd094, 0x0530, 0x7814,
+       0xa084, 0x0184, 0xa085, 0x0010, 0x7816, 0x2079, 0x0140, 0x080c,
+       0x330d, 0x1110, 0x00fe, 0x0430, 0x7804, 0xd0dc, 0x0dc0, 0x2079,
+       0x0100, 0x7827, 0x0086, 0x7814, 0xa084, 0x0184, 0xa085, 0x0032,
+       0x7816, 0x080c, 0x330d, 0x1110, 0x00fe, 0x00a0, 0x7824, 0xd0bc,
+       0x0dc0, 0x7827, 0x0080, 0xa026, 0x7c16, 0x7824, 0xd0ac, 0x0130,
+       0x8b58, 0x080c, 0x3317, 0x00fe, 0x0804, 0x32d7, 0x00fe, 0x080c,
+       0x330d, 0x1150, 0x8948, 0x2001, 0x007a, 0x2602, 0x2001, 0x007b,
+       0x2502, 0x080c, 0x3317, 0x0088, 0x87ff, 0x0140, 0x2001, 0x0201,
+       0x2004, 0xa005, 0x1904, 0x3211, 0x8739, 0x0038, 0x2001, 0xaffd,
+       0x2004, 0xa086, 0x0000, 0x1904, 0x3211, 0x2001, 0x0033, 0x2003,
+       0x00f6, 0x8631, 0x1208, 0x8529, 0x2500, 0xa605, 0x0904, 0x32d7,
+       0x7824, 0xd0bc, 0x0128, 0x2900, 0xaa05, 0xab05, 0x1904, 0x32d7,
+       0x6033, 0x000d, 0x2001, 0x0030, 0x2003, 0x0004, 0x7824, 0xd0ac,
+       0x1148, 0x2001, 0xaffd, 0x2003, 0x0003, 0x2001, 0x0030, 0x2003,
+       0x0009, 0x0040, 0x6027, 0x0001, 0x2001, 0x0075, 0x2004, 0xa005,
+       0x0108, 0x6026, 0x2c00, 0x601a, 0x20e1, 0x9040, 0x2d00, 0x681a,
+       0x6833, 0x000d, 0x7824, 0xd0a4, 0x1180, 0x6827, 0x0000, 0x00c6,
+       0x20a9, 0x0004, 0x2061, 0x0020, 0x6003, 0x0008, 0x2001, 0x0203,
+       0x2004, 0x1f04, 0x32ac, 0x00ce, 0x0040, 0x6827, 0x0001, 0x2001,
+       0x0074, 0x2004, 0xa005, 0x0108, 0x6826, 0x00f6, 0x00c6, 0x2079,
+       0x0100, 0x2061, 0x0020, 0x7827, 0x0002, 0x2001, 0x0072, 0x2004,
+       0xa084, 0xfff8, 0x601a, 0x0006, 0x2001, 0x0073, 0x2004, 0x601e,
+       0x78c6, 0x000e, 0x78ca, 0x00ce, 0x00fe, 0x0804, 0x31ef, 0x2061,
+       0x0100, 0x6027, 0x0002, 0x001e, 0x61e2, 0x001e, 0x6106, 0x7824,
+       0xa084, 0x0003, 0xa086, 0x0002, 0x0188, 0x20e1, 0x9028, 0x6050,
+       0xa084, 0xf7ef, 0x6052, 0x602f, 0x0000, 0x602c, 0xc0ac, 0x602e,
+       0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, 0x0010, 0x2908, 0x2a10,
+       0x2b18, 0x2b00, 0xaa05, 0xa905, 0x00fe, 0x00ee, 0x00de, 0x00ce,
+       0x00be, 0x00ae, 0x009e, 0x008e, 0x1118, 0x012e, 0x0804, 0x2dcc,
+       0x012e, 0x2021, 0x400c, 0x0804, 0x2dce, 0xa085, 0x0001, 0x1d04,
+       0x3316, 0x2091, 0x6000, 0x8420, 0xa486, 0x0064, 0x0005, 0x2001,
+       0x0105, 0x2003, 0x0010, 0x2001, 0x0030, 0x2003, 0x0004, 0x2001,
+       0x0020, 0x2003, 0x0004, 0x2001, 0xaffd, 0x2003, 0x0000, 0x2001,
+       0xb01e, 0x2003, 0x0000, 0x20e1, 0xf000, 0xa026, 0x0005, 0x00f6,
+       0x2079, 0x0100, 0x2001, 0xad14, 0x200c, 0x7932, 0x7936, 0x080c,
+       0x26a0, 0x7850, 0xa084, 0x0980, 0xa085, 0x0030, 0x7852, 0x2019,
+       0x01f4, 0x8319, 0x1df0, 0xa084, 0x0980, 0x7852, 0x782c, 0xc0ad,
+       0x782e, 0x20a9, 0x0046, 0x1d04, 0x334b, 0x2091, 0x6000, 0x1f04,
+       0x334b, 0x7850, 0xa085, 0x0400, 0x7852, 0x2001, 0x0009, 0x2004,
+       0xa084, 0x0003, 0xa086, 0x0001, 0x1118, 0x782c, 0xc0ac, 0x782e,
+       0x784b, 0xf7f7, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, 0x000e,
+       0xe000, 0x1f04, 0x3368, 0x7850, 0xa085, 0x1400, 0x7852, 0x2019,
+       0x61a8, 0x7854, 0xe000, 0xe000, 0xd08c, 0x1110, 0x8319, 0x1dc8,
+       0x7827, 0x0048, 0x7850, 0xa085, 0x0400, 0x7852, 0x7843, 0x0040,
+       0x2019, 0x01f4, 0xe000, 0xe000, 0x8319, 0x1de0, 0x2001, 0x0140,
+       0x2003, 0x0100, 0x7827, 0x0020, 0x7843, 0x0000, 0x2003, 0x0000,
+       0x7827, 0x0048, 0x00fe, 0x0005, 0x7824, 0xd0ac, 0x11c8, 0x00f6,
+       0x00e6, 0x2071, 0xaffd, 0x2079, 0x0030, 0x2001, 0x0201, 0x2004,
+       0xa005, 0x0160, 0x7000, 0xa086, 0x0000, 0x1140, 0x0051, 0xd0bc,
+       0x0108, 0x8738, 0x7003, 0x0003, 0x7803, 0x0019, 0x00ee, 0x00fe,
+       0x0005, 0x780c, 0xa08c, 0x0070, 0x0178, 0x2009, 0x007a, 0x260a,
+       0x2009, 0x007b, 0x250a, 0xd0b4, 0x0108, 0x8a50, 0xd0ac, 0x0108,
+       0x8948, 0xd0a4, 0x0108, 0x8b58, 0x0005, 0x00f6, 0x2079, 0x0200,
+       0x781c, 0xd084, 0x0140, 0x20e1, 0x0007, 0x20e1, 0x2000, 0x2001,
+       0x020a, 0x2004, 0x0ca8, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0100,
+       0x2009, 0xad14, 0x210c, 0x716e, 0x7063, 0x0100, 0x7166, 0x719e,
+       0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008, 0x7078, 0xa080,
+       0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087, 0xaaaa, 0xa006,
+       0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036, 0x70af, 0x95d5,
+       0x7027, 0x0080, 0x7014, 0xa084, 0x0184, 0xa085, 0x0032, 0x7016,
+       0x080c, 0x34ae, 0x080c, 0x330d, 0x1110, 0x8421, 0x0028, 0x7024,
+       0xd0bc, 0x0db0, 0x7027, 0x0080, 0x00f6, 0x00e6, 0x2071, 0xaffd,
+       0x2079, 0x0030, 0x00d6, 0x2069, 0x0000, 0x6824, 0xd0b4, 0x0120,
+       0x683c, 0x783e, 0x6838, 0x783a, 0x00de, 0x2011, 0x0011, 0x080c,
+       0x3486, 0x2011, 0x0001, 0x080c, 0x3486, 0x00ee, 0x00fe, 0x7017,
+       0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, 0xaffd, 0x2079,
+       0x0030, 0x7904, 0xd1fc, 0x0904, 0x3483, 0x7803, 0x0002, 0xa026,
+       0xd19c, 0x1904, 0x347f, 0x7000, 0x0002, 0x3483, 0x3441, 0x3465,
+       0x347f, 0xd1bc, 0x1150, 0xd1dc, 0x1150, 0x8001, 0x7002, 0x2011,
+       0x0001, 0x04e1, 0x05c0, 0x04d1, 0x04b0, 0x780f, 0x0000, 0x7820,
+       0x7924, 0x7803, 0x0004, 0x7822, 0x7926, 0x2001, 0x0201, 0x200c,
+       0x81ff, 0x0de8, 0x080c, 0x33b1, 0x2009, 0x0001, 0x7808, 0xd0ec,
+       0x0110, 0x2009, 0x0011, 0x7902, 0x00f0, 0x8001, 0x7002, 0xa184,
+       0x0880, 0x1138, 0x7804, 0xd0fc, 0x1940, 0x2011, 0x0001, 0x00b1,
+       0x0090, 0x6030, 0xa092, 0x0004, 0xa086, 0x0009, 0x1120, 0x6000,
+       0x601a, 0x2011, 0x0025, 0x6232, 0xd1dc, 0x1988, 0x0870, 0x7803,
+       0x0004, 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x6024, 0xa005,
+       0x0520, 0x8001, 0x6026, 0x6018, 0x6130, 0xa140, 0x2804, 0x7832,
+       0x8840, 0x2804, 0x7836, 0x8840, 0x2804, 0x7822, 0x8840, 0x2804,
+       0x7826, 0x8840, 0x7a02, 0x7000, 0x8000, 0x7002, 0x6018, 0xa802,
+       0xa08a, 0x0029, 0x1138, 0x6018, 0xa080, 0x0001, 0x2004, 0x601a,
+       0x2001, 0x000d, 0x6032, 0xa085, 0x0001, 0x0005, 0x00f6, 0x00e6,
+       0x00c6, 0x2071, 0xb01e, 0x2079, 0x0020, 0x7904, 0xd1fc, 0x01f0,
+       0x7803, 0x0002, 0x2d60, 0xa026, 0x7000, 0x0002, 0x34d6, 0x34c1,
+       0x34cd, 0x8001, 0x7002, 0xd19c, 0x1188, 0x2011, 0x0001, 0x080c,
+       0x3486, 0x0160, 0x080c, 0x3486, 0x0048, 0x8001, 0x7002, 0x7804,
+       0xd0fc, 0x1d30, 0x2011, 0x0001, 0x080c, 0x3486, 0x00ce, 0x00ee,
+       0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x2061, 0x0200, 0x601b,
+       0x0004, 0x2061, 0x0100, 0x60cf, 0x0400, 0x6004, 0xc0ac, 0xa085,
+       0x0200, 0x6006, 0x2001, 0x0074, 0x2004, 0xa005, 0x01f8, 0x2038,
+       0x2001, 0x0076, 0x2024, 0x2001, 0x0077, 0x201c, 0x080c, 0x3c05,
+       0x6833, 0x000d, 0x6f26, 0x2d00, 0x681a, 0xa78a, 0x0007, 0x0220,
+       0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0xa03e, 0x6818, 0xa080,
+       0x000d, 0x04a1, 0x1d90, 0x2d00, 0x681a, 0x0088, 0x080c, 0x3c05,
+       0x6833, 0x000d, 0x2070, 0x6827, 0x0001, 0x2d00, 0x681a, 0x2001,
+       0x0076, 0x2004, 0x2072, 0x2001, 0x0077, 0x2004, 0x7006, 0x2061,
+       0x0020, 0x2079, 0x0100, 0x6013, 0x0400, 0x20e1, 0x9040, 0x2001,
+       0x0072, 0x2004, 0xa084, 0xfff8, 0x700a, 0x601a, 0x0006, 0x2001,
+       0x0073, 0x2004, 0x700e, 0x601e, 0x78c6, 0x000e, 0x78ca, 0xa006,
+       0x603a, 0x603e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6, 0x2071,
+       0x0010, 0x20a0, 0x2099, 0x0014, 0x7003, 0x0026, 0x7432, 0x7336,
+       0xa006, 0x703a, 0x703e, 0x810b, 0x810b, 0x21a8, 0x810b, 0x7122,
+       0x7003, 0x0041, 0x7004, 0xd0fc, 0x0de8, 0x7003, 0x0002, 0x7003,
+       0x0040, 0x53a5, 0x7430, 0x7334, 0x87ff, 0x0180, 0x00c6, 0x00d6,
+       0x2d60, 0x00c6, 0x080c, 0x3c05, 0x00ce, 0x6018, 0x2070, 0x2d00,
+       0x7006, 0x601a, 0x00de, 0x00ce, 0xa085, 0x0001, 0x00ee, 0x0005,
+       0x00e6, 0x2001, 0x0075, 0x2004, 0xa005, 0x0508, 0x2038, 0x2001,
+       0x0078, 0x2024, 0x2001, 0x0079, 0x201c, 0x080c, 0x3c05, 0x2d60,
+       0x6833, 0x000d, 0x6f26, 0x2d00, 0x681a, 0xa78a, 0x0007, 0x0220,
+       0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0xa03e, 0x6818, 0xa080,
+       0x000d, 0x080c, 0x353e, 0x1d88, 0x2d00, 0x681a, 0x00e0, 0x080c,
+       0x3c05, 0x2d60, 0x6033, 0x000d, 0x2070, 0x6027, 0x0001, 0x2c00,
+       0x601a, 0x2001, 0x0078, 0x2004, 0x2072, 0x2001, 0x0079, 0x2004,
+       0x7006, 0x2001, 0x0072, 0x2004, 0xa084, 0xfff8, 0x700a, 0x2001,
+       0x0073, 0x2004, 0x700e, 0x2001, 0x0030, 0x2003, 0x0004, 0x7824,
+       0xd0ac, 0x1178, 0x2001, 0x0101, 0x200c, 0xc1ed, 0x2102, 0x6027,
+       0x0000, 0x2001, 0xaffd, 0x2003, 0x0003, 0x2001, 0x0030, 0x2003,
+       0x0009, 0x00ee, 0x0005, 0x0804, 0x2dcc, 0x0126, 0x2091, 0x8000,
+       0x20a9, 0x0011, 0x2001, 0xad40, 0x20a0, 0xa006, 0x40a4, 0x012e,
+       0x0804, 0x2dcc, 0x7d38, 0x7c3c, 0x0804, 0x2e73, 0x080c, 0x3c05,
+       0x0904, 0x2df1, 0x080c, 0x574f, 0x0110, 0x080c, 0x491f, 0x2009,
+       0x001c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3c46, 0x701b,
+       0x35f2, 0x0005, 0xade8, 0x000d, 0x6800, 0xa005, 0x0904, 0x2df4,
+       0x6804, 0xd0ac, 0x0118, 0xd0a4, 0x0904, 0x2df4, 0xd094, 0x00c6,
+       0x2061, 0x0100, 0x6104, 0x0138, 0x6200, 0xa292, 0x0005, 0x0218,
+       0xa18c, 0xffdf, 0x0010, 0xa18d, 0x0020, 0x6106, 0x00ce, 0xd08c,
+       0x00c6, 0x2061, 0x0100, 0x6104, 0x0118, 0xa18d, 0x0010, 0x0010,
+       0xa18c, 0xffef, 0x6106, 0x00ce, 0x2009, 0x0100, 0x210c, 0xa18a,
+       0x0002, 0x0268, 0xd084, 0x0158, 0x6a28, 0xa28a, 0x007f, 0x1a04,
+       0x2df4, 0xa288, 0x2be6, 0x210d, 0xa18c, 0x00ff, 0x6156, 0xd0dc,
+       0x0130, 0x6828, 0xa08a, 0x007f, 0x1a04, 0x2df4, 0x604e, 0x6808,
+       0xa08a, 0x0100, 0x0a04, 0x2df4, 0xa08a, 0x0841, 0x1a04, 0x2df4,
+       0xa084, 0x0007, 0x1904, 0x2df4, 0x680c, 0xa005, 0x0904, 0x2df4,
+       0x6810, 0xa005, 0x0904, 0x2df4, 0x6848, 0x6940, 0xa10a, 0x1a04,
+       0x2df4, 0x8001, 0x0904, 0x2df4, 0x684c, 0x6944, 0xa10a, 0x1a04,
+       0x2df4, 0x8001, 0x0904, 0x2df4, 0x6804, 0xd0fc, 0x0560, 0x080c,
+       0x3c05, 0x0904, 0x2df1, 0x2009, 0x0014, 0x7a2c, 0x7b28, 0x7c3c,
+       0x7d38, 0xa290, 0x0038, 0xa399, 0x0000, 0x080c, 0x3c46, 0x701b,
+       0x3672, 0x0005, 0xade8, 0x000d, 0x20a9, 0x0014, 0x2d98, 0x2069,
+       0xad6d, 0x2da0, 0x53a3, 0x7010, 0xa0e8, 0x000d, 0x2001, 0xad71,
+       0x200c, 0xd1e4, 0x0140, 0x00c6, 0x2061, 0x0100, 0x6004, 0xa085,
+       0x0b00, 0x6006, 0x00ce, 0x20a9, 0x001c, 0x2d98, 0x2069, 0xad51,
+       0x2da0, 0x53a3, 0x6814, 0xa08c, 0x00ff, 0x613e, 0x8007, 0xa084,
+       0x00ff, 0x6042, 0x080c, 0x5a1c, 0x080c, 0x5070, 0x080c, 0x50d9,
+       0x6000, 0xa086, 0x0000, 0x1904, 0x3755, 0x6808, 0x602a, 0x080c,
+       0x22f8, 0x0006, 0x2001, 0x0100, 0x2004, 0xa082, 0x0005, 0x000e,
+       0x0268, 0x2009, 0x0170, 0x200b, 0x0080, 0xe000, 0xe000, 0x200b,
+       0x0000, 0x0036, 0x6b08, 0x080c, 0x26fb, 0x003e, 0x6818, 0x691c,
+       0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, 0x611a,
+       0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148, 0x6830, 0x6934, 0x6a38,
+       0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0010, 0xa084, 0xf0ff,
+       0x6006, 0x610a, 0x620e, 0x6312, 0x8007, 0x810f, 0x8217, 0x831f,
+       0x20a9, 0x0004, 0x20a1, 0xafad, 0x40a1, 0x080c, 0x659c, 0x6904,
+       0xd1fc, 0x0520, 0x00c6, 0x2009, 0x0000, 0x20a9, 0x0001, 0x6b70,
+       0xd384, 0x01c8, 0x0020, 0x839d, 0x12b0, 0x3508, 0x8109, 0x080c,
+       0x5fa9, 0x6878, 0x6016, 0x6874, 0x2008, 0xa084, 0xff00, 0x8007,
+       0x600a, 0xa184, 0x00ff, 0x6006, 0x8108, 0x1118, 0x6003, 0x0003,
+       0x0010, 0x6003, 0x0001, 0x1f04, 0x36f3, 0x00ce, 0x2069, 0xad51,
+       0x2001, 0xaf9d, 0x6a80, 0xa294, 0x0030, 0xa28e, 0x0000, 0x0170,
+       0xa28e, 0x0010, 0x0118, 0xa28e, 0x0020, 0x0140, 0x2003, 0xaaaa,
+       0x080c, 0x2744, 0x2001, 0xaf8e, 0x2102, 0x0008, 0x2102, 0x00c6,
+       0x2061, 0x0100, 0x602f, 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c,
+       0x574f, 0x0128, 0x080c, 0x3e5f, 0x0110, 0x080c, 0x26c0, 0x60c4,
+       0xa005, 0x01b0, 0x6003, 0x0001, 0x2009, 0x373f, 0x00c0, 0x080c,
+       0x574f, 0x1158, 0x2011, 0x566e, 0x080c, 0x650d, 0x2001, 0xaf9e,
+       0x2003, 0x0000, 0x080c, 0x569a, 0x0040, 0x080c, 0x485e, 0x0028,
+       0x6003, 0x0004, 0x2009, 0x3755, 0x0010, 0x0804, 0x2dcc, 0x2001,
+       0x0100, 0x2004, 0xa082, 0x0005, 0x0258, 0x2001, 0x0170, 0x2004,
+       0xa084, 0x00ff, 0xa086, 0x004c, 0x1118, 0x2091, 0x309d, 0x0817,
+       0x2091, 0x301d, 0x0817, 0x6000, 0xa086, 0x0000, 0x0904, 0x2df1,
+       0x2069, 0xad51, 0x7830, 0x6842, 0x7834, 0x6846, 0x6804, 0xd0fc,
+       0x0118, 0x2009, 0x0030, 0x0010, 0x2009, 0x001c, 0x2d00, 0x7a2c,
+       0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49, 0xa006, 0x080c, 0x26c0,
+       0x81ff, 0x1904, 0x2df1, 0x080c, 0x574f, 0x1178, 0x2001, 0xaf9e,
+       0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0xa085, 0x0001,
+       0x080c, 0x5793, 0x080c, 0x569a, 0x0020, 0x080c, 0x491f, 0x080c,
+       0x485e, 0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x574f,
+       0x1110, 0x0804, 0x2df1, 0x6184, 0x81ff, 0x0198, 0x703f, 0x0000,
+       0x2001, 0xb3c0, 0x2009, 0x0040, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
+       0x0126, 0x2091, 0x8000, 0x080c, 0x3c49, 0x701b, 0x2dca, 0x012e,
+       0x0005, 0x703f, 0x0001, 0x00d6, 0x2069, 0xb3c0, 0x20a9, 0x0040,
+       0x20a1, 0xb3c0, 0x2019, 0xffff, 0x43a4, 0x654c, 0xa588, 0x2be6,
+       0x210d, 0xa18c, 0x00ff, 0x216a, 0xa00e, 0x2011, 0x0002, 0x2100,
+       0xa506, 0x01a8, 0x080c, 0x4cdc, 0x1190, 0x6014, 0x821c, 0x0238,
+       0xa398, 0xb3c0, 0xa085, 0xff00, 0x8007, 0x201a, 0x0038, 0xa398,
+       0xb3c0, 0x2324, 0xa4a4, 0xff00, 0xa405, 0x201a, 0x8210, 0x8108,
+       0xa182, 0x0080, 0x1208, 0x0c18, 0x8201, 0x8007, 0x2d0c, 0xa105,
+       0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, 0xb3c0, 0x2099, 0xb3c0,
+       0x080c, 0x48be, 0x0804, 0x37b0, 0x080c, 0x3c2a, 0x0904, 0x2df4,
+       0x00c6, 0x080c, 0x3c05, 0x00ce, 0x1120, 0x2009, 0x0002, 0x0804,
+       0x2df1, 0x2001, 0xad52, 0x2004, 0xd0b4, 0x01f0, 0x6000, 0xd08c,
+       0x11d8, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x11a8, 0x6837,
+       0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c, 0x970b, 0x1120, 0x2009,
+       0x0003, 0x0804, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3830, 0x0005,
+       0x080c, 0x3c2a, 0x0904, 0x2df4, 0x20a9, 0x002b, 0x2c98, 0xade8,
+       0x0002, 0x2da0, 0x53a3, 0x20a9, 0x0004, 0xac80, 0x0006, 0x2098,
+       0xad80, 0x0006, 0x20a0, 0x080c, 0x48be, 0x20a9, 0x0004, 0xac80,
+       0x000a, 0x2098, 0xad80, 0x000a, 0x20a0, 0x080c, 0x48be, 0x2d00,
+       0x2009, 0x002b, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49,
+       0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904, 0x2df4, 0x080c,
+       0x4eab, 0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x7828, 0xa08a,
+       0x1000, 0x1a04, 0x2df4, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x080c,
+       0x4f0d, 0x0904, 0x2df1, 0x2019, 0x0004, 0x080c, 0x4ebd, 0x7924,
+       0x810f, 0x7a28, 0x0011, 0x0804, 0x2dcc, 0xa186, 0x00ff, 0x0110,
+       0x0071, 0x0060, 0x2029, 0x007e, 0x2061, 0xad00, 0x644c, 0x2400,
+       0xa506, 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c,
+       0x4cdc, 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0xa108, 0x080c,
+       0x6519, 0x0005, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904,
+       0x2df4, 0x080c, 0x4d96, 0x0904, 0x2df1, 0x080c, 0x4eb4, 0x0804,
+       0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904, 0x2df4,
+       0x080c, 0x4d96, 0x0904, 0x2df1, 0x080c, 0x4ea2, 0x0804, 0x2dcc,
+       0x6100, 0x0804, 0x2dcc, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x2001,
+       0xad00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2df1, 0x00d6, 0xace8,
+       0x000a, 0x7924, 0xd184, 0x0110, 0xace8, 0x0006, 0x680c, 0x8007,
+       0x783e, 0x6808, 0x8007, 0x783a, 0x6b04, 0x831f, 0x6a00, 0x8217,
+       0x00de, 0x6100, 0xa18c, 0x0200, 0x0804, 0x2dcc, 0x7824, 0xa09c,
+       0x00ff, 0xa39a, 0x0003, 0x1a04, 0x2df1, 0x624c, 0xa294, 0x00ff,
+       0xa084, 0xff00, 0x8007, 0xa206, 0x1150, 0x2001, 0xad40, 0x2009,
+       0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49, 0x81ff,
+       0x1904, 0x2df1, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x6004, 0xa084,
+       0x00ff, 0xa086, 0x0006, 0x1904, 0x2df1, 0x00c6, 0x080c, 0x3c05,
+       0x00ce, 0x0904, 0x2df1, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a,
+       0x080c, 0x96b7, 0x0904, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3919,
+       0x0005, 0x6830, 0xa086, 0x0100, 0x0904, 0x2df1, 0xad80, 0x000e,
+       0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49,
+       0xa006, 0x080c, 0x26c0, 0x7824, 0xa084, 0x00ff, 0xa086, 0x00ff,
+       0x0118, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x574f, 0x0110, 0x080c,
+       0x491f, 0x7828, 0xa08a, 0x1000, 0x1a04, 0x2df4, 0x7924, 0xa18c,
+       0xff00, 0x810f, 0xa186, 0x00ff, 0x0138, 0xa182, 0x007f, 0x1a04,
+       0x2df4, 0x2100, 0x080c, 0x268a, 0x0026, 0x00c6, 0x0126, 0x2091,
+       0x8000, 0x2061, 0xafda, 0x601b, 0x0000, 0x601f, 0x0000, 0x080c,
+       0x574f, 0x1178, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00,
+       0x2003, 0x0001, 0xa085, 0x0001, 0x080c, 0x5793, 0x080c, 0x569a,
+       0x00a0, 0x2061, 0x0100, 0x2001, 0xad14, 0x2004, 0xa084, 0x00ff,
+       0x810f, 0xa105, 0x604a, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009,
+       0x002d, 0x2011, 0x4883, 0x080c, 0x6593, 0x7924, 0xa18c, 0xff00,
+       0x810f, 0x080c, 0x574f, 0x1110, 0x2009, 0x00ff, 0x7a28, 0x080c,
+       0x387d, 0x012e, 0x00ce, 0x002e, 0x0804, 0x2dcc, 0x7924, 0xa18c,
+       0xff00, 0x810f, 0x00c6, 0x080c, 0x4c80, 0x2c08, 0x00ce, 0x1904,
+       0x2df4, 0x0804, 0x2dcc, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
+       0x2df1, 0x60d0, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005,
+       0x0804, 0x2df1, 0x080c, 0x3c05, 0x1120, 0x2009, 0x0002, 0x0804,
+       0x2df1, 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3c46,
+       0x701b, 0x39bb, 0x0005, 0x2009, 0x0080, 0x080c, 0x4cdc, 0x1130,
+       0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x0120, 0x2021, 0x400a,
+       0x0804, 0x2dce, 0x00d6, 0xade8, 0x000d, 0x6900, 0x6a08, 0x6b0c,
+       0x6c10, 0x6d14, 0x6e18, 0x6820, 0xa0be, 0x0100, 0x0904, 0x3a32,
+       0xa0be, 0x0112, 0x0904, 0x3a32, 0xa0be, 0x0113, 0x0904, 0x3a32,
+       0xa0be, 0x0114, 0x0904, 0x3a32, 0xa0be, 0x0117, 0x0904, 0x3a32,
+       0xa0be, 0x011a, 0x0904, 0x3a32, 0xa0be, 0x011c, 0x0904, 0x3a32,
+       0xa0be, 0x0121, 0x05b0, 0xa0be, 0x0131, 0x0598, 0xa0be, 0x0171,
+       0x05c8, 0xa0be, 0x0173, 0x05b0, 0xa0be, 0x01a1, 0x1120, 0x6830,
+       0x8007, 0x6832, 0x04a8, 0xa0be, 0x0212, 0x0540, 0xa0be, 0x0213,
+       0x0528, 0xa0be, 0x0214, 0x01b0, 0xa0be, 0x0217, 0x0168, 0xa0be,
+       0x021a, 0x1120, 0x6838, 0x8007, 0x683a, 0x00e0, 0xa0be, 0x0300,
+       0x01c8, 0x00de, 0x0804, 0x2df4, 0xad80, 0x0010, 0x20a9, 0x0007,
+       0x080c, 0x3a78, 0xad80, 0x000e, 0x20a9, 0x0001, 0x080c, 0x3a78,
+       0x0048, 0xad80, 0x000c, 0x080c, 0x3a86, 0x0050, 0xad80, 0x000e,
+       0x080c, 0x3a86, 0xad80, 0x000c, 0x20a9, 0x0001, 0x080c, 0x3a78,
+       0x00c6, 0x080c, 0x3c05, 0x0568, 0x6838, 0xc0fd, 0x683a, 0x6837,
+       0x0119, 0x6853, 0x0000, 0x684f, 0x0020, 0x685b, 0x0001, 0x810b,
+       0x697e, 0x6883, 0x0000, 0x6a86, 0x6b8a, 0x6c8e, 0x6d92, 0x6996,
+       0x689b, 0x0000, 0x00ce, 0x00de, 0x6837, 0x0000, 0x6838, 0xc0fd,
+       0x683a, 0x6823, 0x0000, 0x6804, 0x2068, 0x080c, 0x96d3, 0x1120,
+       0x2009, 0x0003, 0x0804, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3a6f,
+       0x0005, 0x00ce, 0x00de, 0x2009, 0x0002, 0x0804, 0x2df1, 0x6820,
+       0xa086, 0x8001, 0x1904, 0x2dcc, 0x2009, 0x0004, 0x0804, 0x2df1,
+       0x0016, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x290a, 0x8108,
+       0x280a, 0x8108, 0x1f04, 0x3a7a, 0x001e, 0x0005, 0x0016, 0x00a6,
+       0x00b6, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x2054, 0x8000,
+       0x205c, 0x2b0a, 0x8108, 0x2a0a, 0x8108, 0x290a, 0x8108, 0x280a,
+       0x00be, 0x00ae, 0x001e, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001,
+       0x0804, 0x2df1, 0x7924, 0x2140, 0xa18c, 0xff00, 0x810f, 0x60d0,
+       0xd0ac, 0x1120, 0xa182, 0x0080, 0x0a04, 0x2df4, 0xa182, 0x00ff,
+       0x1a04, 0x2df4, 0x7a2c, 0x7b28, 0x606c, 0xa306, 0x1140, 0x6070,
+       0xa24e, 0x0904, 0x2df4, 0xa9cc, 0xff00, 0x0904, 0x2df4, 0x00c6,
+       0x080c, 0x3b58, 0x2c68, 0x00ce, 0x0538, 0xa0c6, 0x4000, 0x1180,
+       0x00c6, 0x0006, 0x2d60, 0x2009, 0x0000, 0x080c, 0x4f6e, 0x1108,
+       0xc185, 0x6000, 0xd0bc, 0x0108, 0xc18d, 0x000e, 0x00ce, 0x0088,
+       0xa0c6, 0x4007, 0x1110, 0x2408, 0x0060, 0xa0c6, 0x4008, 0x1118,
+       0x2708, 0x2610, 0x0030, 0xa0c6, 0x4009, 0x1108, 0x0010, 0x2001,
+       0x4006, 0x2020, 0x0804, 0x2dce, 0x2d00, 0x7022, 0x0016, 0x00b6,
+       0x00c6, 0x00e6, 0x2c70, 0x080c, 0x8022, 0x05d8, 0x2d00, 0x601a,
+       0x080c, 0x9956, 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c, 0x3c05,
+       0x00ce, 0x2b70, 0x1150, 0x080c, 0x8078, 0x00ee, 0x00ce, 0x00be,
+       0x001e, 0x2009, 0x0002, 0x0804, 0x2df1, 0x6837, 0x0000, 0x683b,
+       0x0000, 0x2d00, 0x6012, 0x6833, 0x0000, 0x6838, 0xc0fd, 0xd88c,
+       0x0108, 0xc0f5, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x2ad9,
+       0x012e, 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x2001,
+       0x0002, 0x080c, 0x4c30, 0x2009, 0x0002, 0x080c, 0x80a7, 0xa085,
+       0x0001, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x1120, 0x2009, 0x0003,
+       0x0804, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3b3f, 0x0005, 0x6830,
+       0xa086, 0x0100, 0x7020, 0x2060, 0x1138, 0x2009, 0x0004, 0x6204,
+       0xa294, 0x00ff, 0x0804, 0x2df1, 0x2009, 0x0000, 0x080c, 0x4f6e,
+       0x1108, 0xc185, 0x6000, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x2dcc,
+       0x00e6, 0x00d6, 0x2029, 0x0000, 0x2001, 0xad34, 0x2004, 0xd0ac,
+       0x0138, 0x2021, 0x0000, 0x20a9, 0x00ff, 0x2071, 0xae34, 0x0030,
+       0x2021, 0x0080, 0x20a9, 0x007f, 0x2071, 0xaeb4, 0x2e04, 0xa005,
+       0x1130, 0x2100, 0xa406, 0x1548, 0x2428, 0xc5fd, 0x0430, 0x2068,
+       0x6f10, 0x2700, 0xa306, 0x11b0, 0x6e14, 0x2600, 0xa206, 0x1190,
+       0x2400, 0xa106, 0x1160, 0x2d60, 0xd884, 0x0540, 0x6004, 0xa084,
+       0x00ff, 0xa086, 0x0006, 0x1510, 0x2001, 0x4000, 0x0400, 0x2001,
+       0x4007, 0x00e8, 0x2400, 0xa106, 0x1140, 0x6e14, 0x87ff, 0x1110,
+       0x86ff, 0x09d0, 0x2001, 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04,
+       0x3b6e, 0x85ff, 0x1130, 0x2001, 0x4009, 0x0048, 0x2001, 0x0001,
+       0x0030, 0x080c, 0x4c80, 0x1dd0, 0x6312, 0x6216, 0xa006, 0xa005,
+       0x00de, 0x00ee, 0x0005, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c05,
+       0x0904, 0x2df1, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x7824,
+       0xa005, 0x0904, 0x2df4, 0xa096, 0x00ff, 0x0120, 0xa092, 0x0004,
+       0x1a04, 0x2df4, 0x2010, 0x2d18, 0x080c, 0x2a8c, 0x0904, 0x2df1,
+       0x7007, 0x0003, 0x701b, 0x3bd5, 0x0005, 0x6830, 0xa086, 0x0100,
+       0x0904, 0x2df1, 0x0804, 0x2dcc, 0x7924, 0xa18c, 0xff00, 0x810f,
+       0x60d0, 0xd0ac, 0x1120, 0xa182, 0x0080, 0x0a04, 0x2df4, 0xa182,
+       0x00ff, 0x1a04, 0x2df4, 0x0126, 0x2091, 0x8000, 0x080c, 0x95c6,
+       0x1188, 0xa190, 0xae34, 0x2204, 0xa065, 0x0160, 0x080c, 0x493a,
+       0x2001, 0xad34, 0x2004, 0xd0ac, 0x0110, 0x6017, 0x0000, 0x012e,
+       0x0804, 0x2dcc, 0x012e, 0x0804, 0x2df1, 0x080c, 0x15d9, 0x0188,
+       0xa006, 0x6802, 0x7010, 0xa005, 0x1120, 0x2d00, 0x7012, 0x7016,
+       0x0030, 0x7014, 0x6802, 0x2060, 0x2d00, 0x6006, 0x7016, 0xad80,
+       0x000d, 0x0005, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x080c, 0x4cdc,
+       0x1130, 0x7e28, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0208, 0xa066,
+       0x8cff, 0x0005, 0x7e24, 0x860f, 0xa18c, 0x00ff, 0x080c, 0x4cdc,
+       0x1128, 0xa6b4, 0x00ff, 0xa682, 0x4000, 0x0208, 0xa066, 0x8cff,
+       0x0005, 0x0016, 0x7110, 0x81ff, 0x0128, 0x2168, 0x6904, 0x080c,
+       0x15f0, 0x0cc8, 0x7112, 0x7116, 0x001e, 0x0005, 0x2031, 0x0001,
+       0x0010, 0x2031, 0x0000, 0x2061, 0xadd1, 0x6606, 0x6112, 0x600e,
+       0x6226, 0x632a, 0x642e, 0x6532, 0x2c10, 0x080c, 0x1624, 0x7007,
+       0x0002, 0x701b, 0x2dcc, 0x0005, 0x00f6, 0x0126, 0x2091, 0x8000,
+       0x2079, 0x0000, 0x2001, 0xad8f, 0x2004, 0xa005, 0x1168, 0x0e04,
+       0x3c74, 0x7818, 0xd084, 0x1140, 0x7a22, 0x7b26, 0x7c2a, 0x781b,
+       0x0001, 0x2091, 0x4080, 0x0408, 0x0016, 0x00c6, 0x00e6, 0x2071,
+       0xad81, 0x7138, 0xa182, 0x0010, 0x0218, 0x7030, 0x2060, 0x0078,
+       0x7030, 0xa0e0, 0x0004, 0xac82, 0xadd1, 0x0210, 0x2061, 0xad91,
+       0x2c00, 0x7032, 0x81ff, 0x1108, 0x7036, 0x8108, 0x713a, 0x2262,
+       0x6306, 0x640a, 0x00ee, 0x00ce, 0x001e, 0x012e, 0x00fe, 0x0005,
+       0x00e6, 0x2071, 0xad81, 0x7038, 0xa005, 0x0570, 0x0126, 0x2091,
+       0x8000, 0x0e04, 0x3ccb, 0x00f6, 0x2079, 0x0000, 0x7818, 0xd084,
+       0x1508, 0x00c6, 0x7034, 0x2060, 0x2c04, 0x7822, 0x6004, 0x7826,
+       0x6008, 0x782a, 0x781b, 0x0001, 0x2091, 0x4080, 0x7038, 0x8001,
+       0x703a, 0xa005, 0x1130, 0x7033, 0xad91, 0x7037, 0xad91, 0x00ce,
+       0x0048, 0xac80, 0x0004, 0xa0fa, 0xadd1, 0x0210, 0x2001, 0xad91,
+       0x7036, 0x00ce, 0x00fe, 0x012e, 0x00ee, 0x0005, 0x0026, 0x2001,
+       0xad52, 0x2004, 0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, 0x3c5c,
+       0x002e, 0x0005, 0x81ff, 0x1904, 0x2df1, 0x0126, 0x2091, 0x8000,
+       0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x080c, 0x574f, 0x1178,
+       0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001,
+       0xa085, 0x0001, 0x080c, 0x5793, 0x080c, 0x569a, 0x0010, 0x080c,
+       0x485e, 0x012e, 0x0804, 0x2dcc, 0x7824, 0x2008, 0xa18c, 0xfffd,
+       0x1128, 0x61dc, 0xa10d, 0x61de, 0x0804, 0x2dcc, 0x0804, 0x2df4,
+       0x81ff, 0x1904, 0x2df1, 0x6000, 0xa086, 0x0003, 0x1904, 0x2df1,
+       0x2001, 0xad52, 0x2004, 0xd0ac, 0x1904, 0x2df1, 0x080c, 0x3c2a,
+       0x0904, 0x2df4, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1120,
+       0x7828, 0xa005, 0x0904, 0x2dcc, 0x00c6, 0x080c, 0x3c05, 0x00ce,
+       0x0904, 0x2df1, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd,
+       0x683a, 0x080c, 0x979c, 0x0904, 0x2df1, 0x7007, 0x0003, 0x701b,
+       0x3d3a, 0x0005, 0x6830, 0xa086, 0x0100, 0x0904, 0x2df1, 0x0804,
+       0x2dcc, 0x2001, 0xad00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2df1,
+       0x7f24, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3c05, 0x0904,
+       0x2df1, 0x2009, 0x0000, 0x2031, 0x0000, 0x7023, 0x0000, 0x702f,
+       0x0000, 0xad80, 0x0005, 0x7026, 0x20a0, 0x080c, 0x4cdc, 0x1904,
+       0x3db4, 0x6004, 0xa0c4, 0x00ff, 0xa8c6, 0x0006, 0x0130, 0xa0c4,
+       0xff00, 0xa8c6, 0x0600, 0x1904, 0x3db4, 0x2001, 0xad52, 0x2004,
+       0xd0ac, 0x1128, 0x080c, 0x4f6e, 0x1110, 0xd79c, 0x05e8, 0xd794,
+       0x1110, 0xd784, 0x0158, 0xac80, 0x0006, 0x2098, 0x3400, 0x20a9,
+       0x0004, 0x53a3, 0x080c, 0x3a86, 0xd794, 0x0148, 0xac80, 0x000a,
+       0x2098, 0x3400, 0x20a9, 0x0004, 0x53a3, 0x080c, 0x3a86, 0x21a2,
+       0xd794, 0x01d8, 0xac80, 0x0000, 0x2098, 0x94a0, 0x20a9, 0x0002,
+       0x53a3, 0xac80, 0x0003, 0x20a6, 0x94a0, 0xac80, 0x0004, 0x2098,
+       0x3400, 0x20a9, 0x0002, 0x53a3, 0x080c, 0x3a78, 0xac80, 0x0026,
+       0x2098, 0x20a9, 0x0002, 0x53a3, 0x0008, 0x94a0, 0xd794, 0x0110,
+       0xa6b0, 0x000b, 0xa6b0, 0x0005, 0x8108, 0x2001, 0xad34, 0x2004,
+       0xd0ac, 0x0118, 0xa186, 0x0100, 0x0040, 0xd78c, 0x0120, 0xa186,
+       0x0100, 0x0170, 0x0018, 0xa186, 0x007e, 0x0150, 0xd794, 0x0118,
+       0xa686, 0x0020, 0x0010, 0xa686, 0x0028, 0x0150, 0x0804, 0x3d5d,
+       0x86ff, 0x1120, 0x7120, 0x810b, 0x0804, 0x2dcc, 0x702f, 0x0001,
+       0x711e, 0x7020, 0xa600, 0x7022, 0x772a, 0x2061, 0xadd1, 0x6007,
+       0x0000, 0x6612, 0x7024, 0x600e, 0x6226, 0x632a, 0x642e, 0x6532,
+       0x2c10, 0x080c, 0x1624, 0x7007, 0x0002, 0x701b, 0x3df0, 0x0005,
+       0x702c, 0xa005, 0x1170, 0x711c, 0x7024, 0x20a0, 0x7728, 0x2031,
+       0x0000, 0x2061, 0xadd1, 0x6224, 0x6328, 0x642c, 0x6530, 0x0804,
+       0x3d5d, 0x7120, 0x810b, 0x0804, 0x2dcc, 0x2029, 0x007e, 0x7924,
+       0x7a28, 0x7b2c, 0x7c38, 0xa184, 0xff00, 0x8007, 0xa0e2, 0x0020,
+       0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4, 0xa184, 0x00ff, 0xa0e2,
+       0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4, 0xa284, 0xff00,
+       0x8007, 0xa0e2, 0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4,
+       0xa284, 0x00ff, 0xa0e2, 0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04,
+       0x2df4, 0xa384, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0a04, 0x2df4,
+       0xa502, 0x0a04, 0x2df4, 0xa384, 0x00ff, 0xa0e2, 0x0020, 0x0a04,
+       0x2df4, 0xa502, 0x0a04, 0x2df4, 0xa484, 0xff00, 0x8007, 0xa0e2,
+       0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4, 0xa484, 0x00ff,
+       0xa0e2, 0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4, 0x2061,
+       0xafa6, 0x6102, 0x6206, 0x630a, 0x640e, 0x0804, 0x2dcc, 0x0006,
+       0x2001, 0xad52, 0x2004, 0xd0cc, 0x000e, 0x0005, 0x0006, 0x2001,
+       0xad71, 0x2004, 0xd0bc, 0x000e, 0x0005, 0x6164, 0x7a24, 0x6300,
+       0x82ff, 0x1118, 0x7926, 0x0804, 0x2dcc, 0x83ff, 0x1904, 0x2df4,
+       0x2001, 0xfff0, 0xa200, 0x1a04, 0x2df4, 0x2019, 0xffff, 0x6068,
+       0xa302, 0xa200, 0x0a04, 0x2df4, 0x7926, 0x6266, 0x0804, 0x2dcc,
+       0x2001, 0xad00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2df1, 0x7c28,
+       0x7d24, 0x7e38, 0x7f2c, 0x080c, 0x3c05, 0x0904, 0x2df1, 0x2009,
+       0x0000, 0x2019, 0x0000, 0x7023, 0x0000, 0x702f, 0x0000, 0xad80,
+       0x0003, 0x7026, 0x20a0, 0xa1e0, 0xae34, 0x2c64, 0x8cff, 0x01b8,
+       0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x0130, 0x6004, 0xa084,
+       0xff00, 0xa086, 0x0600, 0x1158, 0x6014, 0x20a2, 0x94a0, 0x6010,
+       0x8007, 0xa105, 0x8007, 0x20a2, 0x94a0, 0xa398, 0x0002, 0x8108,
+       0xa182, 0x00ff, 0x0120, 0xa386, 0x002a, 0x0148, 0x08e0, 0x83ff,
+       0x1120, 0x7120, 0x810c, 0x0804, 0x2dcc, 0x702f, 0x0001, 0x711e,
+       0x7020, 0xa300, 0x7022, 0x2061, 0xadd1, 0x6007, 0x0000, 0x6312,
+       0x7024, 0x600e, 0x6426, 0x652a, 0x662e, 0x6732, 0x2c10, 0x080c,
+       0x1624, 0x7007, 0x0002, 0x701b, 0x3ee6, 0x0005, 0x702c, 0xa005,
+       0x1168, 0x711c, 0x7024, 0x20a0, 0x2019, 0x0000, 0x2061, 0xadd1,
+       0x6424, 0x6528, 0x662c, 0x6730, 0x0804, 0x3ea3, 0x7120, 0x810c,
+       0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x60d0, 0xd0ac, 0x1118,
+       0xd09c, 0x0904, 0x2df1, 0x080c, 0x3c05, 0x0904, 0x2df1, 0x7924,
+       0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3c46, 0x701b, 0x3f11,
+       0x0005, 0x00d6, 0xade8, 0x000d, 0x6828, 0xa0be, 0x7000, 0x0148,
+       0xa0be, 0x7100, 0x0130, 0xa0be, 0x7200, 0x0118, 0x00de, 0x0804,
+       0x2df4, 0x6820, 0x6924, 0x080c, 0x2676, 0x1510, 0x080c, 0x4c80,
+       0x11f8, 0x7122, 0x6612, 0x6516, 0x6e18, 0x00c6, 0x080c, 0x3c05,
+       0x01b8, 0x080c, 0x3c05, 0x01a0, 0x00ce, 0x00de, 0x6837, 0x0000,
+       0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000, 0x6804, 0x2068, 0x080c,
+       0x96ef, 0x0904, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3f4b, 0x0005,
+       0x00de, 0x0804, 0x2df1, 0x7120, 0x080c, 0x2bc9, 0x6820, 0xa086,
+       0x8001, 0x0904, 0x2df1, 0x2d00, 0x701e, 0x6804, 0xa080, 0x0002,
+       0x0006, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x080c, 0x48be, 0x000e,
+       0xade8, 0x000d, 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x2061, 0xadd1,
+       0x6007, 0x0000, 0x6e00, 0x6f28, 0xa7c6, 0x7000, 0x1108, 0x0018,
+       0xa7c6, 0x7100, 0x1140, 0xa6c2, 0x0004, 0x0a04, 0x2df4, 0x2009,
+       0x0004, 0x0804, 0x3c49, 0xa7c6, 0x7200, 0x1904, 0x2df4, 0xa6c2,
+       0x0054, 0x0a04, 0x2df4, 0x600e, 0x6013, 0x002a, 0x6226, 0x632a,
+       0x642e, 0x6532, 0x2c10, 0x080c, 0x1624, 0x7007, 0x0002, 0x701b,
+       0x3f92, 0x0005, 0x701c, 0x2068, 0x6804, 0xa080, 0x0001, 0x2004,
+       0xa080, 0x0002, 0x0006, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x080c,
+       0x48be, 0x000e, 0x2009, 0x002a, 0x2061, 0xadd1, 0x6224, 0x6328,
+       0x642c, 0x6530, 0x0804, 0x3c49, 0x81ff, 0x1904, 0x2df1, 0x080c,
+       0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4d96, 0x0904, 0x2df1, 0x080c,
+       0x4ec6, 0x0804, 0x2dcc, 0x7824, 0xd084, 0x0904, 0x3804, 0x080c,
+       0x3c2a, 0x0904, 0x2df4, 0x00c6, 0x080c, 0x3c05, 0x00ce, 0x1120,
+       0x2009, 0x0002, 0x0804, 0x2df1, 0x6004, 0xa084, 0x00ff, 0xa086,
+       0x0006, 0x0128, 0xa08e, 0x0004, 0x0110, 0xa08e, 0x0005, 0x1508,
+       0x2001, 0xad52, 0x2004, 0xd0b4, 0x0904, 0x3834, 0x6000, 0xd08c,
+       0x1904, 0x3834, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c,
+       0x970b, 0x1120, 0x2009, 0x0003, 0x0804, 0x2df1, 0x7007, 0x0003,
+       0x701b, 0x3ff3, 0x0005, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x0804,
+       0x3834, 0x2009, 0xad30, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001,
+       0x0804, 0x2df1, 0x2001, 0xad00, 0x2004, 0xa086, 0x0003, 0x0120,
+       0x2009, 0x0007, 0x0804, 0x2df1, 0x2001, 0xad52, 0x2004, 0xd0ac,
+       0x0120, 0x2009, 0x0008, 0x0804, 0x2df1, 0x609c, 0xd0a4, 0x1118,
+       0xd0ac, 0x1904, 0x3834, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838,
+       0xc0fd, 0x683a, 0x080c, 0x979c, 0x1120, 0x2009, 0x0003, 0x0804,
+       0x2df1, 0x7007, 0x0003, 0x701b, 0x402e, 0x0005, 0x6830, 0xa086,
+       0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x2df1, 0x080c, 0x3c2a,
+       0x0904, 0x2df4, 0x0804, 0x3fd8, 0x81ff, 0x2009, 0x0001, 0x1904,
+       0x2df1, 0x6000, 0xa086, 0x0003, 0x2009, 0x0007, 0x1904, 0x2df1,
+       0x2001, 0xad52, 0x2004, 0xd0ac, 0x2009, 0x0008, 0x1904, 0x2df1,
+       0x080c, 0x3c2a, 0x0904, 0x2df4, 0x6004, 0xa084, 0x00ff, 0xa086,
+       0x0006, 0x2009, 0x0009, 0x1904, 0x2df1, 0x00c6, 0x080c, 0x3c05,
+       0x00ce, 0x2009, 0x0002, 0x0904, 0x2df1, 0x6837, 0x0000, 0x6833,
+       0x0000, 0x6838, 0xc0fd, 0x683a, 0x7928, 0xa194, 0xff00, 0xa18c,
+       0x00ff, 0xa006, 0x82ff, 0x1128, 0xc0ed, 0x6952, 0x792c, 0x6956,
+       0x0048, 0xa28e, 0x0100, 0x1904, 0x2df4, 0xc0e5, 0x6853, 0x0000,
+       0x6857, 0x0000, 0x683e, 0x080c, 0x9957, 0x2009, 0x0003, 0x0904,
+       0x2df1, 0x7007, 0x0003, 0x701b, 0x408e, 0x0005, 0x6830, 0xa086,
+       0x0100, 0x2009, 0x0004, 0x0904, 0x2df1, 0x0804, 0x2dcc, 0x81ff,
+       0x2009, 0x0001, 0x1904, 0x2df1, 0x6000, 0xa086, 0x0003, 0x2009,
+       0x0007, 0x1904, 0x2df1, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x6004,
+       0xa084, 0x00ff, 0xa086, 0x0006, 0x2009, 0x0009, 0x1904, 0x2df1,
+       0x00c6, 0x080c, 0x3c05, 0x00ce, 0x2009, 0x0002, 0x0904, 0x2df1,
+       0xad80, 0x000f, 0x2009, 0x0008, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
+       0x080c, 0x3c46, 0x701b, 0x40c5, 0x0005, 0x00d6, 0xade8, 0x000f,
+       0x6800, 0xa086, 0x0500, 0x1140, 0x6804, 0xa005, 0x1128, 0x6808,
+       0xa084, 0xff00, 0x1108, 0x0018, 0x00de, 0x1904, 0x2df4, 0x00de,
+       0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x00c6,
+       0x080c, 0x3c2a, 0x1118, 0x00ce, 0x0804, 0x2df4, 0x080c, 0x99a6,
+       0x2009, 0x0003, 0x00ce, 0x0904, 0x2df1, 0x7007, 0x0003, 0x701b,
+       0x40f2, 0x0005, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004, 0x0904,
+       0x2df1, 0x0804, 0x2dcc, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
+       0x2df1, 0x6000, 0xa086, 0x0003, 0x0120, 0x2009, 0x0007, 0x0804,
+       0x2df1, 0x7e24, 0x860f, 0xa18c, 0x00ff, 0xa6b4, 0x00ff, 0x080c,
+       0x4cdc, 0x1904, 0x2df4, 0xa186, 0x007f, 0x0150, 0x6004, 0xa084,
+       0x00ff, 0xa086, 0x0006, 0x0120, 0x2009, 0x0009, 0x0804, 0x2df1,
+       0x00c6, 0x080c, 0x3c05, 0x00ce, 0x1120, 0x2009, 0x0002, 0x0804,
+       0x2df1, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c, 0x9726,
+       0x1120, 0x2009, 0x0003, 0x0804, 0x2df1, 0x7007, 0x0003, 0x701b,
+       0x413a, 0x0005, 0x6808, 0x8007, 0xa086, 0x0100, 0x1120, 0x2009,
+       0x0004, 0x0804, 0x2df1, 0x68b0, 0x6836, 0x6810, 0x8007, 0xa084,
+       0x00ff, 0x808e, 0x6814, 0x8007, 0xa084, 0x00ff, 0x8086, 0xa080,
+       0x0002, 0xa108, 0xad80, 0x0004, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
+       0x0804, 0x3c49, 0x080c, 0x3c05, 0x1120, 0x2009, 0x0002, 0x0804,
+       0x2df1, 0x7924, 0xa194, 0xff00, 0xa18c, 0x00ff, 0x8217, 0x82ff,
+       0x0110, 0x0804, 0x2df4, 0x2009, 0x001a, 0x7a2c, 0x7b28, 0x7c3c,
+       0x7d38, 0x080c, 0x3c46, 0x701b, 0x4176, 0x0005, 0xad80, 0x000d,
+       0x2098, 0x20a9, 0x001a, 0x20a1, 0xafad, 0x53a3, 0x0804, 0x2dcc,
+       0x080c, 0x3c05, 0x1120, 0x2009, 0x0002, 0x0804, 0x2df1, 0x7924,
+       0xa194, 0xff00, 0xa18c, 0x00ff, 0x8217, 0x82ff, 0x0110, 0x0804,
+       0x2df4, 0x2099, 0xafad, 0x20a0, 0x20a9, 0x001a, 0x53a3, 0x2009,
+       0x001a, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49, 0x7824,
+       0xa08a, 0x1000, 0x1a04, 0x2df4, 0x0126, 0x2091, 0x8000, 0x8003,
+       0x800b, 0x810b, 0xa108, 0x00c6, 0x2061, 0xafda, 0x6142, 0x00ce,
+       0x012e, 0x0804, 0x2dcc, 0x00c6, 0x080c, 0x574f, 0x1188, 0x2001,
+       0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0xa085,
+       0x0001, 0x080c, 0x5793, 0x080c, 0x569a, 0x080c, 0x14f6, 0x0038,
+       0x2061, 0xad00, 0x6030, 0xc09d, 0x6032, 0x080c, 0x485e, 0x00ce,
+       0x0005, 0x0126, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0xad00,
+       0x6044, 0xd0a4, 0x11b0, 0xd084, 0x0118, 0x080c, 0x4348, 0x0068,
+       0xd08c, 0x0118, 0x080c, 0x4269, 0x0040, 0xd094, 0x0118, 0x080c,
+       0x423a, 0x0018, 0xd09c, 0x0108, 0x0061, 0x00ee, 0x00ce, 0x012e,
+       0x0005, 0x0016, 0x6128, 0xd19c, 0x1110, 0xc19d, 0x612a, 0x001e,
+       0x0ca0, 0x624c, 0xa286, 0xf0f0, 0x1150, 0x6048, 0xa086, 0xf0f0,
+       0x0130, 0x624a, 0x6043, 0x0090, 0x6043, 0x0010, 0x0490, 0xa294,
+       0xff00, 0xa296, 0xf700, 0x0178, 0x7134, 0xd1a4, 0x1160, 0x6240,
+       0xa295, 0x0100, 0x6242, 0xa294, 0x0010, 0x0128, 0x2009, 0x00f7,
+       0x080c, 0x48de, 0x00f0, 0x6040, 0xa084, 0x0010, 0xa085, 0x0040,
+       0x6042, 0x6043, 0x0000, 0x7077, 0x0000, 0x7093, 0x0001, 0x70b7,
+       0x0000, 0x70d3, 0x0000, 0x2009, 0xb3c0, 0x200b, 0x0000, 0x7087,
+       0x0000, 0x707b, 0x000a, 0x2009, 0x000a, 0x2011, 0x4814, 0x080c,
+       0x6593, 0x0005, 0x0156, 0x2001, 0xad73, 0x2004, 0xd08c, 0x0110,
+       0x704f, 0xffff, 0x7078, 0xa005, 0x1510, 0x2011, 0x4814, 0x080c,
+       0x650d, 0x6040, 0xa094, 0x0010, 0xa285, 0x0020, 0x6042, 0x20a9,
+       0x00c8, 0x6044, 0xd08c, 0x1168, 0x1f04, 0x4251, 0x6242, 0x708b,
+       0x0000, 0x6040, 0xa094, 0x0010, 0xa285, 0x0080, 0x6042, 0x6242,
+       0x0030, 0x6242, 0x708b, 0x0000, 0x707f, 0x0000, 0x0000, 0x015e,
+       0x0005, 0x707c, 0xa08a, 0x0003, 0x1210, 0x0023, 0x0010, 0x080c,
+       0x14f6, 0x0005, 0x4275, 0x42c5, 0x4347, 0x00f6, 0x707f, 0x0001,
+       0x20e1, 0xa000, 0xe000, 0x20e1, 0x8700, 0x080c, 0x22f8, 0x20e1,
+       0x9080, 0x20e1, 0x4000, 0x2079, 0xb200, 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, 0xb20c, 0x207b,
+       0x1101, 0x7807, 0x0000, 0x2099, 0xad05, 0x20a1, 0xb20e, 0x20a9,
+       0x0004, 0x53a3, 0x2079, 0xb212, 0x207b, 0x0000, 0x7807, 0x0000,
+       0x2099, 0xb200, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x60c3,
+       0x000c, 0x600f, 0x0000, 0x080c, 0x4845, 0x00fe, 0x7083, 0x0000,
+       0x6043, 0x0008, 0x6043, 0x0000, 0x0005, 0x00d6, 0x7080, 0x7083,
+       0x0000, 0xa025, 0x0904, 0x432f, 0x6020, 0xd0b4, 0x1904, 0x432d,
+       0x7190, 0x81ff, 0x0904, 0x431d, 0xa486, 0x000c, 0x1904, 0x4328,
+       0xa480, 0x0018, 0x8004, 0x20a8, 0x2011, 0xb280, 0x2019, 0xb200,
+       0x220c, 0x2304, 0xa106, 0x11b8, 0x8210, 0x8318, 0x1f04, 0x42e0,
+       0x6043, 0x0004, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006,
+       0x707f, 0x0002, 0x708b, 0x0002, 0x2009, 0x07d0, 0x2011, 0x481b,
+       0x080c, 0x6593, 0x0490, 0x2069, 0xb280, 0x6930, 0xa18e, 0x1101,
+       0x1538, 0x6834, 0xa005, 0x1520, 0x6900, 0xa18c, 0x00ff, 0x1118,
+       0x6804, 0xa005, 0x0190, 0x2011, 0xb28e, 0x2019, 0xad05, 0x20a9,
+       0x0004, 0x220c, 0x2304, 0xa102, 0x0230, 0x1190, 0x8210, 0x8318,
+       0x1f04, 0x4311, 0x0068, 0x7093, 0x0000, 0x20e1, 0x9080, 0x20e1,
+       0x4000, 0x2099, 0xb280, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6,
+       0x6043, 0x0008, 0x6043, 0x0000, 0x0010, 0x00de, 0x0005, 0x6040,
+       0xa085, 0x0100, 0x6042, 0x6020, 0xd0b4, 0x1db8, 0x60c3, 0x000c,
+       0x2011, 0xafd1, 0x2013, 0x0000, 0x7083, 0x0000, 0x20e1, 0x9080,
+       0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x782b, 0x0c30, 0x0005,
+       0x7088, 0xa08a, 0x001d, 0x1210, 0x0023, 0x0010, 0x080c, 0x14f6,
+       0x0005, 0x437b, 0x438a, 0x43b2, 0x43cb, 0x43ef, 0x4417, 0x443b,
+       0x446c, 0x4490, 0x44b8, 0x44ef, 0x4517, 0x4533, 0x4549, 0x4569,
+       0x457c, 0x4584, 0x45b1, 0x45d5, 0x45fd, 0x4621, 0x4652, 0x468f,
+       0x46be, 0x46da, 0x4719, 0x4739, 0x4752, 0x4753, 0x00c6, 0x2061,
+       0xad00, 0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0xa084, 0xfff9,
+       0x6006, 0x00ce, 0x0005, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043,
+       0x0002, 0x708b, 0x0001, 0x2009, 0x07d0, 0x2011, 0x481b, 0x080c,
+       0x6593, 0x0005, 0x00f6, 0x7080, 0xa086, 0x0014, 0x1508, 0x6043,
+       0x0000, 0x6020, 0xd0b4, 0x11e0, 0x2079, 0xb280, 0x7a30, 0xa296,
+       0x1102, 0x11a0, 0x7834, 0xa005, 0x1188, 0x7a38, 0xd2fc, 0x0128,
+       0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001, 0x2011, 0x481b, 0x080c,
+       0x650d, 0x708b, 0x0010, 0x080c, 0x4584, 0x0010, 0x080c, 0x485e,
+       0x00fe, 0x0005, 0x708b, 0x0003, 0x6043, 0x0004, 0x2011, 0x481b,
+       0x080c, 0x650d, 0x080c, 0x48c6, 0x20a3, 0x1102, 0x20a3, 0x0000,
+       0x20a9, 0x000a, 0x20a3, 0x0000, 0x1f04, 0x43c2, 0x60c3, 0x0014,
+       0x080c, 0x4845, 0x0005, 0x00f6, 0x7080, 0xa005, 0x01f0, 0x2011,
+       0x481b, 0x080c, 0x650d, 0xa086, 0x0014, 0x11a8, 0x2079, 0xb280,
+       0x7a30, 0xa296, 0x1102, 0x1178, 0x7834, 0xa005, 0x1160, 0x7a38,
+       0xd2fc, 0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001, 0x708b,
+       0x0004, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe, 0x0005, 0x708b,
+       0x0005, 0x080c, 0x48c6, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430,
+       0x2011, 0xb28e, 0x080c, 0x4917, 0x1160, 0x7074, 0xa005, 0x1148,
+       0x714c, 0xa186, 0xffff, 0x0128, 0x080c, 0x47df, 0x0110, 0x080c,
+       0x48f5, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x4845, 0x0005, 0x00f6,
+       0x7080, 0xa005, 0x01f0, 0x2011, 0x481b, 0x080c, 0x650d, 0xa086,
+       0x0014, 0x11a8, 0x2079, 0xb280, 0x7a30, 0xa296, 0x1103, 0x1178,
+       0x7834, 0xa005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005,
+       0x1110, 0x70b7, 0x0001, 0x708b, 0x0006, 0x0029, 0x0010, 0x080c,
+       0x485e, 0x00fe, 0x0005, 0x708b, 0x0007, 0x080c, 0x48c6, 0x20a3,
+       0x1104, 0x20a3, 0x0000, 0x3430, 0x2011, 0xb28e, 0x080c, 0x4917,
+       0x11a8, 0x7074, 0xa005, 0x1190, 0x7154, 0xa186, 0xffff, 0x0170,
+       0xa180, 0x2be6, 0x200d, 0xa18c, 0xff00, 0x810f, 0x080c, 0x47df,
+       0x0128, 0x080c, 0x3e66, 0x0110, 0x080c, 0x26c0, 0x20a9, 0x0008,
+       0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
+       0x0014, 0x080c, 0x4845, 0x0005, 0x00f6, 0x7080, 0xa005, 0x01f0,
+       0x2011, 0x481b, 0x080c, 0x650d, 0xa086, 0x0014, 0x11a8, 0x2079,
+       0xb280, 0x7a30, 0xa296, 0x1104, 0x1178, 0x7834, 0xa005, 0x1160,
+       0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001,
+       0x708b, 0x0008, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe, 0x0005,
+       0x708b, 0x0009, 0x080c, 0x48c6, 0x20a3, 0x1105, 0x20a3, 0x0100,
+       0x3430, 0x080c, 0x4917, 0x1150, 0x7074, 0xa005, 0x1138, 0x080c,
+       0x4754, 0x1170, 0xa085, 0x0001, 0x080c, 0x26c0, 0x20a9, 0x0008,
+       0x2099, 0xb28e, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
+       0x60c3, 0x0014, 0x080c, 0x4845, 0x0010, 0x080c, 0x436e, 0x0005,
+       0x00f6, 0x7080, 0xa005, 0x0588, 0x2011, 0x481b, 0x080c, 0x650d,
+       0xa086, 0x0014, 0x1540, 0x2079, 0xb280, 0x7a30, 0xa296, 0x1105,
+       0x1510, 0x7834, 0x2011, 0x0100, 0xa21e, 0x1160, 0x7a38, 0xd2fc,
+       0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001, 0x708b, 0x000a,
+       0x00b1, 0x0098, 0xa005, 0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70b4,
+       0xa005, 0x1110, 0x70b7, 0x0001, 0x7087, 0x0000, 0x708b, 0x000e,
+       0x080c, 0x4569, 0x0010, 0x080c, 0x485e, 0x00fe, 0x0005, 0x708b,
+       0x000b, 0x2011, 0xb20e, 0x22a0, 0x20a9, 0x0040, 0x2019, 0xffff,
+       0x43a4, 0x20a9, 0x0002, 0x2009, 0x0000, 0x41a4, 0x080c, 0x48c6,
+       0x20a3, 0x1106, 0x20a3, 0x0000, 0x080c, 0x4917, 0x0118, 0x2013,
+       0x0000, 0x0020, 0x7050, 0xa085, 0x0100, 0x2012, 0x2298, 0x20a9,
+       0x0042, 0x53a6, 0x60c3, 0x0084, 0x080c, 0x4845, 0x0005, 0x00f6,
+       0x7080, 0xa005, 0x01b0, 0x2011, 0x481b, 0x080c, 0x650d, 0xa086,
+       0x0084, 0x1168, 0x2079, 0xb280, 0x7a30, 0xa296, 0x1106, 0x1138,
+       0x7834, 0xa005, 0x1120, 0x708b, 0x000c, 0x0029, 0x0010, 0x080c,
+       0x485e, 0x00fe, 0x0005, 0x708b, 0x000d, 0x080c, 0x48c6, 0x20a3,
+       0x1107, 0x20a3, 0x0000, 0x2099, 0xb28e, 0x20a9, 0x0040, 0x53a6,
+       0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x080c, 0x4845,
+       0x0005, 0x00f6, 0x7080, 0xa005, 0x01d0, 0x2011, 0x481b, 0x080c,
+       0x650d, 0xa086, 0x0084, 0x1188, 0x2079, 0xb280, 0x7a30, 0xa296,
+       0x1107, 0x1158, 0x7834, 0xa005, 0x1140, 0x7087, 0x0001, 0x080c,
+       0x48b8, 0x708b, 0x000e, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe,
+       0x0005, 0x708b, 0x000f, 0x7083, 0x0000, 0x608b, 0xbc85, 0x608f,
+       0xb5b5, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011,
+       0x481b, 0x080c, 0x6501, 0x0005, 0x7080, 0xa005, 0x0120, 0x2011,
+       0x481b, 0x080c, 0x650d, 0x0005, 0x708b, 0x0011, 0x080c, 0x4917,
+       0x1188, 0x716c, 0x81ff, 0x0170, 0x2009, 0x0000, 0x7070, 0xa084,
+       0x00ff, 0x080c, 0x2676, 0xa186, 0x0080, 0x0120, 0x2011, 0xb28e,
+       0x080c, 0x47df, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xb280,
+       0x20a1, 0x020b, 0x7480, 0xa480, 0x0018, 0xa080, 0x0007, 0xa084,
+       0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0014, 0x080c, 0x4845,
+       0x0005, 0x00f6, 0x7080, 0xa005, 0x01f0, 0x2011, 0x481b, 0x080c,
+       0x650d, 0xa086, 0x0014, 0x11a8, 0x2079, 0xb280, 0x7a30, 0xa296,
+       0x1103, 0x1178, 0x7834, 0xa005, 0x1160, 0x7a38, 0xd2fc, 0x0128,
+       0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001, 0x708b, 0x0012, 0x0029,
+       0x0010, 0x080c, 0x485e, 0x00fe, 0x0005, 0x708b, 0x0013, 0x080c,
+       0x48d2, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011, 0xb28e,
+       0x080c, 0x4917, 0x1160, 0x7074, 0xa005, 0x1148, 0x714c, 0xa186,
+       0xffff, 0x0128, 0x080c, 0x47df, 0x0110, 0x080c, 0x48f5, 0x20a9,
+       0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
+       0x60c3, 0x0014, 0x080c, 0x4845, 0x0005, 0x00f6, 0x7080, 0xa005,
+       0x01f0, 0x2011, 0x481b, 0x080c, 0x650d, 0xa086, 0x0014, 0x11a8,
+       0x2079, 0xb280, 0x7a30, 0xa296, 0x1104, 0x1178, 0x7834, 0xa005,
+       0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7,
+       0x0001, 0x708b, 0x0014, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe,
+       0x0005, 0x708b, 0x0015, 0x080c, 0x48d2, 0x20a3, 0x1104, 0x20a3,
+       0x0000, 0x3430, 0x2011, 0xb28e, 0x080c, 0x4917, 0x11a8, 0x7074,
+       0xa005, 0x1190, 0x7154, 0xa186, 0xffff, 0x0170, 0xa180, 0x2be6,
+       0x200d, 0xa18c, 0xff00, 0x810f, 0x080c, 0x47df, 0x0128, 0x080c,
+       0x3e66, 0x0110, 0x080c, 0x26c0, 0x20a9, 0x0008, 0x2298, 0x26a0,
+       0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c,
+       0x4845, 0x0005, 0x00f6, 0x7080, 0xa005, 0x05b8, 0x2011, 0x481b,
+       0x080c, 0x650d, 0xa086, 0x0014, 0x1570, 0x2079, 0xb280, 0x7a30,
+       0xa296, 0x1105, 0x1540, 0x7834, 0x2011, 0x0100, 0xa21e, 0x1148,
+       0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001,
+       0x0060, 0xa005, 0x11c0, 0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005,
+       0x1110, 0x70b7, 0x0001, 0x7087, 0x0000, 0x7a38, 0xd2f4, 0x0138,
+       0x2001, 0xad73, 0x2004, 0xd0a4, 0x1110, 0x70d3, 0x0008, 0x708b,
+       0x0016, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe, 0x0005, 0x20e1,
+       0x9080, 0x20e1, 0x4000, 0x2099, 0xb280, 0x20a1, 0x020b, 0x20a9,
+       0x000e, 0x53a6, 0x3430, 0x2011, 0xb28e, 0x708b, 0x0017, 0x080c,
+       0x4917, 0x1150, 0x7074, 0xa005, 0x1138, 0x080c, 0x4754, 0x1170,
+       0xa085, 0x0001, 0x080c, 0x26c0, 0x20a9, 0x0008, 0x2099, 0xb28e,
+       0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014,
+       0x080c, 0x4845, 0x0010, 0x080c, 0x436e, 0x0005, 0x00f6, 0x7080,
+       0xa005, 0x01b0, 0x2011, 0x481b, 0x080c, 0x650d, 0xa086, 0x0084,
+       0x1168, 0x2079, 0xb280, 0x7a30, 0xa296, 0x1106, 0x1138, 0x7834,
+       0xa005, 0x1120, 0x708b, 0x0018, 0x0029, 0x0010, 0x080c, 0x485e,
+       0x00fe, 0x0005, 0x708b, 0x0019, 0x080c, 0x48d2, 0x20a3, 0x1106,
+       0x20a3, 0x0000, 0x3430, 0x2099, 0xb28e, 0x2039, 0xb20e, 0x27a0,
+       0x20a9, 0x0040, 0x53a3, 0x080c, 0x4917, 0x11e8, 0x2728, 0x2514,
+       0x8207, 0xa084, 0x00ff, 0x8000, 0x2018, 0xa294, 0x00ff, 0x8007,
+       0xa205, 0x202a, 0x7050, 0x2310, 0x8214, 0xa2a0, 0xb20e, 0x2414,
+       0xa38c, 0x0001, 0x0118, 0xa294, 0xff00, 0x0018, 0xa294, 0x00ff,
+       0x8007, 0xa215, 0x2222, 0x2798, 0x26a0, 0x20a9, 0x0040, 0x53a6,
+       0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x080c, 0x4845,
+       0x0005, 0x00f6, 0x7080, 0xa005, 0x01d0, 0x2011, 0x481b, 0x080c,
+       0x650d, 0xa086, 0x0084, 0x1188, 0x2079, 0xb280, 0x7a30, 0xa296,
+       0x1107, 0x1158, 0x7834, 0xa005, 0x1140, 0x7087, 0x0001, 0x080c,
+       0x48b8, 0x708b, 0x001a, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe,
+       0x0005, 0x708b, 0x001b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099,
+       0xb280, 0x20a1, 0x020b, 0x7480, 0xa480, 0x0018, 0xa080, 0x0007,
+       0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0084, 0x080c,
+       0x4845, 0x0005, 0x0005, 0x0005, 0x0086, 0x0096, 0x2029, 0xad52,
+       0x252c, 0x20a9, 0x0008, 0x2041, 0xb20e, 0x28a0, 0x2099, 0xb28e,
+       0x53a3, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0110, 0x2011,
+       0x0000, 0x2800, 0xa200, 0x200c, 0xa1a6, 0xffff, 0x1148, 0xd5d4,
+       0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, 0x4769, 0x0804, 0x47d7,
+       0x82ff, 0x1160, 0xd5d4, 0x0120, 0xa1a6, 0x3fff, 0x0d90, 0x0020,
+       0xa1a6, 0x3fff, 0x0904, 0x47d7, 0xa18d, 0xc000, 0x20a9, 0x0010,
+       0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120, 0xd5d4,
+       0x0110, 0x8423, 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110, 0x8319,
+       0x0008, 0x8318, 0x1f04, 0x478f, 0x04d0, 0x23a8, 0x2021, 0x0001,
+       0x8426, 0x8425, 0x1f04, 0x47a1, 0x2328, 0x8529, 0xa2be, 0x0007,
+       0x0158, 0x0006, 0x2039, 0x0007, 0x2200, 0xa73a, 0x000e, 0x27a8,
+       0xa5a8, 0x0010, 0x1f04, 0x47b0, 0x754e, 0xa5c8, 0x2be6, 0x292d,
+       0xa5ac, 0x00ff, 0x7572, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c,
+       0x26a0, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x2018, 0x2304, 0xa405,
+       0x201a, 0x7077, 0x0001, 0x26a0, 0x2898, 0x20a9, 0x0008, 0x53a6,
+       0x20a3, 0x0000, 0x20a3, 0x0000, 0xa085, 0x0001, 0x0028, 0xa006,
+       0x0018, 0xa006, 0x080c, 0x14f6, 0x009e, 0x008e, 0x0005, 0x2118,
+       0x2021, 0x0000, 0x2001, 0x0007, 0xa39a, 0x0010, 0x0218, 0x8420,
+       0x8001, 0x0cd0, 0x2118, 0x84ff, 0x0120, 0xa39a, 0x0010, 0x8421,
+       0x1de0, 0x2021, 0x0001, 0x83ff, 0x0118, 0x8423, 0x8319, 0x1de8,
+       0xa238, 0x2704, 0xa42c, 0x11b8, 0xa405, 0x203a, 0x714e, 0xa1a0,
+       0x2be6, 0x242d, 0xa5ac, 0x00ff, 0x7572, 0x6532, 0x6536, 0x0016,
+       0x2508, 0x080c, 0x26a0, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x7077,
+       0x0001, 0xa084, 0x0000, 0x0005, 0x00e6, 0x2071, 0xad00, 0x707b,
+       0x0000, 0x00ee, 0x0005, 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071,
+       0x0140, 0x080c, 0x7834, 0x7004, 0xa084, 0x4000, 0x0120, 0x7003,
+       0x1000, 0x7003, 0x0000, 0x0126, 0x2091, 0x8000, 0x2071, 0xad22,
+       0x2073, 0x0000, 0x7840, 0x0026, 0x0016, 0x2009, 0x00f7, 0x080c,
+       0x48de, 0x001e, 0xa094, 0x0010, 0xa285, 0x0080, 0x7842, 0x7a42,
+       0x002e, 0x012e, 0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000,
+       0x2011, 0xafd1, 0x2013, 0x0000, 0x7083, 0x0000, 0x012e, 0x20e1,
+       0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x782b, 0x2009,
+       0x07d0, 0x2011, 0x481b, 0x080c, 0x6593, 0x0005, 0x0016, 0x0026,
+       0x00c6, 0x0126, 0x2091, 0x8000, 0x2009, 0x00f7, 0x080c, 0x48de,
+       0x2061, 0xafda, 0x601b, 0x0000, 0x601f, 0x0000, 0x2061, 0xad00,
+       0x6003, 0x0001, 0x2061, 0x0100, 0x6043, 0x0090, 0x6043, 0x0010,
+       0x2009, 0x002d, 0x2011, 0x4883, 0x080c, 0x6501, 0x012e, 0x00ce,
+       0x002e, 0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000,
+       0x2071, 0x0100, 0x080c, 0x7834, 0x2071, 0x0140, 0x7004, 0xa084,
+       0x4000, 0x0120, 0x7003, 0x1000, 0x7003, 0x0000, 0x080c, 0x5757,
+       0x01a8, 0x080c, 0x5775, 0x1190, 0x2001, 0xaf9d, 0x2003, 0xaaaa,
+       0x0016, 0x080c, 0x2744, 0x2001, 0xaf8e, 0x2102, 0x001e, 0x2001,
+       0xaf9e, 0x2003, 0x0000, 0x080c, 0x569a, 0x0030, 0x2001, 0x0001,
+       0x080c, 0x261e, 0x080c, 0x485e, 0x012e, 0x000e, 0x00ee, 0x0005,
+       0x20a9, 0x0040, 0x20a1, 0xb3c0, 0x2099, 0xb28e, 0x3304, 0x8007,
+       0x20a2, 0x9398, 0x94a0, 0x1f04, 0x48be, 0x0005, 0x20e1, 0x9080,
+       0x20e1, 0x4000, 0x2099, 0xb200, 0x20a1, 0x020b, 0x20a9, 0x000c,
+       0x53a6, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xb280,
+       0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6, 0x0005, 0x00c6, 0x0006,
+       0x2061, 0x0100, 0x810f, 0x2001, 0xad30, 0x2004, 0xa005, 0x1138,
+       0x2001, 0xad14, 0x2004, 0xa084, 0x00ff, 0xa105, 0x0010, 0xa185,
+       0x00f7, 0x604a, 0x000e, 0x00ce, 0x0005, 0x0016, 0x0046, 0x2001,
+       0xad52, 0x2004, 0xd0a4, 0x0158, 0xa006, 0x2020, 0x2009, 0x002a,
+       0x080c, 0xa96c, 0x2001, 0xad0c, 0x200c, 0xc195, 0x2102, 0x2019,
+       0x002a, 0x2009, 0x0000, 0x080c, 0x2aac, 0x004e, 0x001e, 0x0005,
+       0x080c, 0x485e, 0x708b, 0x0000, 0x7083, 0x0000, 0x0005, 0x0006,
+       0x2001, 0xad0c, 0x2004, 0xd09c, 0x0100, 0x000e, 0x0005, 0x0006,
+       0x0016, 0x0126, 0x2091, 0x8000, 0x2001, 0x0101, 0x200c, 0xa18d,
+       0x0006, 0x2102, 0x012e, 0x001e, 0x000e, 0x0005, 0x0156, 0x20a9,
+       0x00ff, 0x2009, 0xae34, 0xa006, 0x200a, 0x8108, 0x1f04, 0x4934,
+       0x015e, 0x0005, 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069,
+       0xad51, 0xa006, 0x6002, 0x6007, 0x0707, 0x600a, 0x600e, 0x6012,
+       0xa198, 0x2be6, 0x231d, 0xa39c, 0x00ff, 0x6316, 0x20a9, 0x0004,
+       0xac98, 0x0006, 0x23a0, 0x40a4, 0x20a9, 0x0004, 0xac98, 0x000a,
+       0x23a0, 0x40a4, 0x603e, 0x6042, 0x604e, 0x6052, 0x6056, 0x605a,
+       0x605e, 0x6062, 0x6066, 0x606a, 0x606e, 0x6072, 0x6076, 0x607a,
+       0x607e, 0x6082, 0x6086, 0x608a, 0x608e, 0x6092, 0x6096, 0x609a,
+       0x609e, 0x60ae, 0x61a2, 0x00d6, 0x60a4, 0xa06d, 0x0110, 0x080c,
+       0x15f0, 0x60a7, 0x0000, 0x60a8, 0xa06d, 0x0110, 0x080c, 0x15f0,
+       0x60ab, 0x0000, 0x00de, 0xa006, 0x604a, 0x6810, 0x603a, 0x680c,
+       0x6046, 0x6814, 0xa084, 0x00ff, 0x6042, 0x014e, 0x013e, 0x015e,
+       0x003e, 0x00de, 0x0005, 0x0126, 0x2091, 0x8000, 0x6944, 0x6e48,
+       0xa684, 0x3fff, 0xa082, 0x4000, 0x1a04, 0x4a49, 0xa18c, 0xff00,
+       0x810f, 0xa182, 0x00ff, 0x1a04, 0x4a4e, 0x2001, 0xad0c, 0x2004,
+       0xa084, 0x0003, 0x01c0, 0x2001, 0xad0c, 0x2004, 0xd084, 0x1904,
+       0x4a31, 0xa188, 0xae34, 0x2104, 0xa065, 0x0904, 0x4a31, 0x6004,
+       0xa084, 0x00ff, 0xa08e, 0x0006, 0x1904, 0x4a31, 0x6000, 0xd0c4,
+       0x0904, 0x4a31, 0x0068, 0xa188, 0xae34, 0x2104, 0xa065, 0x0904,
+       0x4a15, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x1904, 0x4a1a,
+       0x60a4, 0xa00d, 0x0118, 0x080c, 0x4ef9, 0x05d0, 0x60a8, 0xa00d,
+       0x0188, 0x080c, 0x4f43, 0x1170, 0x694c, 0xd1fc, 0x1118, 0x080c,
+       0x4c11, 0x0448, 0x080c, 0x4bd3, 0x694c, 0xd1ec, 0x1520, 0x080c,
+       0x4ded, 0x0408, 0x694c, 0xa184, 0xa000, 0x0178, 0xd1ec, 0x0140,
+       0xd1fc, 0x0118, 0x080c, 0x4dfc, 0x0028, 0x080c, 0x4dfc, 0x0028,
+       0xd1fc, 0x0118, 0x080c, 0x4bd3, 0x0070, 0x6050, 0xa00d, 0x0130,
+       0x2d00, 0x200a, 0x6803, 0x0000, 0x6052, 0x0028, 0x2d00, 0x6052,
+       0x604e, 0x6803, 0x0000, 0x080c, 0x67c5, 0xa006, 0x012e, 0x0005,
+       0x2001, 0x0005, 0x2009, 0x0000, 0x04e8, 0x2001, 0x0028, 0x2009,
+       0x0000, 0x04c0, 0xa082, 0x0006, 0x12a0, 0x2001, 0xad34, 0x2004,
+       0xd0ac, 0x1160, 0x60a0, 0xd0bc, 0x1148, 0x6100, 0xd1fc, 0x0904,
+       0x49d0, 0x2001, 0x0029, 0x2009, 0x1000, 0x0420, 0x2001, 0x0028,
+       0x00a8, 0x2009, 0xad0c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004,
+       0x0068, 0xd184, 0x0118, 0x2001, 0x0004, 0x0040, 0x2001, 0x0029,
+       0x6100, 0xd1fc, 0x0118, 0x2009, 0x1000, 0x0060, 0x2009, 0x0000,
+       0x0048, 0x2001, 0x0029, 0x2009, 0x0000, 0x0020, 0x2001, 0x0029,
+       0x2009, 0x0000, 0xa005, 0x012e, 0x0005, 0x00e6, 0x0126, 0x2091,
+       0x8000, 0x6844, 0x8007, 0xa084, 0x00ff, 0x2008, 0xa182, 0x00ff,
+       0x1a04, 0x4aa8, 0xa188, 0xae34, 0x2104, 0xa065, 0x01c0, 0x6004,
+       0xa084, 0x00ff, 0xa08e, 0x0006, 0x11a8, 0x2c70, 0x080c, 0x8022,
+       0x05e8, 0x2e00, 0x601a, 0x2d00, 0x6012, 0x600b, 0xffff, 0x601f,
+       0x000a, 0x2009, 0x0003, 0x080c, 0x80a7, 0xa006, 0x0460, 0x2001,
+       0x0028, 0x0440, 0xa082, 0x0006, 0x1298, 0x2001, 0xad34, 0x2004,
+       0xd0ac, 0x1158, 0x60a0, 0xd0bc, 0x1140, 0x6100, 0xd1fc, 0x09e8,
+       0x2001, 0x0029, 0x2009, 0x1000, 0x00a8, 0x2001, 0x0028, 0x0090,
+       0x2009, 0xad0c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0050,
+       0xd184, 0x0118, 0x2001, 0x0004, 0x0028, 0x2001, 0x0029, 0x0010,
+       0x2001, 0x0029, 0xa005, 0x012e, 0x00ee, 0x0005, 0x2001, 0x002c,
+       0x0cc8, 0x00f6, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2011, 0x0000,
+       0x2079, 0xad00, 0x6944, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff,
+       0x1a04, 0x4b77, 0x2001, 0xad0c, 0x2004, 0xa084, 0x0003, 0x1904,
+       0x4b65, 0x080c, 0x4cdc, 0x1180, 0x6004, 0xa084, 0x00ff, 0xa082,
+       0x0006, 0x1250, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x1904, 0x4b60,
+       0x60a0, 0xd0bc, 0x1904, 0x4b60, 0x6864, 0xa0c6, 0x006f, 0x0118,
+       0x2008, 0x0804, 0x4b28, 0x6968, 0x2140, 0xa18c, 0xff00, 0x810f,
+       0x78d0, 0xd0ac, 0x1118, 0xa182, 0x0080, 0x06d0, 0xa182, 0x00ff,
+       0x16b8, 0x6a70, 0x6b6c, 0x786c, 0xa306, 0x1160, 0x7870, 0xa24e,
+       0x1118, 0x2208, 0x2310, 0x0460, 0xa9cc, 0xff00, 0x1118, 0x2208,
+       0x2310, 0x0430, 0x080c, 0x3b58, 0x2c70, 0x0550, 0x2009, 0x0000,
+       0x2011, 0x0000, 0xa0c6, 0x4000, 0x1160, 0x0006, 0x2e60, 0x080c,
+       0x4f6e, 0x1108, 0xc185, 0x7000, 0xd0bc, 0x0108, 0xc18d, 0x000e,
+       0x0088, 0xa0c6, 0x4007, 0x1110, 0x2408, 0x0060, 0xa0c6, 0x4008,
+       0x1118, 0x2708, 0x2610, 0x0030, 0xa0c6, 0x4009, 0x1108, 0x0010,
+       0x2001, 0x4006, 0x6866, 0x696a, 0x6a6e, 0x2001, 0x0030, 0x0458,
+       0x080c, 0x8022, 0x1138, 0x2001, 0x4005, 0x2009, 0x0003, 0x2011,
+       0x0000, 0x0c80, 0x2e00, 0x601a, 0x080c, 0x9956, 0x2d00, 0x6012,
+       0x601f, 0x0001, 0xa006, 0xd88c, 0x0110, 0x2001, 0x4000, 0x683a,
+       0x0126, 0x2091, 0x8000, 0x080c, 0x2ad9, 0x012e, 0x2001, 0x0000,
+       0x080c, 0x4c1e, 0x2001, 0x0002, 0x080c, 0x4c30, 0x2009, 0x0002,
+       0x080c, 0x80a7, 0xa006, 0xa005, 0x012e, 0x00ee, 0x00fe, 0x0005,
+       0x2001, 0x0028, 0x2009, 0x0000, 0x0cb0, 0x2009, 0xad0c, 0x210c,
+       0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001,
+       0x0004, 0x0010, 0x2001, 0x0029, 0x2009, 0x0000, 0x0c20, 0x2001,
+       0x0029, 0x2009, 0x0000, 0x08f8, 0x6944, 0x6e48, 0xa684, 0x3fff,
+       0xa082, 0x4000, 0x16b8, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff,
+       0x12e0, 0xa188, 0xae34, 0x2104, 0xa065, 0x01b8, 0x6004, 0xa084,
+       0x00ff, 0xa08e, 0x0006, 0x11b0, 0x684c, 0xd0ec, 0x0120, 0x080c,
+       0x4dfc, 0x04c9, 0x0030, 0x04b9, 0x684c, 0xd0fc, 0x0110, 0x080c,
+       0x4ded, 0x080c, 0x4e3a, 0xa006, 0x00c8, 0x2001, 0x0028, 0x2009,
+       0x0000, 0x00a0, 0xa082, 0x0006, 0x1240, 0x6100, 0xd1fc, 0x0d20,
+       0x2001, 0x0029, 0x2009, 0x1000, 0x0048, 0x2001, 0x0029, 0x2009,
+       0x0000, 0x0020, 0x2001, 0x0029, 0x2009, 0x0000, 0xa005, 0x0005,
+       0x0126, 0x2091, 0x8000, 0x6050, 0xa00d, 0x0138, 0x2d00, 0x200a,
+       0x6803, 0x0000, 0x6052, 0x012e, 0x0005, 0x2d00, 0x6052, 0x604e,
+       0x6803, 0x0000, 0x0cc0, 0x0126, 0x2091, 0x8000, 0x604c, 0xa005,
+       0x0170, 0x00e6, 0x2071, 0xafc7, 0x7004, 0xa086, 0x0002, 0x0168,
+       0x00ee, 0x604c, 0x6802, 0x2d00, 0x604e, 0x012e, 0x0005, 0x2d00,
+       0x6052, 0x604e, 0x6803, 0x0000, 0x0cc0, 0x701c, 0xac06, 0x1d80,
+       0x604c, 0x2070, 0x7000, 0x6802, 0x2d00, 0x7002, 0x00ee, 0x012e,
+       0x0005, 0x0126, 0x2091, 0x8000, 0x604c, 0xa06d, 0x0130, 0x6800,
+       0xa005, 0x1108, 0x6052, 0x604e, 0xad05, 0x012e, 0x0005, 0x604c,
+       0xa06d, 0x0130, 0x6800, 0xa005, 0x1108, 0x6052, 0x604e, 0xad05,
+       0x0005, 0x6803, 0x0000, 0x6084, 0xa00d, 0x0120, 0x2d00, 0x200a,
+       0x6086, 0x0005, 0x2d00, 0x6086, 0x6082, 0x0cd8, 0x0126, 0x00c6,
+       0x0026, 0x2091, 0x8000, 0x6218, 0x2260, 0x6200, 0xa005, 0x0110,
+       0xc285, 0x0008, 0xc284, 0x6202, 0x002e, 0x00ce, 0x012e, 0x0005,
+       0x0126, 0x00c6, 0x2091, 0x8000, 0x6218, 0x2260, 0x6204, 0x0006,
+       0xa086, 0x0006, 0x1180, 0x609c, 0xd0ac, 0x0168, 0x2001, 0xad52,
+       0x2004, 0xd0a4, 0x0140, 0xa284, 0xff00, 0x8007, 0xa086, 0x0007,
+       0x1110, 0x2011, 0x0600, 0x000e, 0xa294, 0xff00, 0xa215, 0x6206,
+       0x0006, 0xa086, 0x0006, 0x1128, 0x6290, 0x82ff, 0x1110, 0x080c,
+       0x14f6, 0x000e, 0x00ce, 0x012e, 0x0005, 0x0126, 0x00c6, 0x2091,
+       0x8000, 0x6218, 0x2260, 0x6204, 0x0006, 0xa086, 0x0006, 0x1178,
+       0x609c, 0xd0a4, 0x0160, 0x2001, 0xad52, 0x2004, 0xd0ac, 0x1138,
+       0xa284, 0x00ff, 0xa086, 0x0007, 0x1110, 0x2011, 0x0006, 0x000e,
+       0xa294, 0x00ff, 0x8007, 0xa215, 0x6206, 0x00ce, 0x012e, 0x0005,
+       0x0026, 0xa182, 0x00ff, 0x0218, 0xa085, 0x0001, 0x00b0, 0xa190,
+       0xae34, 0x2204, 0xa065, 0x1180, 0x0016, 0x00d6, 0x080c, 0x15c0,
+       0x2d60, 0x00de, 0x001e, 0x0d80, 0x2c00, 0x2012, 0x60a7, 0x0000,
+       0x60ab, 0x0000, 0x080c, 0x493a, 0xa006, 0x002e, 0x0005, 0x0126,
+       0x2091, 0x8000, 0x0026, 0xa182, 0x00ff, 0x0218, 0xa085, 0x0001,
+       0x0480, 0x00d6, 0xa190, 0xae34, 0x2204, 0xa06d, 0x0540, 0x2013,
+       0x0000, 0x00d6, 0x00c6, 0x2d60, 0x60a4, 0xa06d, 0x0110, 0x080c,
+       0x15f0, 0x60a8, 0xa06d, 0x0110, 0x080c, 0x15f0, 0x00ce, 0x00de,
+       0x00d6, 0x00c6, 0x68ac, 0x2060, 0x8cff, 0x0168, 0x600c, 0x0006,
+       0x6010, 0x2068, 0x080c, 0x9596, 0x0110, 0x080c, 0x1600, 0x080c,
+       0x8078, 0x00ce, 0x0c88, 0x00ce, 0x00de, 0x080c, 0x15f0, 0x00de,
+       0xa006, 0x002e, 0x012e, 0x0005, 0x0016, 0xa182, 0x00ff, 0x0218,
+       0xa085, 0x0001, 0x0030, 0xa188, 0xae34, 0x2104, 0xa065, 0x0dc0,
+       0xa006, 0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x600b,
+       0x0000, 0x600f, 0x0000, 0x6000, 0xc08c, 0x6002, 0x080c, 0x574f,
+       0x1538, 0x60a0, 0xa086, 0x007e, 0x2069, 0xb290, 0x0130, 0x2001,
+       0xad34, 0x2004, 0xd0ac, 0x11e0, 0x0098, 0x2d04, 0xd0e4, 0x01c0,
+       0x00d6, 0x2069, 0xb28e, 0x00c6, 0x2061, 0xaf9f, 0x6810, 0x2062,
+       0x6814, 0x6006, 0x6818, 0x600a, 0x681c, 0x600e, 0x00ce, 0x00de,
+       0x8d69, 0x2d04, 0x2069, 0x0140, 0x6886, 0x2069, 0xad00, 0x68a2,
+       0x2069, 0xb28e, 0x6808, 0x605e, 0x6810, 0x6062, 0x6138, 0xa10a,
+       0x0208, 0x603a, 0x6814, 0x6066, 0x2099, 0xb296, 0xac88, 0x000a,
+       0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2099, 0xb29a, 0xac88, 0x0006,
+       0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2069, 0xb2ae, 0x6808, 0x606a,
+       0x690c, 0x616e, 0x6810, 0x6072, 0x6818, 0x6076, 0xa182, 0x0211,
+       0x1218, 0x2009, 0x0008, 0x0400, 0xa182, 0x0259, 0x1218, 0x2009,
+       0x0007, 0x00d0, 0xa182, 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0,
+       0xa182, 0x0349, 0x1218, 0x2009, 0x0005, 0x0070, 0xa182, 0x0421,
+       0x1218, 0x2009, 0x0004, 0x0040, 0xa182, 0x0581, 0x1218, 0x2009,
+       0x0003, 0x0010, 0x2009, 0x0002, 0x6192, 0x014e, 0x013e, 0x015e,
+       0x00de, 0x0005, 0x0016, 0x0026, 0x00e6, 0x2071, 0xb28d, 0x2e04,
+       0x6896, 0x2071, 0xb28e, 0x7004, 0x689a, 0x701c, 0x689e, 0x6a00,
+       0x2009, 0xad71, 0x210c, 0xd0bc, 0x0120, 0xd1ec, 0x0110, 0xc2ad,
+       0x0008, 0xc2ac, 0xd0c4, 0x0120, 0xd1e4, 0x0110, 0xc2bd, 0x0008,
+       0xc2bc, 0x6a02, 0x00ee, 0x002e, 0x001e, 0x0005, 0x00d6, 0x0126,
+       0x2091, 0x8000, 0x60a4, 0xa06d, 0x01c0, 0x6900, 0x81ff, 0x1540,
+       0x6a04, 0xa282, 0x0010, 0x1648, 0xad88, 0x0004, 0x20a9, 0x0010,
+       0x2104, 0xa086, 0xffff, 0x0128, 0x8108, 0x1f04, 0x4da8, 0x080c,
+       0x14f6, 0x260a, 0x8210, 0x6a06, 0x0098, 0x080c, 0x15d9, 0x01a8,
+       0x2d00, 0x60a6, 0x6803, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010,
+       0x200b, 0xffff, 0x8108, 0x1f04, 0x4dc0, 0x6807, 0x0001, 0x6e12,
+       0xa085, 0x0001, 0x012e, 0x00de, 0x0005, 0xa006, 0x0cd8, 0x0126,
+       0x2091, 0x8000, 0x00d6, 0x60a4, 0xa00d, 0x01a0, 0x2168, 0x6800,
+       0xa005, 0x1160, 0x080c, 0x4ef9, 0x1168, 0x200b, 0xffff, 0x6804,
+       0xa08a, 0x0002, 0x0218, 0x8001, 0x6806, 0x0020, 0x080c, 0x15f0,
+       0x60a7, 0x0000, 0x00de, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000,
+       0x080c, 0x4f56, 0x0010, 0x080c, 0x4bc0, 0x080c, 0x4e71, 0x1dd8,
+       0x080c, 0x4e3a, 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000,
+       0x60a8, 0xa06d, 0x01c0, 0x6950, 0x81ff, 0x1540, 0x6a54, 0xa282,
+       0x0010, 0x1670, 0xad88, 0x0018, 0x20a9, 0x0010, 0x2104, 0xa086,
+       0xffff, 0x0128, 0x8108, 0x1f04, 0x4e0e, 0x080c, 0x14f6, 0x260a,
+       0x8210, 0x6a56, 0x0098, 0x080c, 0x15d9, 0x01d0, 0x2d00, 0x60aa,
+       0x6853, 0x0000, 0xad88, 0x0018, 0x20a9, 0x0010, 0x200b, 0xffff,
+       0x8108, 0x1f04, 0x4e26, 0x6857, 0x0001, 0x6e62, 0x0010, 0x080c,
+       0x4c11, 0x0089, 0x1de0, 0xa085, 0x0001, 0x012e, 0x00de, 0x0005,
+       0xa006, 0x0cd8, 0x0126, 0x2091, 0x8000, 0x080c, 0x67c5, 0x012e,
+       0x0005, 0xa01e, 0x0010, 0x2019, 0x0001, 0xa00e, 0x0126, 0x2091,
+       0x8000, 0x604c, 0x2068, 0x6000, 0xd0dc, 0x1170, 0x8dff, 0x01e8,
+       0x83ff, 0x0120, 0x6848, 0xa606, 0x0158, 0x0030, 0x683c, 0xa406,
+       0x1118, 0x6840, 0xa506, 0x0120, 0x2d08, 0x6800, 0x2068, 0x0c70,
+       0x6a00, 0x604c, 0xad06, 0x1110, 0x624e, 0x0018, 0xa180, 0x0000,
+       0x2202, 0x82ff, 0x1110, 0x6152, 0x8dff, 0x012e, 0x0005, 0xa01e,
+       0x0010, 0x2019, 0x0001, 0xa00e, 0x6080, 0x2068, 0x8dff, 0x01e8,
+       0x83ff, 0x0120, 0x6848, 0xa606, 0x0158, 0x0030, 0x683c, 0xa406,
+       0x1118, 0x6840, 0xa506, 0x0120, 0x2d08, 0x6800, 0x2068, 0x0c70,
+       0x6a00, 0x6080, 0xad06, 0x1110, 0x6282, 0x0018, 0xa180, 0x0000,
+       0x2202, 0x82ff, 0x1110, 0x6186, 0x8dff, 0x0005, 0xa016, 0x080c,
+       0x4ef3, 0x1110, 0x2011, 0x0001, 0x080c, 0x4f3d, 0x1110, 0xa295,
+       0x0002, 0x0005, 0x080c, 0x4f6e, 0x0118, 0x080c, 0x964b, 0x0010,
+       0xa085, 0x0001, 0x0005, 0x080c, 0x4f6e, 0x0118, 0x080c, 0x95e4,
+       0x0010, 0xa085, 0x0001, 0x0005, 0x080c, 0x4f6e, 0x0118, 0x080c,
+       0x962e, 0x0010, 0xa085, 0x0001, 0x0005, 0x080c, 0x4f6e, 0x0118,
+       0x080c, 0x9600, 0x0010, 0xa085, 0x0001, 0x0005, 0x080c, 0x4f6e,
+       0x0118, 0x080c, 0x9667, 0x0010, 0xa085, 0x0001, 0x0005, 0x0126,
+       0x0006, 0x00d6, 0x2091, 0x8000, 0x6080, 0xa06d, 0x01a0, 0x6800,
+       0x0006, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x97fd,
+       0x0006, 0x6000, 0xd0fc, 0x0110, 0x080c, 0xac03, 0x000e, 0x080c,
+       0x510c, 0x000e, 0x0c50, 0x6083, 0x0000, 0x6087, 0x0000, 0x00de,
+       0x000e, 0x012e, 0x0005, 0x60a4, 0xa00d, 0x1118, 0xa085, 0x0001,
+       0x0005, 0x00e6, 0x2170, 0x7000, 0xa005, 0x1160, 0x20a9, 0x0010,
+       0xae88, 0x0004, 0x2104, 0xa606, 0x0128, 0x8108, 0x1f04, 0x4f02,
+       0xa085, 0x0001, 0xa006, 0x00ee, 0x0005, 0x00d6, 0x0126, 0x2091,
+       0x8000, 0x60a4, 0xa06d, 0x1128, 0x080c, 0x15d9, 0x01a0, 0x2d00,
+       0x60a6, 0x6803, 0x0001, 0x6807, 0x0000, 0xad88, 0x0004, 0x20a9,
+       0x0010, 0x200b, 0xffff, 0x8108, 0x1f04, 0x4f21, 0xa085, 0x0001,
+       0x012e, 0x00de, 0x0005, 0xa006, 0x0cd8, 0x00d6, 0x0126, 0x2091,
+       0x8000, 0x60a4, 0xa06d, 0x0130, 0x60a7, 0x0000, 0x080c, 0x15f0,
+       0xa085, 0x0001, 0x012e, 0x00de, 0x0005, 0x60a8, 0xa00d, 0x1118,
+       0xa085, 0x0001, 0x0005, 0x00e6, 0x2170, 0x7050, 0xa005, 0x1160,
+       0x20a9, 0x0010, 0xae88, 0x0018, 0x2104, 0xa606, 0x0128, 0x8108,
+       0x1f04, 0x4f4c, 0xa085, 0x0001, 0x00ee, 0x0005, 0x0126, 0x2091,
+       0x8000, 0x0c19, 0x1188, 0x200b, 0xffff, 0x00d6, 0x60a8, 0x2068,
+       0x6854, 0xa08a, 0x0002, 0x0218, 0x8001, 0x6856, 0x0020, 0x080c,
+       0x15f0, 0x60ab, 0x0000, 0x00de, 0x012e, 0x0005, 0x609c, 0xd0a4,
+       0x0005, 0x00f6, 0x080c, 0x574f, 0x01b0, 0x71b4, 0x81ff, 0x1198,
+       0x71d0, 0xd19c, 0x0180, 0x2001, 0x007e, 0xa080, 0xae34, 0x2004,
+       0xa07d, 0x0148, 0x7804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1118,
+       0x7800, 0xc0ed, 0x7802, 0x2079, 0xad51, 0x7804, 0xd0a4, 0x01e8,
+       0x0156, 0x00c6, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x080c,
+       0x4cdc, 0x1168, 0x6004, 0xa084, 0xff00, 0x8007, 0xa096, 0x0004,
+       0x0118, 0xa086, 0x0006, 0x1118, 0x6000, 0xc0ed, 0x6002, 0x001e,
+       0x8108, 0x1f04, 0x4f96, 0x00ce, 0x015e, 0x080c, 0x502d, 0x0120,
+       0x2001, 0xafa2, 0x200c, 0x0038, 0x2079, 0xad51, 0x7804, 0xd0a4,
+       0x0130, 0x2009, 0x07d0, 0x2011, 0x4fc1, 0x080c, 0x6593, 0x00fe,
+       0x0005, 0x2011, 0x4fc1, 0x080c, 0x650d, 0x080c, 0x502d, 0x01f0,
+       0x2001, 0xaeb2, 0x2004, 0xa080, 0x0000, 0x200c, 0xc1ec, 0x2102,
+       0x2001, 0xad52, 0x2004, 0xd0a4, 0x0130, 0x2009, 0x07d0, 0x2011,
+       0x4fc1, 0x080c, 0x6593, 0x00e6, 0x2071, 0xad00, 0x706f, 0x0000,
+       0x7073, 0x0000, 0x080c, 0x28fa, 0x00ee, 0x04b0, 0x0156, 0x00c6,
+       0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x4cdc, 0x1530,
+       0x6000, 0xd0ec, 0x0518, 0x0046, 0x62a0, 0xa294, 0x00ff, 0x8227,
+       0xa006, 0x2009, 0x0029, 0x080c, 0xa96c, 0x6000, 0xc0e5, 0xc0ec,
+       0x6002, 0x6004, 0xa084, 0x00ff, 0xa085, 0x0700, 0x6006, 0x2019,
+       0x0029, 0x080c, 0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d,
+       0x2009, 0x0000, 0x080c, 0xa712, 0x007e, 0x004e, 0x001e, 0x8108,
+       0x1f04, 0x4fec, 0x00ce, 0x015e, 0x0005, 0x00c6, 0x6018, 0x2060,
+       0x6000, 0xc0ec, 0x6002, 0x00ce, 0x0005, 0x7818, 0x2004, 0xd0ac,
+       0x0005, 0x7818, 0x2004, 0xd0bc, 0x0005, 0x00f6, 0x2001, 0xaeb2,
+       0x2004, 0xa07d, 0x0110, 0x7800, 0xd0ec, 0x00fe, 0x0005, 0x0126,
+       0x0026, 0x2091, 0x8000, 0x6200, 0xa005, 0x0110, 0xc2fd, 0x0008,
+       0xc2fc, 0x6202, 0x002e, 0x012e, 0x0005, 0x2071, 0xae13, 0x7003,
+       0x0001, 0x7007, 0x0000, 0x7013, 0x0000, 0x7017, 0x0000, 0x701b,
+       0x0000, 0x701f, 0x0000, 0x700b, 0x0000, 0x704b, 0x0001, 0x704f,
+       0x0000, 0x705b, 0x0020, 0x705f, 0x0040, 0x707f, 0x0000, 0x2071,
+       0xaf7c, 0x7003, 0xae13, 0x7007, 0x0000, 0x700b, 0x0000, 0x700f,
+       0xaf5c, 0x7013, 0x0020, 0x7017, 0x0040, 0x7037, 0x0000, 0x0005,
+       0x0016, 0x00e6, 0x2071, 0xaf34, 0xa00e, 0x7186, 0x718a, 0x7097,
+       0x0001, 0x2001, 0xad52, 0x2004, 0xd0fc, 0x1150, 0x2001, 0xad52,
+       0x2004, 0xa00e, 0xd09c, 0x0108, 0x8108, 0x7102, 0x0804, 0x50d6,
+       0x2001, 0xad71, 0x200c, 0xa184, 0x000f, 0x2009, 0xad72, 0x210c,
+       0x0002, 0x507e, 0x50b1, 0x50b8, 0x50c2, 0x50c7, 0x507e, 0x507e,
+       0x507e, 0x50a1, 0x507e, 0x507e, 0x507e, 0x507e, 0x507e, 0x507e,
+       0x507e, 0x7003, 0x0004, 0x0136, 0x0146, 0x0156, 0x2099, 0xad75,
+       0x20a1, 0xaf85, 0x20a9, 0x0004, 0x53a3, 0x015e, 0x014e, 0x013e,
+       0x0428, 0x708f, 0x0005, 0x7007, 0x0122, 0x2001, 0x0002, 0x0030,
+       0x708f, 0x0002, 0x7007, 0x0121, 0x2001, 0x0003, 0x7002, 0x7097,
+       0x0001, 0x0088, 0x7007, 0x0122, 0x2001, 0x0002, 0x0020, 0x7007,
+       0x0121, 0x2001, 0x0003, 0x7002, 0xa006, 0x7096, 0x708e, 0xa184,
+       0xff00, 0x8007, 0x709a, 0xa184, 0x00ff, 0x7092, 0x00ee, 0x001e,
+       0x0005, 0x00e6, 0x2071, 0xae13, 0x684c, 0xa005, 0x1130, 0x7028,
+       0xc085, 0x702a, 0xa085, 0x0001, 0x0428, 0x6a60, 0x7236, 0x6b64,
+       0x733a, 0x6868, 0x703e, 0x7076, 0x686c, 0x7042, 0x707a, 0x684c,
+       0x702e, 0x6844, 0x7032, 0x2009, 0x000d, 0x200a, 0x700b, 0x0000,
+       0x8007, 0x8006, 0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210,
+       0x2100, 0xa319, 0x726e, 0x7372, 0x7028, 0xc084, 0x702a, 0x7007,
+       0x0001, 0xa006, 0x00ee, 0x0005, 0x0156, 0x00e6, 0x0026, 0x6838,
+       0xd0fc, 0x1904, 0x5165, 0x6804, 0xa00d, 0x0188, 0x00d6, 0x2071,
+       0xad00, 0xa016, 0x702c, 0x2168, 0x6904, 0x206a, 0x8210, 0x2d00,
+       0x81ff, 0x1dc8, 0x702e, 0x70b0, 0xa200, 0x70b2, 0x00de, 0x2071,
+       0xae13, 0x701c, 0xa005, 0x1904, 0x5175, 0x20a9, 0x0032, 0x0f04,
+       0x5173, 0x0e04, 0x512f, 0x2071, 0xaf34, 0x7200, 0x82ff, 0x05d8,
+       0x6934, 0xa186, 0x0103, 0x1904, 0x5183, 0x6948, 0x6844, 0xa105,
+       0x1540, 0x2009, 0x8020, 0x2200, 0x0002, 0x5173, 0x514a, 0x519b,
+       0x51a7, 0x5173, 0x2071, 0x0000, 0x20a9, 0x0032, 0x0f04, 0x5173,
+       0x7018, 0xd084, 0x1dd8, 0x7122, 0x683c, 0x7026, 0x6840, 0x702a,
+       0x701b, 0x0001, 0x2091, 0x4080, 0x2071, 0xad00, 0x702c, 0x206a,
+       0x2d00, 0x702e, 0x70b0, 0x8000, 0x70b2, 0x002e, 0x00ee, 0x015e,
+       0x0005, 0x6844, 0xa086, 0x0100, 0x1130, 0x6868, 0xa005, 0x1118,
+       0x2009, 0x8020, 0x0880, 0x2071, 0xae13, 0x2d08, 0x206b, 0x0000,
+       0x7010, 0x8000, 0x7012, 0x7018, 0xa06d, 0x711a, 0x0110, 0x6902,
+       0x0008, 0x711e, 0x0c10, 0xa18c, 0x00ff, 0xa186, 0x0017, 0x0130,
+       0xa186, 0x001e, 0x0118, 0xa18e, 0x001f, 0x1d28, 0x684c, 0xd0cc,
+       0x0d10, 0x6850, 0xa084, 0x00ff, 0xa086, 0x0001, 0x19e0, 0x2009,
+       0x8021, 0x0804, 0x5143, 0x7084, 0x8008, 0xa092, 0x001e, 0x1a98,
+       0x7186, 0xae90, 0x0003, 0xa210, 0x683c, 0x2012, 0x0078, 0x7084,
+       0x8008, 0xa092, 0x000f, 0x1a38, 0x7186, 0xae90, 0x0003, 0x8003,
+       0xa210, 0x683c, 0x2012, 0x8210, 0x6840, 0x2012, 0x7088, 0xa10a,
+       0x0a04, 0x515c, 0x718c, 0x7084, 0xa10a, 0x0a04, 0x515c, 0x2071,
+       0x0000, 0x7018, 0xd084, 0x1904, 0x515c, 0x2071, 0xaf34, 0x7000,
+       0xa086, 0x0002, 0x1150, 0x080c, 0x5426, 0x2071, 0x0000, 0x701b,
+       0x0001, 0x2091, 0x4080, 0x0804, 0x515c, 0x080c, 0x5450, 0x2071,
+       0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0804, 0x515c, 0x0006,
+       0x684c, 0x0006, 0x6837, 0x0103, 0x20a9, 0x001c, 0xad80, 0x0011,
+       0x20a0, 0x2001, 0x0000, 0x40a4, 0x000e, 0xa084, 0x00ff, 0x684e,
+       0x000e, 0x684a, 0x6952, 0x0005, 0x2071, 0xae13, 0x7004, 0x0002,
+       0x5202, 0x5213, 0x5411, 0x5412, 0x541f, 0x5425, 0x5203, 0x5402,
+       0x5398, 0x53ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x0e04, 0x5212,
+       0x2009, 0x000d, 0x7030, 0x200a, 0x2091, 0x4080, 0x7007, 0x0001,
+       0x700b, 0x0000, 0x012e, 0x2069, 0xafda, 0x683c, 0xa005, 0x03f8,
+       0x11f0, 0x0126, 0x2091, 0x8000, 0x2069, 0x0000, 0x6934, 0x2001,
+       0xae1f, 0x2004, 0xa10a, 0x0170, 0x0e04, 0x5236, 0x2069, 0x0000,
+       0x6818, 0xd084, 0x1158, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001,
+       0x2091, 0x4080, 0x2069, 0xafda, 0x683f, 0xffff, 0x012e, 0x2069,
+       0xad00, 0x6844, 0x6964, 0xa102, 0x2069, 0xaf34, 0x688a, 0x6984,
+       0x701c, 0xa06d, 0x0120, 0x81ff, 0x0904, 0x528c, 0x00a0, 0x81ff,
+       0x0904, 0x5352, 0x2071, 0xaf34, 0x7184, 0x7088, 0xa10a, 0x1258,
+       0x7190, 0x2071, 0xafda, 0x7038, 0xa005, 0x0128, 0x1b04, 0x5352,
+       0x713a, 0x0804, 0x5352, 0x2071, 0xaf34, 0x718c, 0x0126, 0x2091,
+       0x8000, 0x7084, 0xa10a, 0x0a04, 0x536d, 0x0e04, 0x530e, 0x2071,
+       0x0000, 0x7018, 0xd084, 0x1904, 0x530e, 0x2001, 0xffff, 0x2071,
+       0xafda, 0x703a, 0x2071, 0xaf34, 0x7000, 0xa086, 0x0002, 0x1150,
+       0x080c, 0x5426, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080,
+       0x0804, 0x530e, 0x080c, 0x5450, 0x2071, 0x0000, 0x701b, 0x0001,
+       0x2091, 0x4080, 0x0804, 0x530e, 0x2071, 0xaf34, 0x7000, 0xa005,
+       0x0904, 0x5334, 0x6934, 0xa186, 0x0103, 0x1904, 0x5311, 0x684c,
+       0xd0bc, 0x1904, 0x5334, 0x6948, 0x6844, 0xa105, 0x1904, 0x5329,
+       0x2009, 0x8020, 0x2071, 0xaf34, 0x7000, 0x0002, 0x5334, 0x52f4,
+       0x52cc, 0x52de, 0x52ab, 0x0136, 0x0146, 0x0156, 0x2099, 0xad75,
+       0x20a1, 0xaf85, 0x20a9, 0x0004, 0x53a3, 0x015e, 0x014e, 0x013e,
+       0x2071, 0xaf7c, 0xad80, 0x000f, 0x700e, 0x7013, 0x0002, 0x7007,
+       0x0002, 0x700b, 0x0000, 0x2e10, 0x080c, 0x1624, 0x2071, 0xae13,
+       0x7007, 0x0009, 0x0804, 0x5352, 0x7084, 0x8008, 0xa092, 0x001e,
+       0x1a04, 0x5352, 0xae90, 0x0003, 0xa210, 0x683c, 0x2012, 0x7186,
+       0x2071, 0xae13, 0x080c, 0x54a7, 0x0804, 0x5352, 0x7084, 0x8008,
+       0xa092, 0x000f, 0x1a04, 0x5352, 0xae90, 0x0003, 0x8003, 0xa210,
+       0x683c, 0x2012, 0x8210, 0x6840, 0x2012, 0x7186, 0x2071, 0xae13,
+       0x080c, 0x54a7, 0x0804, 0x5352, 0x0126, 0x2091, 0x8000, 0x0e04,
+       0x530e, 0x2071, 0x0000, 0x7018, 0xd084, 0x1180, 0x7122, 0x683c,
+       0x7026, 0x6840, 0x702a, 0x701b, 0x0001, 0x2091, 0x4080, 0x012e,
+       0x2071, 0xae13, 0x080c, 0x54a7, 0x0804, 0x5352, 0x012e, 0x0804,
+       0x5352, 0xa18c, 0x00ff, 0xa186, 0x0017, 0x0130, 0xa186, 0x001e,
+       0x0118, 0xa18e, 0x001f, 0x11c0, 0x684c, 0xd0cc, 0x01a8, 0x6850,
+       0xa084, 0x00ff, 0xa086, 0x0001, 0x1178, 0x2009, 0x8021, 0x0804,
+       0x52a2, 0x6844, 0xa086, 0x0100, 0x1138, 0x6868, 0xa005, 0x1120,
+       0x2009, 0x8020, 0x0804, 0x52a2, 0x2071, 0xae13, 0x080c, 0x54b9,
+       0x01c8, 0x2071, 0xae13, 0x700f, 0x0001, 0x6934, 0xa184, 0x00ff,
+       0xa086, 0x0003, 0x1130, 0x810f, 0xa18c, 0x00ff, 0x8101, 0x0108,
+       0x710e, 0x7007, 0x0003, 0x080c, 0x54d2, 0x7050, 0xa086, 0x0100,
+       0x0904, 0x5412, 0x0126, 0x2091, 0x8000, 0x2071, 0xae13, 0x7008,
+       0xa086, 0x0001, 0x1180, 0x0e04, 0x536b, 0x2009, 0x000d, 0x7030,
+       0x200a, 0x2091, 0x4080, 0x700b, 0x0000, 0x7004, 0xa086, 0x0006,
+       0x1110, 0x7007, 0x0001, 0x012e, 0x0005, 0x2071, 0xae13, 0x080c,
+       0x54b9, 0x0518, 0x2071, 0xaf34, 0x7084, 0x700a, 0x20a9, 0x0020,
+       0x2099, 0xaf35, 0x20a1, 0xaf5c, 0x53a3, 0x7087, 0x0000, 0x2071,
+       0xae13, 0x2069, 0xaf7c, 0x706c, 0x6826, 0x7070, 0x682a, 0x7074,
+       0x682e, 0x7078, 0x6832, 0x2d10, 0x080c, 0x1624, 0x7007, 0x0008,
+       0x2001, 0xffff, 0x2071, 0xafda, 0x703a, 0x012e, 0x0804, 0x5352,
+       0x2069, 0xaf7c, 0x6808, 0xa08e, 0x0000, 0x0904, 0x53ed, 0xa08e,
+       0x0200, 0x0904, 0x53eb, 0xa08e, 0x0100, 0x1904, 0x53ed, 0x0126,
+       0x2091, 0x8000, 0x0e04, 0x53e9, 0x2069, 0x0000, 0x6818, 0xd084,
+       0x15c0, 0x702c, 0x7130, 0x8108, 0xa102, 0x0230, 0xa00e, 0x7034,
+       0x706e, 0x7038, 0x7072, 0x0048, 0x706c, 0xa080, 0x0040, 0x706e,
+       0x1220, 0x7070, 0xa081, 0x0000, 0x7072, 0x7132, 0x6936, 0x700b,
+       0x0000, 0x2001, 0xaf59, 0x2004, 0xa005, 0x1190, 0x6934, 0x2069,
+       0xaf34, 0x689c, 0x699e, 0x2069, 0xafda, 0xa102, 0x1118, 0x683c,
+       0xa005, 0x1368, 0x2001, 0xaf5a, 0x200c, 0x810d, 0x693e, 0x0038,
+       0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091, 0x4080, 0x7007,
+       0x0001, 0x012e, 0x0010, 0x7007, 0x0005, 0x0005, 0x2001, 0xaf7e,
+       0x2004, 0xa08e, 0x0100, 0x1128, 0x7007, 0x0001, 0x080c, 0x54a7,
+       0x0005, 0xa08e, 0x0000, 0x0de0, 0xa08e, 0x0200, 0x1dc8, 0x7007,
+       0x0005, 0x0005, 0x701c, 0xa06d, 0x0158, 0x080c, 0x54b9, 0x0140,
+       0x7007, 0x0003, 0x080c, 0x54d2, 0x7050, 0xa086, 0x0100, 0x0110,
+       0x0005, 0x0005, 0x7050, 0xa09e, 0x0100, 0x1118, 0x7007, 0x0004,
+       0x0030, 0xa086, 0x0200, 0x1110, 0x7007, 0x0005, 0x0005, 0x080c,
+       0x5475, 0x7006, 0x080c, 0x54a7, 0x0005, 0x0005, 0x00e6, 0x0156,
+       0x2071, 0xaf34, 0x7184, 0x81ff, 0x0500, 0xa006, 0x7086, 0xae80,
+       0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, 0x7226, 0x8000, 0x0f04,
+       0x544a, 0x2014, 0x722a, 0x8000, 0x0f04, 0x544a, 0x2014, 0x722e,
+       0x8000, 0x0f04, 0x544a, 0x2014, 0x723a, 0x8000, 0x0f04, 0x544a,
+       0x2014, 0x723e, 0xa180, 0x8030, 0x7022, 0x015e, 0x00ee, 0x0005,
+       0x00e6, 0x0156, 0x2071, 0xaf34, 0x7184, 0x81ff, 0x01d8, 0xa006,
+       0x7086, 0xae80, 0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, 0x7226,
+       0x8000, 0x2014, 0x722a, 0x8000, 0x0f04, 0x546c, 0x2014, 0x723a,
+       0x8000, 0x2014, 0x723e, 0x0018, 0x2001, 0x8020, 0x0010, 0x2001,
+       0x8042, 0x7022, 0x015e, 0x00ee, 0x0005, 0x702c, 0x7130, 0x8108,
+       0xa102, 0x0230, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072, 0x0048,
+       0x706c, 0xa080, 0x0040, 0x706e, 0x1220, 0x7070, 0xa081, 0x0000,
+       0x7072, 0x7132, 0x700c, 0x8001, 0x700e, 0x1180, 0x0126, 0x2091,
+       0x8000, 0x0e04, 0x54a1, 0x2001, 0x000d, 0x2102, 0x2091, 0x4080,
+       0x2001, 0x0001, 0x700b, 0x0000, 0x012e, 0x0005, 0x2001, 0x0007,
+       0x0005, 0x2001, 0x0006, 0x700b, 0x0001, 0x012e, 0x0005, 0x701c,
+       0xa06d, 0x0170, 0x0126, 0x2091, 0x8000, 0x7010, 0x8001, 0x7012,
+       0x2d04, 0x701e, 0xa005, 0x1108, 0x701a, 0x012e, 0x080c, 0x15f0,
+       0x0005, 0x2019, 0x000d, 0x2304, 0x230c, 0xa10e, 0x0130, 0x2304,
+       0x230c, 0xa10e, 0x0110, 0xa006, 0x0060, 0x732c, 0x8319, 0x7130,
+       0xa102, 0x1118, 0x2300, 0xa005, 0x0020, 0x0210, 0xa302, 0x0008,
+       0x8002, 0x0005, 0x2d00, 0x7026, 0xa080, 0x000d, 0x7056, 0x7053,
+       0x0000, 0x0126, 0x2091, 0x8000, 0x2009, 0xafec, 0x2104, 0xc08d,
+       0x200a, 0x012e, 0x080c, 0x163c, 0x0005, 0x7088, 0xa08a, 0x0029,
+       0x1220, 0xa082, 0x001d, 0x0033, 0x0010, 0x080c, 0x14f6, 0x6027,
+       0x1e00, 0x0005, 0x55c1, 0x555b, 0x5571, 0x5595, 0x55b4, 0x55e6,
+       0x55f8, 0x5571, 0x55d2, 0x54ff, 0x552d, 0x54fe, 0x0005, 0x00d6,
+       0x2069, 0x0200, 0x6804, 0xa005, 0x1180, 0x6808, 0xa005, 0x1518,
+       0x708b, 0x0028, 0x2069, 0xafac, 0x2d04, 0x7002, 0x080c, 0x584d,
+       0x6028, 0xa085, 0x0600, 0x602a, 0x00b0, 0x708b, 0x0028, 0x2069,
+       0xafac, 0x2d04, 0x7002, 0x6028, 0xa085, 0x0600, 0x602a, 0x00e6,
+       0x0036, 0x0046, 0x0056, 0x2071, 0xaffd, 0x080c, 0x1d22, 0x005e,
+       0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, 0x00d6, 0x2069, 0x0200,
+       0x6804, 0xa005, 0x1180, 0x6808, 0xa005, 0x1518, 0x708b, 0x0028,
+       0x2069, 0xafac, 0x2d04, 0x7002, 0x080c, 0x58da, 0x6028, 0xa085,
+       0x0600, 0x602a, 0x00b0, 0x708b, 0x0028, 0x2069, 0xafac, 0x2d04,
+       0x7002, 0x6028, 0xa085, 0x0600, 0x602a, 0x00e6, 0x0036, 0x0046,
+       0x0056, 0x2071, 0xaffd, 0x080c, 0x1d22, 0x005e, 0x004e, 0x003e,
+       0x00ee, 0x00de, 0x0005, 0x6803, 0x0090, 0x6124, 0xd1e4, 0x1180,
+       0x080c, 0x5663, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1cc, 0x0140,
+       0x708b, 0x0020, 0x0028, 0x708b, 0x001d, 0x0010, 0x708b, 0x001f,
+       0x0005, 0x6803, 0x0088, 0x6124, 0xd1cc, 0x11c8, 0xd1dc, 0x11a0,
+       0xd1e4, 0x1178, 0xa184, 0x1e00, 0x11b8, 0x60e3, 0x0001, 0x600c,
+       0xc0b4, 0x600e, 0x080c, 0x577f, 0x6803, 0x0080, 0x708b, 0x0028,
+       0x0058, 0x708b, 0x001e, 0x0040, 0x708b, 0x001d, 0x0028, 0x708b,
+       0x0020, 0x0010, 0x708b, 0x001f, 0x0005, 0x60e3, 0x0001, 0x600c,
+       0xc0b4, 0x600e, 0x080c, 0x577f, 0x6803, 0x0080, 0x6124, 0xd1d4,
+       0x1180, 0xd1dc, 0x1158, 0xd1e4, 0x1130, 0xa184, 0x1e00, 0x1158,
+       0x708b, 0x0028, 0x0040, 0x708b, 0x001e, 0x0028, 0x708b, 0x001d,
+       0x0010, 0x708b, 0x001f, 0x0005, 0x6803, 0x00a0, 0x6124, 0xd1dc,
+       0x1128, 0xd1e4, 0x0128, 0x708b, 0x001e, 0x0010, 0x708b, 0x001d,
+       0x0005, 0x080c, 0x568d, 0x6124, 0xd1dc, 0x1158, 0x080c, 0x5663,
+       0xd1d4, 0x1128, 0xd1e4, 0x0128, 0x708b, 0x001e, 0x0010, 0x708b,
+       0x001f, 0x0005, 0x6803, 0x00a0, 0x6124, 0xd1d4, 0x1160, 0xd1cc,
+       0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x708b, 0x001e, 0x0028,
+       0x708b, 0x001d, 0x0010, 0x708b, 0x0021, 0x0005, 0x080c, 0x568d,
+       0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x708b,
+       0x001e, 0x0028, 0x708b, 0x001d, 0x0010, 0x708b, 0x001f, 0x0005,
+       0x6803, 0x0090, 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc,
+       0x1128, 0xd1e4, 0x0158, 0x708b, 0x001e, 0x0040, 0x708b, 0x001d,
+       0x0028, 0x708b, 0x0020, 0x0010, 0x708b, 0x001f, 0x0005, 0x0016,
+       0x00c6, 0x00d6, 0x00e6, 0x0126, 0x2061, 0x0100, 0x2069, 0x0140,
+       0x2071, 0xad00, 0x2091, 0x8000, 0x080c, 0x574f, 0x11e8, 0x2001,
+       0xad0c, 0x200c, 0xd1b4, 0x01c0, 0xc1b4, 0x2102, 0x6027, 0x0200,
+       0xe000, 0xe000, 0x6024, 0xd0cc, 0x0158, 0x6803, 0x00a0, 0x2001,
+       0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0x0428,
+       0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, 0x576b, 0x0150, 0x080c,
+       0x5761, 0x1138, 0x2001, 0x0001, 0x080c, 0x261e, 0x080c, 0x5726,
+       0x00a0, 0x080c, 0x568a, 0x0178, 0x2001, 0x0001, 0x080c, 0x261e,
+       0x7088, 0xa086, 0x001e, 0x0120, 0x7088, 0xa086, 0x0022, 0x1118,
+       0x708b, 0x0025, 0x0010, 0x708b, 0x0021, 0x012e, 0x00ee, 0x00de,
+       0x00ce, 0x001e, 0x0005, 0x0016, 0x0026, 0x2009, 0x0064, 0x2011,
+       0x566e, 0x080c, 0x6501, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6,
+       0x0016, 0x080c, 0x7834, 0x2071, 0xad00, 0x080c, 0x560f, 0x001e,
+       0x00fe, 0x00ee, 0x0005, 0x2001, 0xad00, 0x2004, 0xa086, 0x0004,
+       0x0140, 0x2001, 0xaf9d, 0x2003, 0xaaaa, 0x2001, 0xaf9e, 0x2003,
+       0x0000, 0x0005, 0x6020, 0xd09c, 0x0005, 0x6803, 0x00c0, 0x0156,
+       0x20a9, 0x002d, 0x1d04, 0x5692, 0x2091, 0x6000, 0x1f04, 0x5692,
+       0x015e, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069,
+       0x0140, 0x2071, 0xad00, 0x2001, 0xaf9e, 0x200c, 0xa186, 0x0000,
+       0x0158, 0xa186, 0x0001, 0x0158, 0xa186, 0x0002, 0x0158, 0xa186,
+       0x0003, 0x0158, 0x0804, 0x5714, 0x708b, 0x0022, 0x0040, 0x708b,
+       0x0021, 0x0028, 0x708b, 0x0023, 0x0020, 0x708b, 0x0024, 0x6043,
+       0x0000, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c,
+       0x26cb, 0x0026, 0x2011, 0x0003, 0x080c, 0x7adf, 0x2011, 0x0002,
+       0x080c, 0x7ae9, 0x002e, 0x7000, 0xa08e, 0x0004, 0x0118, 0x602b,
+       0x0028, 0x0010, 0x602b, 0x0020, 0x0156, 0x0126, 0x2091, 0x8000,
+       0x20a9, 0x0005, 0x6024, 0xd0ac, 0x0118, 0x012e, 0x015e, 0x04d0,
+       0x6800, 0xa084, 0x00a0, 0xc0bd, 0x6802, 0x6904, 0xd1d4, 0x1130,
+       0x6803, 0x0100, 0x1f04, 0x56e2, 0x080c, 0x57a0, 0x012e, 0x015e,
+       0x080c, 0x5761, 0x01a8, 0x6044, 0xa005, 0x0168, 0x6050, 0x0006,
+       0xa085, 0x0020, 0x6052, 0x080c, 0x57a0, 0xa006, 0x8001, 0x1df0,
+       0x000e, 0x6052, 0x0028, 0x6804, 0xd0d4, 0x1110, 0x080c, 0x57a0,
+       0x2001, 0xaf9e, 0x2003, 0x0004, 0x080c, 0x54e5, 0x080c, 0x5761,
+       0x0148, 0x6804, 0xd0d4, 0x1130, 0xd0dc, 0x1100, 0x2001, 0xaf9e,
+       0x2003, 0x0000, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6,
+       0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0xad00, 0x2001,
+       0xaf9d, 0x2003, 0x0000, 0x2001, 0xaf8e, 0x2003, 0x0000, 0x708b,
+       0x0000, 0x60e3, 0x0000, 0x6887, 0x0000, 0x2001, 0x0000, 0x080c,
+       0x26cb, 0x6803, 0x0000, 0x6043, 0x0090, 0x6043, 0x0010, 0x6027,
+       0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006,
+       0x2001, 0xaf9d, 0x2004, 0xa086, 0xaaaa, 0x000e, 0x0005, 0x0006,
+       0x2001, 0xad71, 0x2004, 0xa084, 0x0030, 0xa086, 0x0000, 0x000e,
+       0x0005, 0x0006, 0x2001, 0xad71, 0x2004, 0xa084, 0x0030, 0xa086,
+       0x0030, 0x000e, 0x0005, 0x0006, 0x2001, 0xad71, 0x2004, 0xa084,
+       0x0030, 0xa086, 0x0010, 0x000e, 0x0005, 0x0006, 0x2001, 0xad71,
+       0x2004, 0xa084, 0x0030, 0xa086, 0x0020, 0x000e, 0x0005, 0x2001,
+       0xad0c, 0x2004, 0xd0a4, 0x0170, 0x080c, 0x26eb, 0x0036, 0x0016,
+       0x2009, 0x0000, 0x2019, 0x0028, 0x080c, 0x2aac, 0x001e, 0x003e,
+       0xa006, 0x0009, 0x0005, 0x00e6, 0x2071, 0xad0c, 0x2e04, 0x0118,
+       0xa085, 0x0010, 0x0010, 0xa084, 0xffef, 0x2072, 0x00ee, 0x0005,
+       0x6050, 0x0006, 0x60f0, 0x0006, 0x60ec, 0x0006, 0x600c, 0x0006,
+       0x6004, 0x0006, 0x6028, 0x0006, 0x602f, 0x0100, 0x602f, 0x0000,
+       0x602f, 0x0040, 0x602f, 0x0000, 0x000e, 0x602a, 0x000e, 0x6006,
+       0x000e, 0x600e, 0x000e, 0x60ee, 0x000e, 0x60f2, 0x60e3, 0x0000,
+       0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x26cb, 0x6800, 0xa084,
+       0x00a0, 0xc0bd, 0x6802, 0x6803, 0x00a0, 0x000e, 0x6052, 0x6050,
+       0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6,
+       0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0xad00, 0x6020, 0xa084,
+       0x0080, 0x0138, 0x2001, 0xad0c, 0x200c, 0xc1bd, 0x2102, 0x0804,
+       0x5845, 0x2001, 0xad0c, 0x200c, 0xc1bc, 0x2102, 0x6028, 0xa084,
+       0xe1ff, 0x602a, 0x6027, 0x0200, 0x6803, 0x0090, 0x20a9, 0x0384,
+       0x6024, 0xd0cc, 0x1518, 0x1d04, 0x57f8, 0x2091, 0x6000, 0x1f04,
+       0x57f8, 0x2011, 0x0003, 0x080c, 0x7adf, 0x2011, 0x0002, 0x080c,
+       0x7ae9, 0x080c, 0x79e1, 0x080c, 0x6581, 0x2019, 0x0000, 0x080c,
+       0x7a64, 0x6803, 0x00a0, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001,
+       0xad00, 0x2003, 0x0001, 0xa085, 0x0001, 0x0438, 0x60e3, 0x0000,
+       0x2001, 0xaf8e, 0x2004, 0x080c, 0x26cb, 0x60e2, 0x6803, 0x0080,
+       0x20a9, 0x0384, 0x6027, 0x1e00, 0x2009, 0x1e00, 0xe000, 0x6024,
+       0xa10c, 0x0138, 0x1d04, 0x582a, 0x2091, 0x6000, 0x1f04, 0x582a,
+       0x0840, 0x6028, 0xa085, 0x1e00, 0x602a, 0x70a0, 0xa005, 0x1118,
+       0x6887, 0x0001, 0x0008, 0x6886, 0xa006, 0x00ee, 0x00de, 0x00ce,
+       0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026,
+       0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0xad00,
+       0x2069, 0x0140, 0x6020, 0xa084, 0x00c0, 0x0120, 0x6884, 0xa005,
+       0x1904, 0x58a1, 0x6803, 0x0088, 0x60e3, 0x0000, 0x6887, 0x0000,
+       0x2001, 0x0000, 0x080c, 0x26cb, 0x2069, 0x0200, 0x6804, 0xa005,
+       0x1118, 0x6808, 0xa005, 0x01c0, 0x6028, 0xa084, 0xfbff, 0x602a,
+       0x6027, 0x0400, 0x2069, 0xafac, 0x7000, 0x206a, 0x708b, 0x0026,
+       0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x5884, 0x2091, 0x6000,
+       0x1f04, 0x5884, 0x0804, 0x58d2, 0x2069, 0x0140, 0x20a9, 0x0384,
+       0x6027, 0x1e00, 0x2009, 0x1e00, 0xe000, 0x6024, 0xa10c, 0x0530,
+       0xa084, 0x1a00, 0x1518, 0x1d04, 0x5890, 0x2091, 0x6000, 0x1f04,
+       0x5890, 0x2011, 0x0003, 0x080c, 0x7adf, 0x2011, 0x0002, 0x080c,
+       0x7ae9, 0x080c, 0x79e1, 0x080c, 0x6581, 0x2019, 0x0000, 0x080c,
+       0x7a64, 0x6803, 0x00a0, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001,
+       0xad00, 0x2003, 0x0001, 0xa085, 0x0001, 0x00a0, 0x6803, 0x0080,
+       0x2069, 0x0140, 0x60e3, 0x0000, 0x70a0, 0xa005, 0x1118, 0x6887,
+       0x0001, 0x0008, 0x6886, 0x2001, 0xaf8e, 0x2004, 0x080c, 0x26cb,
+       0x60e2, 0xa006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e,
+       0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6,
+       0x00e6, 0x2061, 0x0100, 0x2071, 0xad00, 0x6020, 0xa084, 0x00c0,
+       0x01f0, 0x2011, 0x0003, 0x080c, 0x7adf, 0x2011, 0x0002, 0x080c,
+       0x7ae9, 0x080c, 0x79e1, 0x080c, 0x6581, 0x2019, 0x0000, 0x080c,
+       0x7a64, 0x2069, 0x0140, 0x6803, 0x00a0, 0x2001, 0xaf9e, 0x2003,
+       0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0x0804, 0x5972, 0x2001,
+       0xad0c, 0x200c, 0xd1b4, 0x1150, 0xc1b5, 0x2102, 0x080c, 0x5663,
+       0x2069, 0x0140, 0x6803, 0x0080, 0x60e3, 0x0000, 0x2069, 0x0200,
+       0x6804, 0xa005, 0x1118, 0x6808, 0xa005, 0x01b8, 0x6028, 0xa084,
+       0xfdff, 0x602a, 0x6027, 0x0200, 0x2069, 0xafac, 0x7000, 0x206a,
+       0x708b, 0x0027, 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x592e,
+       0x2091, 0x6000, 0x1f04, 0x592e, 0x04e8, 0x6027, 0x1e00, 0x2009,
+       0x1e00, 0xe000, 0x6024, 0xa10c, 0x01c8, 0xa084, 0x1c00, 0x11b0,
+       0x1d04, 0x5935, 0x0006, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c,
+       0x64a2, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071,
+       0xafda, 0x7018, 0x00ee, 0xa005, 0x1d00, 0x01e0, 0x0026, 0x2011,
+       0x566e, 0x080c, 0x650d, 0x002e, 0x2069, 0x0140, 0x60e3, 0x0000,
+       0x70a0, 0xa005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x2001,
+       0xaf8e, 0x2004, 0x080c, 0x26cb, 0x60e2, 0x2001, 0xad0c, 0x200c,
+       0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e,
+       0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x0046, 0x00c6,
+       0x00e6, 0x2061, 0x0100, 0x2071, 0xad00, 0x7130, 0xd184, 0x1180,
+       0x2011, 0xad52, 0x2214, 0xd2ec, 0x0138, 0xc18d, 0x7132, 0x2011,
+       0xad52, 0x2214, 0xd2ac, 0x1120, 0x7030, 0xd08c, 0x0904, 0x59df,
+       0x7130, 0xc185, 0x7132, 0x2011, 0xad52, 0x220c, 0xd1a4, 0x0530,
+       0x0016, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x663f, 0x2019,
+       0x000e, 0x080c, 0xa8eb, 0x0156, 0x20a9, 0x007f, 0x2009, 0x0000,
+       0xa186, 0x007e, 0x0170, 0xa186, 0x0080, 0x0158, 0x080c, 0x4cdc,
+       0x1140, 0x8127, 0xa006, 0x0016, 0x2009, 0x000e, 0x080c, 0xa96c,
+       0x001e, 0x8108, 0x1f04, 0x59b0, 0x015e, 0x001e, 0xd1ac, 0x1148,
+       0x0016, 0x2009, 0x0000, 0x2019, 0x0004, 0x080c, 0x2aac, 0x001e,
+       0x0070, 0x0156, 0x20a9, 0x007f, 0x2009, 0x0000, 0x080c, 0x4cdc,
+       0x1110, 0x080c, 0x493a, 0x8108, 0x1f04, 0x59d6, 0x015e, 0x2011,
+       0x0003, 0x080c, 0x7adf, 0x2011, 0x0002, 0x080c, 0x7ae9, 0x080c,
+       0x79e1, 0x080c, 0x6581, 0x0036, 0x2019, 0x0000, 0x080c, 0x7a64,
+       0x003e, 0x60e3, 0x0000, 0x2001, 0xad00, 0x2003, 0x0001, 0x080c,
+       0x569a, 0x00ee, 0x00ce, 0x004e, 0x003e, 0x002e, 0x001e, 0x015e,
+       0x0005, 0x2071, 0xade1, 0x7003, 0x0000, 0x7007, 0x0000, 0x700f,
+       0x0000, 0x702b, 0x0001, 0x704f, 0x0000, 0x7053, 0x0001, 0x705f,
+       0x0020, 0x7063, 0x0040, 0x7083, 0x0000, 0x708b, 0x0000, 0x708f,
+       0x0001, 0x70bf, 0x0000, 0x0005, 0x00e6, 0x2071, 0xade1, 0x6848,
+       0xa005, 0x1130, 0x7028, 0xc085, 0x702a, 0xa085, 0x0001, 0x0428,
+       0x6a50, 0x7236, 0x6b54, 0x733a, 0x6858, 0x703e, 0x707a, 0x685c,
+       0x7042, 0x707e, 0x6848, 0x702e, 0x6840, 0x7032, 0x2009, 0x000c,
+       0x200a, 0x8007, 0x8006, 0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0,
+       0xa210, 0x2100, 0xa319, 0x7272, 0x7376, 0x7028, 0xc084, 0x702a,
+       0x7007, 0x0001, 0x700f, 0x0000, 0xa006, 0x00ee, 0x0005, 0x2b78,
+       0x2071, 0xade1, 0x7004, 0x0043, 0x700c, 0x0002, 0x5a5b, 0x5a52,
+       0x5a52, 0x5a52, 0x5a52, 0x0005, 0x5ab1, 0x5ab2, 0x5ae4, 0x5ae5,
+       0x5aaf, 0x5b33, 0x5b38, 0x5b69, 0x5b6a, 0x5b85, 0x5b86, 0x5b87,
+       0x5b88, 0x5b89, 0x5b8a, 0x5c40, 0x5c67, 0x700c, 0x0002, 0x5a74,
+       0x5aaf, 0x5aaf, 0x5ab0, 0x5ab0, 0x7830, 0x7930, 0xa106, 0x0120,
+       0x7830, 0x7930, 0xa106, 0x1510, 0x7030, 0xa10a, 0x01f8, 0x1210,
+       0x712c, 0xa10a, 0xa18a, 0x0002, 0x12d0, 0x080c, 0x15c0, 0x01b0,
+       0x2d00, 0x705a, 0x7063, 0x0040, 0x2001, 0x0003, 0x7057, 0x0000,
+       0x0126, 0x0006, 0x2091, 0x8000, 0x2009, 0xafec, 0x2104, 0xc085,
+       0x200a, 0x000e, 0x700e, 0x012e, 0x080c, 0x163c, 0x0005, 0x080c,
+       0x15c0, 0x0de0, 0x2d00, 0x705a, 0x080c, 0x15c0, 0x1108, 0x0c10,
+       0x2d00, 0x7086, 0x7063, 0x0080, 0x2001, 0x0004, 0x08f8, 0x0005,
+       0x0005, 0x0005, 0x700c, 0x0002, 0x5ab9, 0x5abc, 0x5aca, 0x5ae3,
+       0x5ae3, 0x080c, 0x5a6d, 0x0005, 0x0126, 0x8001, 0x700e, 0x7058,
+       0x0006, 0x080c, 0x5f90, 0x0120, 0x2091, 0x8000, 0x080c, 0x5a6d,
+       0x00de, 0x0048, 0x0126, 0x8001, 0x700e, 0x080c, 0x5f90, 0x7058,
+       0x2068, 0x7084, 0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834,
+       0xa084, 0x00ff, 0xa08a, 0x003a, 0x1218, 0x00db, 0x012e, 0x0005,
+       0x012e, 0x080c, 0x5b8b, 0x0005, 0x0005, 0x0005, 0x00e6, 0x2071,
+       0xade1, 0x700c, 0x0002, 0x5af0, 0x5af0, 0x5af0, 0x5af2, 0x5af5,
+       0x00ee, 0x0005, 0x700f, 0x0001, 0x0010, 0x700f, 0x0002, 0x00ee,
+       0x0005, 0x5b8b, 0x5b8b, 0x5ba7, 0x5b8b, 0x5d22, 0x5b8b, 0x5b8b,
+       0x5b8b, 0x5b8b, 0x5b8b, 0x5ba7, 0x5d64, 0x5da7, 0x5df0, 0x5e04,
+       0x5b8b, 0x5b8b, 0x5bc3, 0x5ba7, 0x5b8b, 0x5b8b, 0x5c1d, 0x5ead,
+       0x5ec8, 0x5b8b, 0x5bc3, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5c13,
+       0x5ec8, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b,
+       0x5b8b, 0x5b8b, 0x5bd7, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b,
+       0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b,
+       0x5b8b, 0x5b8b, 0x5bec, 0x7020, 0x2068, 0x080c, 0x15f0, 0x0005,
+       0x700c, 0x0002, 0x5b3f, 0x5b42, 0x5b50, 0x5b68, 0x5b68, 0x080c,
+       0x5a6d, 0x0005, 0x0126, 0x8001, 0x700e, 0x7058, 0x0006, 0x080c,
+       0x5f90, 0x0120, 0x2091, 0x8000, 0x080c, 0x5a6d, 0x00de, 0x0048,
+       0x0126, 0x8001, 0x700e, 0x080c, 0x5f90, 0x7058, 0x2068, 0x7084,
+       0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834, 0xa084, 0x00ff,
+       0xa08a, 0x001a, 0x1218, 0x003b, 0x012e, 0x0005, 0x012e, 0x0419,
+       0x0005, 0x0005, 0x0005, 0x5b8b, 0x5ba7, 0x5d0e, 0x5b8b, 0x5ba7,
+       0x5b8b, 0x5ba7, 0x5ba7, 0x5b8b, 0x5ba7, 0x5d0e, 0x5ba7, 0x5ba7,
+       0x5ba7, 0x5ba7, 0x5ba7, 0x5b8b, 0x5ba7, 0x5d0e, 0x5b8b, 0x5b8b,
+       0x5ba7, 0x5b8b, 0x5b8b, 0x5b8b, 0x5ba7, 0x0005, 0x0005, 0x0005,
+       0x0005, 0x0005, 0x0005, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff,
+       0xc0d5, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x510c, 0x012e,
+       0x0005, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0e5, 0x683a,
+       0x0126, 0x2091, 0x8000, 0x080c, 0x510c, 0x012e, 0x0005, 0x7007,
+       0x0001, 0x6838, 0xa084, 0x00ff, 0xc0ed, 0x683a, 0x0126, 0x2091,
+       0x8000, 0x080c, 0x510c, 0x012e, 0x0005, 0x7007, 0x0001, 0x6838,
+       0xa084, 0x00ff, 0xc0dd, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c,
+       0x510c, 0x012e, 0x0005, 0x6834, 0x8007, 0xa084, 0x00ff, 0x0988,
+       0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x5cd0, 0x7007, 0x0006,
+       0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x5cd0, 0x0005, 0x6834,
+       0x8007, 0xa084, 0x00ff, 0x0904, 0x5b99, 0x8001, 0x1120, 0x7007,
+       0x0001, 0x0804, 0x5ced, 0x7007, 0x0006, 0x7012, 0x2d00, 0x7016,
+       0x701a, 0x704b, 0x5ced, 0x0005, 0x6834, 0x8007, 0xa084, 0x00ff,
+       0xa086, 0x0001, 0x1904, 0x5b99, 0x7007, 0x0001, 0x2009, 0xad30,
+       0x210c, 0x81ff, 0x11a8, 0x6838, 0xa084, 0x00ff, 0x683a, 0x6853,
+       0x0000, 0x080c, 0x4ab1, 0x1108, 0x0005, 0x0126, 0x2091, 0x8000,
+       0x6837, 0x0139, 0x684a, 0x6952, 0x080c, 0x510c, 0x012e, 0x0ca0,
+       0x2001, 0x0028, 0x0c90, 0x684c, 0xa084, 0x00c0, 0xa086, 0x00c0,
+       0x1120, 0x7007, 0x0001, 0x0804, 0x5ee0, 0x2d00, 0x7016, 0x701a,
+       0x20a9, 0x0004, 0xa080, 0x0024, 0x2098, 0x20a1, 0xae0c, 0x53a3,
+       0x6858, 0x7012, 0xa082, 0x0401, 0x1a04, 0x5bb5, 0x6a84, 0xa28a,
+       0x0002, 0x1a04, 0x5bb5, 0x82ff, 0x1138, 0x6888, 0x698c, 0xa105,
+       0x0118, 0x2001, 0x5ca3, 0x0018, 0xa280, 0x5c99, 0x2005, 0x70c6,
+       0x7010, 0xa015, 0x0904, 0x5c85, 0x080c, 0x15c0, 0x1118, 0x7007,
+       0x000f, 0x0005, 0x2d00, 0x7022, 0x70c4, 0x2060, 0x2c05, 0x6836,
+       0xe004, 0xad00, 0x7096, 0xe008, 0xa20a, 0x1210, 0xa00e, 0x2200,
+       0x7112, 0xe20c, 0x8003, 0x800b, 0xa296, 0x0004, 0x0108, 0xa108,
+       0x719a, 0x810b, 0x719e, 0xae90, 0x0022, 0x080c, 0x1624, 0x7090,
+       0xa08e, 0x0100, 0x0170, 0xa086, 0x0200, 0x0118, 0x7007, 0x0010,
+       0x0005, 0x7020, 0x2068, 0x080c, 0x15f0, 0x7014, 0x2068, 0x0804,
+       0x5bb5, 0x7020, 0x2068, 0x7018, 0x6802, 0x6807, 0x0000, 0x2d08,
+       0x2068, 0x6906, 0x711a, 0x0804, 0x5c40, 0x7014, 0x2068, 0x7007,
+       0x0001, 0x6884, 0xa005, 0x1128, 0x6888, 0x698c, 0xa105, 0x0108,
+       0x00b1, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x0904, 0x5ee0,
+       0x04b8, 0x5c9b, 0x5c9f, 0x0002, 0x0011, 0x0007, 0x0004, 0x000a,
+       0x000f, 0x0005, 0x0006, 0x000a, 0x0011, 0x0005, 0x0004, 0x00f6,
+       0x00e6, 0x00c6, 0x0076, 0x0066, 0x6f88, 0x6e8c, 0x6804, 0x2060,
+       0xacf0, 0x0021, 0xacf8, 0x0027, 0x2009, 0x0005, 0x700c, 0x7816,
+       0x7008, 0x7812, 0x7004, 0x7806, 0x7000, 0x7802, 0x7e0e, 0x7f0a,
+       0x8109, 0x0128, 0xaef2, 0x0004, 0xaffa, 0x0006, 0x0c78, 0x6004,
+       0xa065, 0x1d30, 0x006e, 0x007e, 0x00ce, 0x00ee, 0x00fe, 0x0005,
+       0x2009, 0xad30, 0x210c, 0x81ff, 0x1198, 0x6838, 0xa084, 0x00ff,
+       0x683a, 0x080c, 0x4993, 0x1108, 0x0005, 0x080c, 0x51df, 0x0126,
+       0x2091, 0x8000, 0x080c, 0x97fd, 0x080c, 0x510c, 0x012e, 0x0ca0,
+       0x2001, 0x0028, 0x2009, 0x0000, 0x0c80, 0x2009, 0xad30, 0x210c,
+       0x81ff, 0x11b0, 0x6858, 0xa005, 0x01b0, 0x6838, 0xa084, 0x00ff,
+       0x683a, 0x6853, 0x0000, 0x080c, 0x4a55, 0x1108, 0x0005, 0x0126,
+       0x2091, 0x8000, 0x080c, 0x51df, 0x080c, 0x510c, 0x012e, 0x0cb0,
+       0x2001, 0x0028, 0x0ca0, 0x2001, 0x0000, 0x0c88, 0x7018, 0x6802,
+       0x2d08, 0x2068, 0x6906, 0x711a, 0x7010, 0x8001, 0x7012, 0x0118,
+       0x7007, 0x0006, 0x0030, 0x7014, 0x2068, 0x7007, 0x0001, 0x7048,
+       0x080f, 0x0005, 0x7007, 0x0001, 0x6944, 0x810f, 0xa18c, 0x00ff,
+       0x6848, 0xa084, 0x00ff, 0x20a9, 0x0001, 0xa096, 0x0001, 0x01b0,
+       0x2009, 0x0000, 0x20a9, 0x00ff, 0xa096, 0x0002, 0x0178, 0xa005,
+       0x11f0, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x080c, 0x4cdc, 0x11b8,
+       0x0066, 0x6e50, 0x080c, 0x4dcf, 0x006e, 0x0088, 0x0046, 0x2011,
+       0xad0c, 0x2224, 0xc484, 0x2412, 0x004e, 0x00c6, 0x080c, 0x4cdc,
+       0x1110, 0x080c, 0x4f2d, 0x8108, 0x1f04, 0x5d4e, 0x00ce, 0x684c,
+       0xd084, 0x1118, 0x080c, 0x15f0, 0x0005, 0x0126, 0x2091, 0x8000,
+       0x080c, 0x510c, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x7007,
+       0x0001, 0x2001, 0xad52, 0x2004, 0xd0a4, 0x0580, 0x2061, 0xb048,
+       0x6100, 0xd184, 0x0178, 0x6858, 0xa084, 0x00ff, 0x1550, 0x6000,
+       0xd084, 0x0520, 0x6004, 0xa005, 0x1538, 0x6003, 0x0000, 0x600b,
+       0x0000, 0x00c8, 0x2011, 0x0001, 0x6860, 0xa005, 0x1110, 0x2001,
+       0x001e, 0x8000, 0x6016, 0x6858, 0xa084, 0x00ff, 0x0178, 0x6006,
+       0x6858, 0x8007, 0xa084, 0x00ff, 0x0148, 0x600a, 0x6858, 0x8000,
+       0x1108, 0xc28d, 0x6202, 0x012e, 0x0804, 0x5f7f, 0x012e, 0x0804,
+       0x5f79, 0x012e, 0x0804, 0x5f73, 0x012e, 0x0804, 0x5f76, 0x0126,
+       0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0xad52, 0x2004, 0xd0a4,
+       0x05e0, 0x2061, 0xb048, 0x6000, 0xd084, 0x05b8, 0x6204, 0x6308,
+       0xd08c, 0x1530, 0x6c48, 0xa484, 0x0003, 0x0170, 0x6958, 0xa18c,
+       0x00ff, 0x8001, 0x1120, 0x2100, 0xa210, 0x0620, 0x0028, 0x8001,
+       0x1508, 0x2100, 0xa212, 0x02f0, 0xa484, 0x000c, 0x0188, 0x6958,
+       0x810f, 0xa18c, 0x00ff, 0xa082, 0x0004, 0x1120, 0x2100, 0xa318,
+       0x0288, 0x0030, 0xa082, 0x0004, 0x1168, 0x2100, 0xa31a, 0x0250,
+       0x6860, 0xa005, 0x0110, 0x8000, 0x6016, 0x6206, 0x630a, 0x012e,
+       0x0804, 0x5f7f, 0x012e, 0x0804, 0x5f7c, 0x012e, 0x0804, 0x5f79,
+       0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061, 0xb048, 0x6300,
+       0xd38c, 0x1120, 0x6308, 0x8318, 0x0220, 0x630a, 0x012e, 0x0804,
+       0x5f8d, 0x012e, 0x0804, 0x5f7c, 0x0126, 0x00c6, 0x2091, 0x8000,
+       0x7007, 0x0001, 0x684c, 0xd0ac, 0x0148, 0x00c6, 0x2061, 0xb048,
+       0x6000, 0xa084, 0xfcff, 0x6002, 0x00ce, 0x0448, 0x6858, 0xa005,
+       0x05d0, 0x685c, 0xa065, 0x0598, 0x2001, 0xad30, 0x2004, 0xa005,
+       0x0118, 0x080c, 0x974e, 0x0068, 0x6013, 0x0400, 0x6057, 0x0000,
+       0x694c, 0xd1a4, 0x0110, 0x6950, 0x6156, 0x2009, 0x0041, 0x080c,
+       0x80a7, 0x6958, 0xa18c, 0xff00, 0xa186, 0x2000, 0x1140, 0x0026,
+       0x2009, 0x0000, 0x2011, 0xfdff, 0x080c, 0x663f, 0x002e, 0x684c,
+       0xd0c4, 0x0148, 0x2061, 0xb048, 0x6000, 0xd08c, 0x1120, 0x6008,
+       0x8000, 0x0208, 0x600a, 0x00ce, 0x012e, 0x0804, 0x5f7f, 0x00ce,
+       0x012e, 0x0804, 0x5f79, 0x6954, 0xa186, 0x002e, 0x0d40, 0xa186,
+       0x002d, 0x0d28, 0xa186, 0x0045, 0x0510, 0xa186, 0x002a, 0x1130,
+       0x2001, 0xad0c, 0x200c, 0xc194, 0x2102, 0x08c8, 0xa186, 0x0020,
+       0x0170, 0xa186, 0x0029, 0x1d18, 0x6944, 0xa18c, 0xff00, 0x810f,
+       0x080c, 0x4cdc, 0x1960, 0x6000, 0xc0e4, 0x6002, 0x0840, 0x685c,
+       0xa065, 0x09a8, 0x2001, 0xafa3, 0x2004, 0x6016, 0x0800, 0x685c,
+       0xa065, 0x0968, 0x00e6, 0x6860, 0xa075, 0x2001, 0xad30, 0x2004,
+       0xa005, 0x0150, 0x080c, 0x974e, 0x8eff, 0x0118, 0x2e60, 0x080c,
+       0x974e, 0x00ee, 0x0804, 0x5e3f, 0x6020, 0xc0dc, 0xc0d5, 0x6022,
+       0x2e60, 0x6007, 0x003a, 0x6870, 0xa005, 0x0130, 0x6007, 0x003b,
+       0x6874, 0x602a, 0x6878, 0x6012, 0x6003, 0x0001, 0x080c, 0x67a8,
+       0x080c, 0x6c50, 0x00ee, 0x0804, 0x5e3f, 0x2061, 0xb048, 0x6000,
+       0xd084, 0x0190, 0xd08c, 0x1904, 0x5f8d, 0x0126, 0x2091, 0x8000,
+       0x6204, 0x8210, 0x0220, 0x6206, 0x012e, 0x0804, 0x5f8d, 0x012e,
+       0x6853, 0x0016, 0x0804, 0x5f86, 0x6853, 0x0007, 0x0804, 0x5f86,
+       0x6834, 0x8007, 0xa084, 0x00ff, 0x1118, 0x080c, 0x5b99, 0x0078,
+       0x2030, 0x8001, 0x1120, 0x7007, 0x0001, 0x0051, 0x0040, 0x7007,
+       0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x5ee0, 0x0005,
+       0x00e6, 0x0126, 0x2091, 0x8000, 0x2009, 0xad30, 0x210c, 0x81ff,
+       0x1904, 0x5f5b, 0x2009, 0xad0c, 0x210c, 0xd194, 0x1904, 0x5f63,
+       0x6848, 0x2070, 0xae82, 0xb400, 0x0a04, 0x5f4f, 0x2001, 0xad16,
+       0x2004, 0xae02, 0x1a04, 0x5f4f, 0x2061, 0xb048, 0x6100, 0xa184,
+       0x0301, 0xa086, 0x0001, 0x15a8, 0x711c, 0xa186, 0x0006, 0x15b0,
+       0x7018, 0xa005, 0x0904, 0x5f5b, 0x2004, 0xd0e4, 0x1904, 0x5f5e,
+       0x7020, 0xd0dc, 0x1904, 0x5f66, 0x6853, 0x0000, 0x6803, 0x0000,
+       0x2d08, 0x7010, 0xa005, 0x1158, 0x7112, 0x684c, 0xd0f4, 0x1904,
+       0x5f69, 0x2e60, 0x080c, 0x65aa, 0x012e, 0x00ee, 0x0005, 0x2068,
+       0x6800, 0xa005, 0x1de0, 0x6902, 0x2168, 0x684c, 0xd0f4, 0x15c8,
+       0x012e, 0x00ee, 0x0005, 0x012e, 0x00ee, 0x6853, 0x0006, 0x0804,
+       0x5f86, 0xd184, 0x0dc0, 0xd1c4, 0x11a8, 0x00b8, 0x6944, 0xa18c,
+       0xff00, 0x810f, 0x080c, 0x4cdc, 0x11c8, 0x6000, 0xd0e4, 0x11b0,
+       0x711c, 0xa186, 0x0007, 0x1118, 0x6853, 0x0002, 0x0088, 0x6853,
+       0x0008, 0x0070, 0x6853, 0x000e, 0x0058, 0x6853, 0x0017, 0x0040,
+       0x6853, 0x0035, 0x0028, 0x6853, 0x0028, 0x0010, 0x6853, 0x0029,
+       0x012e, 0x00ee, 0x0418, 0x6853, 0x002a, 0x0cd0, 0x6853, 0x0045,
+       0x0cb8, 0x2e60, 0x2019, 0x0002, 0x6017, 0x0014, 0x080c, 0xa566,
+       0x012e, 0x00ee, 0x0005, 0x2009, 0x003e, 0x0058, 0x2009, 0x0004,
+       0x0040, 0x2009, 0x0006, 0x0028, 0x2009, 0x0016, 0x0010, 0x2009,
+       0x0001, 0x6854, 0xa084, 0xff00, 0xa105, 0x6856, 0x0126, 0x2091,
+       0x8000, 0x080c, 0x510c, 0x012e, 0x0005, 0x080c, 0x15f0, 0x0005,
+       0x702c, 0x7130, 0x8108, 0xa102, 0x0230, 0xa00e, 0x7034, 0x7072,
+       0x7038, 0x7076, 0x0058, 0x7070, 0xa080, 0x0040, 0x7072, 0x1230,
+       0x7074, 0xa081, 0x0000, 0x7076, 0xa085, 0x0001, 0x7932, 0x7132,
+       0x0005, 0x00d6, 0x080c, 0x65a1, 0x00de, 0x0005, 0x00d6, 0x2011,
+       0x0004, 0x2204, 0xa085, 0x8002, 0x2012, 0x00de, 0x0005, 0x20e1,
+       0x0002, 0x3d08, 0x20e1, 0x2000, 0x3d00, 0xa084, 0x7000, 0x0118,
+       0xa086, 0x1000, 0x1540, 0x20e1, 0x0000, 0x3d00, 0xa094, 0xff00,
+       0x8217, 0xa084, 0xf000, 0xa086, 0x3000, 0x1118, 0x080c, 0x61c6,
+       0x00b0, 0x20e1, 0x0004, 0x3d60, 0xd1bc, 0x1108, 0x3e60, 0xac84,
+       0x0007, 0x1188, 0xac82, 0xb400, 0x0270, 0x6858, 0xac02, 0x1258,
+       0x6120, 0xd1f4, 0x1160, 0x2009, 0x0047, 0x080c, 0x80a7, 0x7a1c,
+       0xd284, 0x1968, 0x0005, 0xa016, 0x080c, 0x1824, 0x0cc0, 0x0cd8,
+       0x781c, 0xd08c, 0x0500, 0x0156, 0x0136, 0x0146, 0x20e1, 0x3000,
+       0x3d20, 0x3e28, 0xa584, 0x0076, 0x1530, 0xa484, 0x7000, 0xa086,
+       0x1000, 0x11a8, 0x080c, 0x604e, 0x01f0, 0x20e1, 0x3000, 0x7828,
+       0x7828, 0x080c, 0x606a, 0x014e, 0x013e, 0x015e, 0x2009, 0xafcf,
+       0x2104, 0xa005, 0x1108, 0x0005, 0x080c, 0x6c50, 0x0ce0, 0xa484,
+       0x7000, 0x1518, 0x0499, 0x01b8, 0x7000, 0xa084, 0xff00, 0xa086,
+       0x8100, 0x0d18, 0x0080, 0xd5a4, 0x0158, 0x080c, 0x1d86, 0x20e1,
+       0x9010, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0048,
+       0x00e9, 0x6883, 0x0000, 0x080c, 0xac59, 0x20e1, 0x3000, 0x7828,
+       0x7828, 0x014e, 0x013e, 0x015e, 0x08b0, 0x0081, 0x1130, 0x7000,
+       0xa084, 0xff00, 0xa086, 0x8100, 0x1d70, 0x080c, 0xac59, 0x20e1,
+       0x3000, 0x7828, 0x7828, 0x080c, 0x642d, 0x0c58, 0xa484, 0x01ff,
+       0x6882, 0xa005, 0x0160, 0xa080, 0x001f, 0xa084, 0x03f8, 0x80ac,
+       0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0x0005, 0x20a9,
+       0x000c, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0xa085,
+       0x0001, 0x0ca0, 0x7000, 0xa084, 0xff00, 0xa08c, 0xf000, 0x8007,
+       0xa196, 0x0000, 0x1118, 0x0804, 0x62cf, 0x0005, 0xa196, 0x2000,
+       0x1148, 0x6900, 0xa18e, 0x0001, 0x1118, 0x080c, 0x41d1, 0x0ca8,
+       0x0039, 0x0c98, 0xa196, 0x8000, 0x1d80, 0x080c, 0x6372, 0x0c68,
+       0x00c6, 0x6a80, 0x82ff, 0x0904, 0x61c0, 0x7110, 0xa18c, 0xff00,
+       0x810f, 0xa196, 0x0001, 0x0120, 0xa196, 0x0023, 0x1904, 0x61c0,
+       0xa08e, 0x0023, 0x1570, 0x080c, 0x6408, 0x0904, 0x61c0, 0x7124,
+       0x610a, 0x7030, 0xa08e, 0x0200, 0x1150, 0x7034, 0xa005, 0x1904,
+       0x61c0, 0x2009, 0x0015, 0x080c, 0x80a7, 0x0804, 0x61c0, 0xa08e,
+       0x0214, 0x0118, 0xa08e, 0x0210, 0x1130, 0x2009, 0x0015, 0x080c,
+       0x80a7, 0x0804, 0x61c0, 0xa08e, 0x0100, 0x1904, 0x61c0, 0x7034,
+       0xa005, 0x1904, 0x61c0, 0x2009, 0x0016, 0x080c, 0x80a7, 0x0804,
+       0x61c0, 0xa08e, 0x0022, 0x1904, 0x61c0, 0x7030, 0xa08e, 0x0300,
+       0x1580, 0x68d0, 0xd0a4, 0x0528, 0xc0b5, 0x68d2, 0x7100, 0xa18c,
+       0x00ff, 0x696e, 0x7004, 0x6872, 0x00f6, 0x2079, 0x0100, 0x79e6,
+       0x78ea, 0x0006, 0xa084, 0x00ff, 0x0016, 0x2008, 0x080c, 0x26a0,
+       0x7932, 0x7936, 0x001e, 0x000e, 0x00fe, 0x080c, 0x2676, 0x694e,
+       0x703c, 0x00e6, 0x2071, 0x0140, 0x7086, 0x2071, 0xad00, 0x70a2,
+       0x00ee, 0x7034, 0xa005, 0x1904, 0x61c0, 0x2009, 0x0017, 0x0804,
+       0x6193, 0xa08e, 0x0400, 0x1158, 0x7034, 0xa005, 0x1904, 0x61c0,
+       0x68d0, 0xc0a5, 0x68d2, 0x2009, 0x0030, 0x0804, 0x6193, 0xa08e,
+       0x0500, 0x1140, 0x7034, 0xa005, 0x1904, 0x61c0, 0x2009, 0x0018,
+       0x0804, 0x6193, 0xa08e, 0x2010, 0x1120, 0x2009, 0x0019, 0x0804,
+       0x6193, 0xa08e, 0x2110, 0x1120, 0x2009, 0x001a, 0x0804, 0x6193,
+       0xa08e, 0x5200, 0x1140, 0x7034, 0xa005, 0x1904, 0x61c0, 0x2009,
+       0x001b, 0x0804, 0x6193, 0xa08e, 0x5000, 0x1140, 0x7034, 0xa005,
+       0x1904, 0x61c0, 0x2009, 0x001c, 0x0804, 0x6193, 0xa08e, 0x1300,
+       0x1120, 0x2009, 0x0034, 0x0804, 0x6193, 0xa08e, 0x1200, 0x1140,
+       0x7034, 0xa005, 0x1904, 0x61c0, 0x2009, 0x0024, 0x0804, 0x6193,
+       0xa08c, 0xff00, 0xa18e, 0x2400, 0x1118, 0x2009, 0x002d, 0x04d8,
+       0xa08c, 0xff00, 0xa18e, 0x5300, 0x1118, 0x2009, 0x002a, 0x0498,
+       0xa08e, 0x0f00, 0x1118, 0x2009, 0x0020, 0x0468, 0xa08e, 0x5300,
+       0x1108, 0x00d8, 0xa08e, 0x6104, 0x11c0, 0x2011, 0xb28d, 0x8208,
+       0x2204, 0xa082, 0x0004, 0x20a8, 0x95ac, 0x95ac, 0x2011, 0x8015,
+       0x211c, 0x8108, 0x0046, 0x2124, 0x080c, 0x3c5c, 0x004e, 0x8108,
+       0x1f04, 0x6176, 0x2009, 0x0023, 0x0070, 0xa08e, 0x6000, 0x1118,
+       0x2009, 0x003f, 0x0040, 0xa08e, 0x7800, 0x1118, 0x2009, 0x0045,
+       0x0010, 0x2009, 0x001d, 0x0016, 0x2011, 0xb283, 0x2204, 0x8211,
+       0x220c, 0x080c, 0x2676, 0x1530, 0x080c, 0x4c80, 0x1518, 0x6612,
+       0x6516, 0x86ff, 0x0180, 0x001e, 0x0016, 0xa186, 0x0017, 0x1158,
+       0x686c, 0xa606, 0x1140, 0x6870, 0xa506, 0xa084, 0xff00, 0x1118,
+       0x6000, 0xc0f5, 0x6002, 0x00c6, 0x080c, 0x8022, 0x0168, 0x001e,
+       0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0x80a7,
+       0x00ce, 0x0005, 0x001e, 0x0ce0, 0x00ce, 0x0ce0, 0x00c6, 0x0046,
+       0x080c, 0x6221, 0x1904, 0x621e, 0xa184, 0xff00, 0x8007, 0xa086,
+       0x0008, 0x1904, 0x621e, 0xa28e, 0x0033, 0x11e8, 0x080c, 0x6408,
+       0x0904, 0x621e, 0x7124, 0x610a, 0x7030, 0xa08e, 0x0200, 0x1140,
+       0x7034, 0xa005, 0x15d8, 0x2009, 0x0015, 0x080c, 0x80a7, 0x04b0,
+       0xa08e, 0x0100, 0x1598, 0x7034, 0xa005, 0x1580, 0x2009, 0x0016,
+       0x080c, 0x80a7, 0x0458, 0xa28e, 0x0032, 0x1540, 0x7030, 0xa08e,
+       0x1400, 0x1520, 0x2009, 0x0038, 0x0016, 0x2011, 0xb283, 0x2204,
+       0x8211, 0x220c, 0x080c, 0x2676, 0x11c0, 0x080c, 0x4c80, 0x11a8,
+       0x6612, 0x6516, 0x00c6, 0x080c, 0x8022, 0x0170, 0x001e, 0x611a,
+       0x080c, 0x9956, 0x601f, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c,
+       0x80a7, 0x080c, 0x6c50, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce,
+       0x0005, 0x00f6, 0x00d6, 0x0026, 0x0016, 0x0136, 0x0146, 0x0156,
+       0x3c00, 0x0006, 0x2079, 0x0030, 0x2069, 0x0200, 0x080c, 0x1df2,
+       0x1590, 0x080c, 0x1ce2, 0x05c8, 0x04d9, 0x1130, 0x7908, 0xa18c,
+       0x1fff, 0xa182, 0x0011, 0x1688, 0x20a9, 0x000c, 0x20e1, 0x0000,
+       0x2ea0, 0x2099, 0x020a, 0x53a5, 0x20e1, 0x2000, 0x2001, 0x020a,
+       0x2004, 0x7a0c, 0x7808, 0xa080, 0x0007, 0xa084, 0x1ff8, 0x0401,
+       0x1120, 0xa08a, 0x0140, 0x1a0c, 0x14f6, 0x80ac, 0x20e1, 0x6000,
+       0x2099, 0x020a, 0x53a5, 0x20e1, 0x7000, 0x6828, 0x6828, 0x7803,
+       0x0004, 0xa294, 0x0070, 0x000e, 0x20e0, 0x015e, 0x014e, 0x013e,
+       0x001e, 0x002e, 0x00de, 0x00fe, 0x0005, 0xa085, 0x0001, 0x0c98,
+       0x0006, 0x2001, 0x0111, 0x2004, 0xa084, 0x0003, 0x000e, 0x0005,
+       0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130, 0xa696, 0x00ff, 0x1198,
+       0xa596, 0xfffd, 0x1120, 0x2009, 0x007f, 0x0804, 0x62ca, 0xa596,
+       0xfffe, 0x1118, 0x2009, 0x007e, 0x04e8, 0xa596, 0xfffc, 0x1118,
+       0x2009, 0x0080, 0x04b8, 0x2011, 0x0000, 0x2019, 0xad34, 0x231c,
+       0xd3ac, 0x0138, 0x2021, 0x0000, 0x20a9, 0x00ff, 0x2071, 0xae34,
+       0x0030, 0x2021, 0x0081, 0x20a9, 0x007e, 0x2071, 0xaeb5, 0x2e1c,
+       0x83ff, 0x1128, 0x82ff, 0x1198, 0x2410, 0xc2fd, 0x0080, 0x2368,
+       0x6f10, 0x0006, 0x2100, 0xa706, 0x000e, 0x6b14, 0x1120, 0xa346,
+       0x1110, 0x2408, 0x0078, 0x87ff, 0x1110, 0x83ff, 0x0d58, 0x8420,
+       0x8e70, 0x1f04, 0x62a7, 0x82ff, 0x1118, 0xa085, 0x0001, 0x0018,
+       0xc2fc, 0x2208, 0xa006, 0x00de, 0x00ee, 0x004e, 0x0005, 0xa084,
+       0x0007, 0x000a, 0x0005, 0x62db, 0x62db, 0x62db, 0x641a, 0x62db,
+       0x62dc, 0x62f1, 0x635d, 0x0005, 0x7110, 0xd1bc, 0x0188, 0x7120,
+       0x2160, 0xac8c, 0x0007, 0x1160, 0xac8a, 0xb400, 0x0248, 0x6858,
+       0xac02, 0x1230, 0x7124, 0x610a, 0x2009, 0x0046, 0x080c, 0x80a7,
+       0x0005, 0x00c6, 0x7110, 0xd1bc, 0x1904, 0x6344, 0x2011, 0xb283,
+       0x2204, 0x8211, 0x220c, 0x080c, 0x2676, 0x1904, 0x6344, 0x080c,
+       0x4c80, 0x1904, 0x6344, 0x6612, 0x6516, 0x6000, 0xd0ec, 0x15e0,
+       0x6204, 0xa294, 0xff00, 0x8217, 0xa286, 0x0006, 0x0160, 0x080c,
+       0x574f, 0x11d0, 0x6204, 0xa294, 0x00ff, 0xa286, 0x0006, 0x11a0,
+       0xa295, 0x0600, 0x6206, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0530,
+       0x611a, 0x601f, 0x0006, 0x7120, 0x610a, 0x7130, 0x6152, 0x2009,
+       0x0044, 0x080c, 0x80a7, 0x00c0, 0x00c6, 0x080c, 0x8022, 0x001e,
+       0x0198, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0xa286, 0x0004,
+       0x1118, 0x6007, 0x0005, 0x0010, 0x6007, 0x0001, 0x6003, 0x0001,
+       0x080c, 0x67ee, 0x080c, 0x6c50, 0x00ce, 0x0005, 0x00c6, 0x080c,
+       0x9807, 0x001e, 0x0dc8, 0x611a, 0x601f, 0x0006, 0x7120, 0x610a,
+       0x7130, 0x6152, 0x6013, 0x0300, 0x6003, 0x0001, 0x6007, 0x0041,
+       0x080c, 0x67a8, 0x080c, 0x6c50, 0x0c38, 0x7110, 0xd1bc, 0x0188,
+       0x7020, 0x2060, 0xac84, 0x0007, 0x1160, 0xac82, 0xb400, 0x0248,
+       0x6858, 0xac02, 0x1230, 0x7124, 0x610a, 0x2009, 0x0045, 0x080c,
+       0x80a7, 0x0005, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa18e, 0x0000,
+       0x1130, 0xa084, 0x000f, 0xa08a, 0x0006, 0x1208, 0x000b, 0x0005,
+       0x6386, 0x6387, 0x6386, 0x6386, 0x63f0, 0x63fc, 0x0005, 0x7110,
+       0xd1bc, 0x0120, 0x702c, 0xd084, 0x0904, 0x63ef, 0x700c, 0x7108,
+       0x080c, 0x2676, 0x1904, 0x63ef, 0x080c, 0x4c80, 0x1904, 0x63ef,
+       0x6612, 0x6516, 0x6204, 0x7110, 0xd1bc, 0x01f8, 0xa28c, 0x00ff,
+       0xa186, 0x0004, 0x0118, 0xa186, 0x0006, 0x15c8, 0x00c6, 0x080c,
+       0x6408, 0x00ce, 0x0904, 0x63ef, 0x00c6, 0x080c, 0x8022, 0x001e,
+       0x05f0, 0x611a, 0x080c, 0x9956, 0x601f, 0x0002, 0x7120, 0x610a,
+       0x2009, 0x0088, 0x080c, 0x80a7, 0x0490, 0xa28c, 0x00ff, 0xa186,
+       0x0006, 0x0160, 0xa186, 0x0004, 0x0148, 0xa294, 0xff00, 0x8217,
+       0xa286, 0x0004, 0x0118, 0xa286, 0x0006, 0x1188, 0x00c6, 0x080c,
+       0x8022, 0x001e, 0x01e0, 0x611a, 0x080c, 0x9956, 0x601f, 0x0005,
+       0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0x80a7, 0x0080, 0x00c6,
+       0x080c, 0x8022, 0x001e, 0x0158, 0x611a, 0x080c, 0x9956, 0x601f,
+       0x0004, 0x7120, 0x610a, 0x2009, 0x0001, 0x080c, 0x80a7, 0x0005,
+       0x7110, 0xd1bc, 0x0140, 0x00a1, 0x0130, 0x7124, 0x610a, 0x2009,
+       0x0089, 0x080c, 0x80a7, 0x0005, 0x7110, 0xd1bc, 0x0140, 0x0041,
+       0x0130, 0x7124, 0x610a, 0x2009, 0x008a, 0x080c, 0x80a7, 0x0005,
+       0x7020, 0x2060, 0xac84, 0x0007, 0x1158, 0xac82, 0xb400, 0x0240,
+       0x2001, 0xad16, 0x2004, 0xac02, 0x1218, 0xa085, 0x0001, 0x0005,
+       0xa006, 0x0ce8, 0x7110, 0xd1bc, 0x1178, 0x7024, 0x2060, 0xac84,
+       0x0007, 0x1150, 0xac82, 0xb400, 0x0238, 0x6858, 0xac02, 0x1220,
+       0x2009, 0x0051, 0x080c, 0x80a7, 0x0005, 0x2031, 0x0105, 0x0069,
+       0x0005, 0x2031, 0x0206, 0x0049, 0x0005, 0x2031, 0x0207, 0x0029,
+       0x0005, 0x2031, 0x0213, 0x0009, 0x0005, 0x00c6, 0x00d6, 0x00f6,
+       0x7000, 0xa084, 0xf000, 0xa086, 0xc000, 0x05b0, 0x080c, 0x8022,
+       0x0598, 0x0066, 0x00c6, 0x0046, 0x2011, 0xb283, 0x2204, 0x8211,
+       0x220c, 0x080c, 0x2676, 0x1580, 0x080c, 0x4c80, 0x1568, 0x6612,
+       0x6516, 0x2c00, 0x004e, 0x00ce, 0x601a, 0x080c, 0x9956, 0x080c,
+       0x15d9, 0x01f0, 0x2d00, 0x6056, 0x6803, 0x0000, 0x6837, 0x0000,
+       0x6c3a, 0xadf8, 0x000f, 0x20a9, 0x000e, 0x2fa0, 0x2e98, 0x53a3,
+       0x006e, 0x6612, 0x6007, 0x003e, 0x601f, 0x0001, 0x6003, 0x0001,
+       0x080c, 0x67ee, 0x080c, 0x6c50, 0x00fe, 0x00de, 0x00ce, 0x0005,
+       0x080c, 0x8078, 0x006e, 0x0cc0, 0x004e, 0x00ce, 0x0cc8, 0x2071,
+       0xafda, 0x7003, 0x0003, 0x700f, 0x0361, 0xa006, 0x701a, 0x7012,
+       0x7017, 0xb400, 0x7007, 0x0000, 0x7026, 0x702b, 0x7841, 0x7032,
+       0x7037, 0x789d, 0x703b, 0xffff, 0x703f, 0xffff, 0x7042, 0x7047,
+       0x41b3, 0x0005, 0x2071, 0xafda, 0x1d04, 0x64fc, 0x2091, 0x6000,
+       0x700c, 0x8001, 0x700e, 0x1180, 0x700f, 0x0361, 0x7007, 0x0001,
+       0x0126, 0x2091, 0x8000, 0x7040, 0xa00d, 0x0148, 0x8109, 0x7142,
+       0x1130, 0x7044, 0x080f, 0x0018, 0x0126, 0x2091, 0x8000, 0x7024,
+       0xa00d, 0x0188, 0x7020, 0x8001, 0x7022, 0x1168, 0x7023, 0x0009,
+       0x8109, 0x7126, 0xa186, 0x03e8, 0x1110, 0x7028, 0x080f, 0x81ff,
+       0x1110, 0x7028, 0x080f, 0x7030, 0xa00d, 0x0158, 0x702c, 0x8001,
+       0x702e, 0x1138, 0x702f, 0x0009, 0x8109, 0x7132, 0x1110, 0x7034,
+       0x080f, 0x7038, 0xa005, 0x0118, 0x0310, 0x8001, 0x703a, 0x703c,
+       0xa005, 0x0118, 0x0310, 0x8001, 0x703e, 0x7018, 0xa00d, 0x0158,
+       0x7008, 0x8001, 0x700a, 0x1138, 0x700b, 0x0009, 0x8109, 0x711a,
+       0x1110, 0x701c, 0x080f, 0x012e, 0x7004, 0x0002, 0x6522, 0x6523,
+       0x653b, 0x00e6, 0x2071, 0xafda, 0x7018, 0xa005, 0x1120, 0x711a,
+       0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071,
+       0xafda, 0x701c, 0xa206, 0x1110, 0x701a, 0x701e, 0x000e, 0x00ee,
+       0x0005, 0x00e6, 0x2071, 0xafda, 0x6088, 0xa102, 0x0208, 0x618a,
+       0x00ee, 0x0005, 0x0005, 0x7110, 0x080c, 0x4cdc, 0x1158, 0x6088,
+       0x8001, 0x0240, 0x608a, 0x1130, 0x0126, 0x2091, 0x8000, 0x080c,
+       0x6c50, 0x012e, 0x8108, 0xa182, 0x00ff, 0x0218, 0xa00e, 0x7007,
+       0x0002, 0x7112, 0x0005, 0x7014, 0x2060, 0x0126, 0x2091, 0x8000,
+       0x603c, 0xa005, 0x0128, 0x8001, 0x603e, 0x1110, 0x080c, 0x9846,
+       0x6014, 0xa005, 0x0500, 0x8001, 0x6016, 0x11e8, 0x611c, 0xa186,
+       0x0003, 0x0118, 0xa186, 0x0006, 0x11a0, 0x6010, 0x2068, 0x6854,
+       0xa08a, 0x199a, 0x0270, 0xa082, 0x1999, 0x6856, 0xa08a, 0x199a,
+       0x0210, 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116,
+       0x0010, 0x080c, 0x9350, 0x012e, 0xac88, 0x0018, 0x7116, 0x2001,
+       0xe400, 0xa102, 0x0220, 0x7017, 0xb400, 0x7007, 0x0000, 0x0005,
+       0x00e6, 0x2071, 0xafda, 0x7027, 0x07d0, 0x7023, 0x0009, 0x00ee,
+       0x0005, 0x2001, 0xafe3, 0x2003, 0x0000, 0x0005, 0x00e6, 0x2071,
+       0xafda, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011, 0xafe6,
+       0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0xafda, 0x711a, 0x721e,
+       0x700b, 0x0009, 0x00ee, 0x0005, 0x00c6, 0x2061, 0xb048, 0x00ce,
+       0x0005, 0xa184, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0xb048,
+       0x2060, 0x0005, 0x6854, 0xa08a, 0x199a, 0x0210, 0x2001, 0x1999,
+       0xa005, 0x1150, 0x00c6, 0x2061, 0xb048, 0x6014, 0x00ce, 0xa005,
+       0x1138, 0x2001, 0x001e, 0x0020, 0xa08e, 0xffff, 0x1108, 0xa006,
+       0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x684c, 0xa08c, 0x00c0,
+       0xa18e, 0x00c0, 0x05b0, 0xd0b4, 0x1138, 0xd0bc, 0x1528, 0x2009,
+       0x0006, 0x080c, 0x661a, 0x0005, 0xd0fc, 0x0130, 0xa084, 0x0003,
+       0x0118, 0xa086, 0x0003, 0x15c0, 0x6020, 0xd0d4, 0x0130, 0xc0d4,
+       0x6022, 0x6860, 0x602a, 0x685c, 0x602e, 0x2009, 0xad73, 0x2104,
+       0xd084, 0x0128, 0x2009, 0x0042, 0x080c, 0x80a7, 0x0005, 0x2009,
+       0x0043, 0x080c, 0x80a7, 0x0005, 0xd0fc, 0x0130, 0xa084, 0x0003,
+       0x0118, 0xa086, 0x0003, 0x11c0, 0x2009, 0x0042, 0x080c, 0x80a7,
+       0x0005, 0xd0fc, 0x0150, 0xa084, 0x0003, 0xa08e, 0x0002, 0x0138,
+       0x2009, 0x0041, 0x080c, 0x80a7, 0x0005, 0x0051, 0x0ce8, 0x2009,
+       0x0043, 0x080c, 0x80a7, 0x0cc0, 0x2009, 0x0004, 0x0019, 0x0005,
+       0x2009, 0x0001, 0x00d6, 0x6010, 0xa0ec, 0xf000, 0x01f0, 0x2068,
+       0x6952, 0x6800, 0x6012, 0xa186, 0x0001, 0x1188, 0x694c, 0xa18c,
+       0x8100, 0xa18e, 0x8100, 0x1158, 0x00c6, 0x2061, 0xb048, 0x6200,
+       0xd28c, 0x1120, 0x6204, 0x8210, 0x0208, 0x6206, 0x00ce, 0x080c,
+       0x510c, 0x6010, 0xa06d, 0x190c, 0x65aa, 0x00de, 0x0005, 0x0156,
+       0x00c6, 0x2061, 0xb048, 0x6000, 0x81ff, 0x0110, 0xa205, 0x0008,
+       0xa204, 0x6002, 0x00ce, 0x015e, 0x0005, 0x6800, 0xd08c, 0x1138,
+       0x6808, 0xa005, 0x0120, 0x8001, 0x680a, 0xa085, 0x0001, 0x0005,
+       0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e, 0x1208, 0xa200,
+       0x1f04, 0x665c, 0x8086, 0x818e, 0x0005, 0x0156, 0x20a9, 0x0010,
+       0xa005, 0x01b8, 0xa11a, 0x12a8, 0x8213, 0x818d, 0x0228, 0xa11a,
+       0x1220, 0x1f04, 0x666c, 0x0028, 0xa11a, 0x2308, 0x8210, 0x1f04,
+       0x666c, 0x0006, 0x3200, 0xa084, 0xefff, 0x2080, 0x000e, 0x015e,
+       0x0005, 0x0006, 0x3200, 0xa085, 0x1000, 0x0cb8, 0x0126, 0x2091,
+       0x2800, 0x2079, 0xafc7, 0x012e, 0x00d6, 0x2069, 0xafc7, 0x6803,
+       0x0005, 0x2069, 0x0004, 0x2d04, 0xa085, 0x8001, 0x206a, 0x00de,
+       0x0005, 0x00c6, 0x6027, 0x0001, 0x7804, 0xa084, 0x0007, 0x0002,
+       0x66aa, 0x66cb, 0x671e, 0x66b0, 0x66cb, 0x66aa, 0x66a8, 0x66a8,
+       0x080c, 0x14f6, 0x080c, 0x6581, 0x080c, 0x6c50, 0x00ce, 0x0005,
+       0x62c0, 0x82ff, 0x1110, 0x00ce, 0x0005, 0x2011, 0x481b, 0x080c,
+       0x650d, 0x7828, 0xa092, 0x00c8, 0x1228, 0x8000, 0x782a, 0x080c,
+       0x4855, 0x0c88, 0x080c, 0x481b, 0x7807, 0x0003, 0x7827, 0x0000,
+       0x782b, 0x0000, 0x0c40, 0x080c, 0x6581, 0x3c00, 0x0006, 0x2011,
+       0x0209, 0x20e1, 0x4000, 0x2214, 0x000e, 0x20e0, 0x82ff, 0x0178,
+       0x62c0, 0x82ff, 0x1160, 0x782b, 0x0000, 0x7824, 0xa065, 0x090c,
+       0x14f6, 0x2009, 0x0013, 0x080c, 0x80a7, 0x00ce, 0x0005, 0x3900,
+       0xa082, 0xb0e8, 0x1210, 0x080c, 0x7d8d, 0x00c6, 0x7824, 0xa065,
+       0x090c, 0x14f6, 0x7804, 0xa086, 0x0004, 0x0904, 0x675e, 0x7828,
+       0xa092, 0x2710, 0x1230, 0x8000, 0x782a, 0x00ce, 0x080c, 0x7827,
+       0x0c20, 0x6104, 0xa186, 0x0003, 0x1188, 0x00e6, 0x2071, 0xad00,
+       0x70dc, 0x00ee, 0xd08c, 0x0150, 0x00c6, 0x00e6, 0x2061, 0x0100,
+       0x2071, 0xad00, 0x080c, 0x485e, 0x00ee, 0x00ce, 0x080c, 0xaca2,
+       0x2009, 0x0014, 0x080c, 0x80a7, 0x00ce, 0x0838, 0x2001, 0xafe3,
+       0x2003, 0x0000, 0x62c0, 0x82ff, 0x1160, 0x782b, 0x0000, 0x7824,
+       0xa065, 0x090c, 0x14f6, 0x2009, 0x0013, 0x080c, 0x80fb, 0x00ce,
+       0x0005, 0x00c6, 0x00d6, 0x3900, 0xa082, 0xb0e8, 0x1210, 0x080c,
+       0x7d8d, 0x7824, 0xa005, 0x090c, 0x14f6, 0x781c, 0xa06d, 0x090c,
+       0x14f6, 0x6800, 0xc0dc, 0x6802, 0x7924, 0x2160, 0x080c, 0x8078,
+       0x693c, 0x81ff, 0x090c, 0x14f6, 0x8109, 0x693e, 0x6854, 0xa015,
+       0x0110, 0x7a1e, 0x0010, 0x7918, 0x791e, 0x7807, 0x0000, 0x7827,
+       0x0000, 0x00de, 0x00ce, 0x080c, 0x6c50, 0x0888, 0x6104, 0xa186,
+       0x0002, 0x0128, 0xa186, 0x0004, 0x0110, 0x0804, 0x66f7, 0x7808,
+       0xac06, 0x0904, 0x66f7, 0x080c, 0x6b73, 0x080c, 0x67ee, 0x00ce,
+       0x080c, 0x6c50, 0x0804, 0x66e5, 0x00c6, 0x6027, 0x0002, 0x62c8,
+       0x60c4, 0xa205, 0x1178, 0x793c, 0xa1e5, 0x0000, 0x0130, 0x2009,
+       0x0049, 0x080c, 0x80a7, 0x00ce, 0x0005, 0x2011, 0xafe6, 0x2013,
+       0x0000, 0x0cc8, 0x3908, 0xa192, 0xb0e8, 0x1210, 0x080c, 0x7d8d,
+       0x793c, 0x81ff, 0x0d90, 0x793c, 0xa188, 0x0007, 0x210c, 0xa18e,
+       0x0006, 0x1138, 0x6014, 0xa084, 0x0184, 0xa085, 0x0012, 0x6016,
+       0x0c10, 0x6014, 0xa084, 0x0184, 0xa085, 0x0016, 0x6016, 0x08d8,
+       0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000,
+       0x2c08, 0x2061, 0xafc7, 0x6020, 0x8000, 0x6022, 0x6010, 0xa005,
+       0x0148, 0xa080, 0x0003, 0x2102, 0x6112, 0x012e, 0x00ce, 0x001e,
+       0x000e, 0x0005, 0x6116, 0x6112, 0x0cc0, 0x00d6, 0x2069, 0xafc7,
+       0x6000, 0xd0d4, 0x0168, 0x6820, 0x8000, 0x6822, 0xa086, 0x0001,
+       0x1110, 0x2c00, 0x681e, 0x6804, 0xa084, 0x0007, 0x0804, 0x6c56,
+       0xc0d5, 0x6002, 0x6818, 0xa005, 0x0158, 0x6056, 0x605b, 0x0000,
+       0x0006, 0x2c00, 0x681a, 0x00de, 0x685a, 0x2069, 0xafc7, 0x0c18,
+       0x6056, 0x605a, 0x2c00, 0x681a, 0x681e, 0x08e8, 0x0006, 0x0016,
+       0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061,
+       0xafc7, 0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0148, 0xa080,
+       0x0003, 0x2102, 0x610a, 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005,
+       0x610e, 0x610a, 0x0cc0, 0x00c6, 0x600f, 0x0000, 0x2c08, 0x2061,
+       0xafc7, 0x6034, 0xa005, 0x0130, 0xa080, 0x0003, 0x2102, 0x6136,
+       0x00ce, 0x0005, 0x613a, 0x6136, 0x0cd8, 0x00f6, 0x00e6, 0x00d6,
+       0x00c6, 0x0076, 0x0066, 0x0026, 0x0016, 0x0006, 0x0126, 0x2071,
+       0xafc7, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0904,
+       0x6889, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904, 0x6884,
+       0x87ff, 0x0120, 0x6050, 0xa106, 0x1904, 0x6884, 0x703c, 0xac06,
+       0x1170, 0x0036, 0x2019, 0x0001, 0x080c, 0x7a64, 0x7033, 0x0000,
+       0x703f, 0x0000, 0x7043, 0x0000, 0x7047, 0x0000, 0x003e, 0x7038,
+       0xac36, 0x1110, 0x660c, 0x763a, 0x7034, 0xac36, 0x1140, 0x2c00,
+       0xaf36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c,
+       0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f,
+       0x0000, 0x080c, 0x9596, 0x0198, 0x6010, 0x2068, 0x601c, 0xa086,
+       0x0003, 0x1510, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c,
+       0x97fd, 0x080c, 0xabfa, 0x080c, 0x510c, 0x080c, 0x9742, 0x080c,
+       0x974e, 0x00ce, 0x0804, 0x682e, 0x2c78, 0x600c, 0x2060, 0x0804,
+       0x682e, 0x012e, 0x000e, 0x001e, 0x002e, 0x006e, 0x007e, 0x00ce,
+       0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086, 0x0006, 0x19d0,
+       0x080c, 0xabfa, 0x080c, 0xa91f, 0x0c10, 0x0006, 0x0066, 0x00c6,
+       0x00d6, 0x00f6, 0x2031, 0x0000, 0x0126, 0x2091, 0x8000, 0x2079,
+       0xafc7, 0x7838, 0xa065, 0x0558, 0x600c, 0x0006, 0x600f, 0x0000,
+       0x783c, 0xac06, 0x1170, 0x0036, 0x2019, 0x0001, 0x080c, 0x7a64,
+       0x7833, 0x0000, 0x783f, 0x0000, 0x7843, 0x0000, 0x7847, 0x0000,
+       0x003e, 0x080c, 0x9596, 0x0178, 0x6010, 0x2068, 0x601c, 0xa086,
+       0x0003, 0x11b0, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c,
+       0x510c, 0x080c, 0x9742, 0x080c, 0x974e, 0x000e, 0x0898, 0x7e3a,
+       0x7e36, 0x012e, 0x00fe, 0x00de, 0x00ce, 0x006e, 0x000e, 0x0005,
+       0x601c, 0xa086, 0x0006, 0x1d30, 0x080c, 0xa91f, 0x0c60, 0x0016,
+       0x0026, 0x0086, 0x2041, 0x0000, 0x0099, 0x080c, 0x69a9, 0x008e,
+       0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079, 0xafc7, 0x2091,
+       0x8000, 0x080c, 0x6a36, 0x080c, 0x6aa8, 0x012e, 0x00fe, 0x0005,
+       0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0016, 0x0006, 0x0126,
+       0x2091, 0x8000, 0x2071, 0xafc7, 0x7614, 0x2660, 0x2678, 0x8cff,
+       0x0904, 0x6985, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904,
+       0x6980, 0x88ff, 0x0120, 0x6050, 0xa106, 0x1904, 0x6980, 0x7024,
+       0xac06, 0x1538, 0x2069, 0x0100, 0x68c0, 0xa005, 0x01f0, 0x080c,
+       0x6581, 0x080c, 0x7834, 0x68c3, 0x0000, 0x080c, 0x7ca8, 0x7027,
+       0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120,
+       0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084,
+       0x0110, 0x6827, 0x0001, 0x003e, 0x0020, 0x6003, 0x0009, 0x630a,
+       0x04b8, 0x7014, 0xac36, 0x1110, 0x660c, 0x7616, 0x7010, 0xac36,
+       0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013,
+       0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008,
+       0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x080c, 0x9596, 0x0188,
+       0x601c, 0xa086, 0x0003, 0x1510, 0x6837, 0x0103, 0x6b4a, 0x6847,
+       0x0000, 0x080c, 0x97fd, 0x080c, 0xabfa, 0x080c, 0x510c, 0x080c,
+       0x9742, 0x080c, 0x974e, 0x080c, 0x7b88, 0x00ce, 0x0804, 0x690f,
+       0x2c78, 0x600c, 0x2060, 0x0804, 0x690f, 0x012e, 0x000e, 0x001e,
+       0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086,
+       0x0006, 0x1128, 0x080c, 0xabfa, 0x080c, 0xa91f, 0x0c10, 0x601c,
+       0xa086, 0x0002, 0x1128, 0x6004, 0xa086, 0x0085, 0x0968, 0x08c8,
+       0x601c, 0xa086, 0x0005, 0x19a8, 0x6004, 0xa086, 0x0085, 0x0d50,
+       0x0880, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0xa280, 0xae34,
+       0x2004, 0xa065, 0x0904, 0x6a32, 0x00f6, 0x00e6, 0x00d6, 0x0066,
+       0x2071, 0xafc7, 0x6654, 0x7018, 0xac06, 0x1108, 0x761a, 0x701c,
+       0xac06, 0x1130, 0x86ff, 0x1118, 0x7018, 0x701e, 0x0008, 0x761e,
+       0x6058, 0xa07d, 0x0108, 0x7e56, 0xa6ed, 0x0000, 0x0110, 0x2f00,
+       0x685a, 0x6057, 0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc,
+       0x6002, 0x080c, 0x4c07, 0x0904, 0x6a2e, 0x7624, 0x86ff, 0x05e8,
+       0xa680, 0x0004, 0x2004, 0xad06, 0x15c0, 0x00d6, 0x2069, 0x0100,
+       0x68c0, 0xa005, 0x0548, 0x080c, 0x6581, 0x080c, 0x7834, 0x68c3,
+       0x0000, 0x080c, 0x7ca8, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140,
+       0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, 0x0000,
+       0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e,
+       0x00de, 0x00c6, 0x603c, 0xa005, 0x0110, 0x8001, 0x603e, 0x2660,
+       0x080c, 0x974e, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003,
+       0x0009, 0x630a, 0x00ce, 0x0804, 0x69d9, 0x8dff, 0x0158, 0x6837,
+       0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x97fd, 0x080c, 0xabfa,
+       0x080c, 0x510c, 0x080c, 0x7b88, 0x0804, 0x69d9, 0x006e, 0x00de,
+       0x00ee, 0x00fe, 0x012e, 0x000e, 0x00ce, 0x0005, 0x0006, 0x0066,
+       0x00c6, 0x00d6, 0x2031, 0x0000, 0x7814, 0xa065, 0x0904, 0x6a88,
+       0x600c, 0x0006, 0x600f, 0x0000, 0x7824, 0xac06, 0x1540, 0x2069,
+       0x0100, 0x68c0, 0xa005, 0x01f0, 0x080c, 0x6581, 0x080c, 0x7834,
+       0x68c3, 0x0000, 0x080c, 0x7ca8, 0x7827, 0x0000, 0x0036, 0x2069,
+       0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803,
+       0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001,
+       0x003e, 0x0028, 0x6003, 0x0009, 0x630a, 0x2c30, 0x00b0, 0x6010,
+       0x2068, 0x080c, 0x9596, 0x0168, 0x601c, 0xa086, 0x0003, 0x11b8,
+       0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x510c, 0x080c,
+       0x9742, 0x080c, 0x974e, 0x080c, 0x7b88, 0x000e, 0x0804, 0x6a3d,
+       0x7e16, 0x7e12, 0x00de, 0x00ce, 0x006e, 0x000e, 0x0005, 0x601c,
+       0xa086, 0x0006, 0x1118, 0x080c, 0xa91f, 0x0c58, 0x601c, 0xa086,
+       0x0002, 0x1128, 0x6004, 0xa086, 0x0085, 0x09d0, 0x0c10, 0x601c,
+       0xa086, 0x0005, 0x19f0, 0x6004, 0xa086, 0x0085, 0x0d60, 0x08c8,
+       0x0006, 0x0066, 0x00c6, 0x00d6, 0x7818, 0xa065, 0x0904, 0x6b0e,
+       0x6054, 0x0006, 0x6057, 0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4,
+       0xc0dc, 0x6002, 0x080c, 0x4c07, 0x0904, 0x6b0b, 0x7e24, 0x86ff,
+       0x05e8, 0xa680, 0x0004, 0x2004, 0xad06, 0x15c0, 0x00d6, 0x2069,
+       0x0100, 0x68c0, 0xa005, 0x0548, 0x080c, 0x6581, 0x080c, 0x7834,
+       0x68c3, 0x0000, 0x080c, 0x7ca8, 0x7827, 0x0000, 0x0036, 0x2069,
+       0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803,
+       0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001,
+       0x003e, 0x00de, 0x00c6, 0x603c, 0xa005, 0x0110, 0x8001, 0x603e,
+       0x2660, 0x080c, 0x974e, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660,
+       0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x6aba, 0x8dff, 0x0138,
+       0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x510c, 0x080c,
+       0x7b88, 0x0804, 0x6aba, 0x000e, 0x0804, 0x6aad, 0x781e, 0x781a,
+       0x00de, 0x00ce, 0x006e, 0x000e, 0x0005, 0x00e6, 0x00d6, 0x0066,
+       0x6000, 0xd0dc, 0x0188, 0x604c, 0xa06d, 0x0170, 0x6848, 0xa606,
+       0x1158, 0x2071, 0xafc7, 0x7024, 0xa035, 0x0130, 0xa080, 0x0004,
+       0x2004, 0xad06, 0x1108, 0x0021, 0x006e, 0x00de, 0x00ee, 0x0005,
+       0x00f6, 0x2079, 0x0100, 0x78c0, 0xa005, 0x1138, 0x00c6, 0x2660,
+       0x6003, 0x0009, 0x630a, 0x00ce, 0x04a0, 0x080c, 0x7834, 0x78c3,
+       0x0000, 0x080c, 0x7ca8, 0x7027, 0x0000, 0x0036, 0x2079, 0x0140,
+       0x7b04, 0xa384, 0x1000, 0x0120, 0x7803, 0x0100, 0x7803, 0x0000,
+       0x2079, 0x0100, 0x7824, 0xd084, 0x0110, 0x7827, 0x0001, 0x080c,
+       0x7ca8, 0x003e, 0x080c, 0x4c07, 0x00c6, 0x603c, 0xa005, 0x0110,
+       0x8001, 0x603e, 0x2660, 0x080c, 0x8078, 0x00ce, 0x6837, 0x0103,
+       0x6b4a, 0x6847, 0x0000, 0x080c, 0x97fd, 0x080c, 0x510c, 0x080c,
+       0x7b88, 0x00fe, 0x0005, 0x00e6, 0x00c6, 0x2071, 0xafc7, 0x7004,
+       0xa084, 0x0007, 0x0002, 0x6b85, 0x6b88, 0x6b9e, 0x6bb7, 0x6bf0,
+       0x6b85, 0x6b83, 0x6b83, 0x080c, 0x14f6, 0x00ce, 0x00ee, 0x0005,
+       0x7024, 0xa065, 0x0148, 0x7020, 0x8001, 0x7022, 0x600c, 0xa015,
+       0x0150, 0x7216, 0x600f, 0x0000, 0x7007, 0x0000, 0x7027, 0x0000,
+       0x00ce, 0x00ee, 0x0005, 0x7216, 0x7212, 0x0cb0, 0x6018, 0x2060,
+       0x080c, 0x4c07, 0x6000, 0xc0dc, 0x6002, 0x7020, 0x8001, 0x7022,
+       0x0120, 0x6054, 0xa015, 0x0140, 0x721e, 0x7007, 0x0000, 0x7027,
+       0x0000, 0x00ce, 0x00ee, 0x0005, 0x7218, 0x721e, 0x0cb0, 0x7024,
+       0xa065, 0x0598, 0x700c, 0xac06, 0x1160, 0x080c, 0x7b88, 0x600c,
+       0xa015, 0x0120, 0x720e, 0x600f, 0x0000, 0x0428, 0x720e, 0x720a,
+       0x0410, 0x7014, 0xac06, 0x1160, 0x080c, 0x7b88, 0x600c, 0xa015,
+       0x0120, 0x7216, 0x600f, 0x0000, 0x00b0, 0x7216, 0x7212, 0x0098,
+       0x6018, 0x2060, 0x080c, 0x4c07, 0x6000, 0xc0dc, 0x6002, 0x080c,
+       0x7b88, 0x701c, 0xa065, 0x0138, 0x6054, 0xa015, 0x0110, 0x721e,
+       0x0010, 0x7218, 0x721e, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x0005,
+       0x7024, 0xa065, 0x0140, 0x080c, 0x7b88, 0x600c, 0xa015, 0x0150,
+       0x720e, 0x600f, 0x0000, 0x080c, 0x7ca8, 0x7027, 0x0000, 0x00ce,
+       0x00ee, 0x0005, 0x720e, 0x720a, 0x0cb0, 0x00d6, 0x2069, 0xafc7,
+       0x6830, 0xa084, 0x0003, 0x0002, 0x6c12, 0x6c14, 0x6c38, 0x6c10,
+       0x080c, 0x14f6, 0x00de, 0x0005, 0x00c6, 0x6840, 0xa086, 0x0001,
+       0x01b8, 0x683c, 0xa065, 0x0130, 0x600c, 0xa015, 0x0170, 0x6a3a,
+       0x600f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x2011, 0xafe6,
+       0x2013, 0x0000, 0x00ce, 0x00de, 0x0005, 0x683a, 0x6836, 0x0c90,
+       0x6843, 0x0000, 0x6838, 0xa065, 0x0d68, 0x6003, 0x0003, 0x0c50,
+       0x00c6, 0x6843, 0x0000, 0x6847, 0x0000, 0x683c, 0xa065, 0x0168,
+       0x600c, 0xa015, 0x0130, 0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000,
+       0x0020, 0x683f, 0x0000, 0x683a, 0x6836, 0x00ce, 0x00de, 0x0005,
+       0x00d6, 0x2069, 0xafc7, 0x6804, 0xa084, 0x0007, 0x0002, 0x6c61,
+       0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x6cff, 0x6c5f, 0x6c5f, 0x080c,
+       0x14f6, 0x6820, 0xa005, 0x1110, 0x00de, 0x0005, 0x00c6, 0x680c,
+       0xa065, 0x0150, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c,
+       0x6d49, 0x00ce, 0x00de, 0x0005, 0x6814, 0xa065, 0x0150, 0x6807,
+       0x0001, 0x6826, 0x682b, 0x0000, 0x080c, 0x6d49, 0x00ce, 0x00de,
+       0x0005, 0x00e6, 0x0036, 0x6a1c, 0xa2f5, 0x0000, 0x0904, 0x6cf9,
+       0x704c, 0xa00d, 0x0118, 0x7088, 0xa005, 0x01a0, 0x7054, 0xa075,
+       0x0120, 0xa20e, 0x0904, 0x6cf9, 0x0028, 0x6818, 0xa20e, 0x0904,
+       0x6cf9, 0x2070, 0x704c, 0xa00d, 0x0d88, 0x7088, 0xa005, 0x1d70,
+       0x2e00, 0x681e, 0x733c, 0x7038, 0xa302, 0x1e40, 0x080c, 0x804f,
+       0x0904, 0x6cf9, 0x8318, 0x733e, 0x6112, 0x2e10, 0x621a, 0xa180,
+       0x0014, 0x2004, 0xa084, 0x00ff, 0x605a, 0xa180, 0x0014, 0x2003,
+       0x0000, 0xa180, 0x0015, 0x2004, 0xa08a, 0x199a, 0x0210, 0x2001,
+       0x1999, 0x8003, 0x801b, 0x831b, 0xa318, 0x6316, 0x003e, 0x00f6,
+       0x2c78, 0x71a0, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x1110, 0xd1bc,
+       0x0150, 0x7100, 0xd1f4, 0x0120, 0x7114, 0xa18c, 0x00ff, 0x0040,
+       0x2009, 0x0000, 0x0028, 0xa1e0, 0x2be6, 0x2c0d, 0xa18c, 0x00ff,
+       0x2061, 0x0100, 0x619a, 0x080c, 0x736f, 0x7300, 0xc3dd, 0x7302,
+       0x6807, 0x0002, 0x2f18, 0x6b26, 0x682b, 0x0000, 0x781f, 0x0003,
+       0x7803, 0x0001, 0x7807, 0x0040, 0x00fe, 0x00ee, 0x00ce, 0x00de,
+       0x0005, 0x003e, 0x00ee, 0x00ce, 0x0cd0, 0x00de, 0x0005, 0x00c6,
+       0x680c, 0xa065, 0x0138, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000,
+       0x080c, 0x6d49, 0x00ce, 0x00de, 0x0005, 0x00f6, 0x00d6, 0x2069,
+       0xafc7, 0x6830, 0xa086, 0x0000, 0x11c0, 0x2001, 0xad0c, 0x200c,
+       0xd1bc, 0x1550, 0x6838, 0xa07d, 0x0180, 0x6833, 0x0001, 0x683e,
+       0x6847, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c,
+       0x1ee6, 0x1130, 0x012e, 0x080c, 0x76a5, 0x00de, 0x00fe, 0x0005,
+       0x012e, 0xe000, 0x6843, 0x0000, 0x7803, 0x0002, 0x780c, 0xa015,
+       0x0140, 0x6a3a, 0x780f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000,
+       0x0c60, 0x683a, 0x6836, 0x0cc0, 0xc1bc, 0x2102, 0x080c, 0x57d1,
+       0x0888, 0x601c, 0xa084, 0x000f, 0x000b, 0x0005, 0x6d57, 0x6d5c,
+       0x7210, 0x732c, 0x6d5c, 0x7210, 0x732c, 0x6d57, 0x6d5c, 0x080c,
+       0x6b73, 0x080c, 0x6c50, 0x0005, 0x0156, 0x0136, 0x0146, 0x00c6,
+       0x00f6, 0x6004, 0xa08a, 0x0080, 0x1a0c, 0x14f6, 0x6118, 0x2178,
+       0x79a0, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd1bc, 0x0150,
+       0x7900, 0xd1f4, 0x0120, 0x7914, 0xa18c, 0x00ff, 0x0040, 0x2009,
+       0x0000, 0x0028, 0xa1f8, 0x2be6, 0x2f0d, 0xa18c, 0x00ff, 0x2c78,
+       0x2061, 0x0100, 0x619a, 0xa08a, 0x0040, 0x1a04, 0x6dd0, 0x0033,
+       0x00fe, 0x00ce, 0x014e, 0x013e, 0x015e, 0x0005, 0x6e7c, 0x6ec7,
+       0x6ef4, 0x6fc1, 0x6fef, 0x6ff7, 0x701d, 0x702e, 0x703f, 0x7047,
+       0x705d, 0x7047, 0x70b7, 0x702e, 0x70d8, 0x70e0, 0x703f, 0x70e0,
+       0x70f1, 0x6dce, 0x6dce, 0x6dce, 0x6dce, 0x6dce, 0x6dce, 0x6dce,
+       0x6dce, 0x6dce, 0x6dce, 0x6dce, 0x790d, 0x7932, 0x7947, 0x796a,
+       0x798b, 0x701d, 0x6dce, 0x701d, 0x7047, 0x6dce, 0x6ef4, 0x6fc1,
+       0x6dce, 0x7daa, 0x7047, 0x6dce, 0x7dca, 0x7047, 0x6dce, 0x703f,
+       0x6e75, 0x6de0, 0x6dce, 0x7def, 0x7e64, 0x7f3b, 0x6dce, 0x7f4c,
+       0x7018, 0x7f68, 0x6dce, 0x79a0, 0x7fc3, 0x6dce, 0x080c, 0x14f6,
+       0x2100, 0x0033, 0x00fe, 0x00ce, 0x014e, 0x013e, 0x015e, 0x0005,
+       0x6dde, 0x6dde, 0x6dde, 0x6e14, 0x6e32, 0x6e48, 0x080c, 0x14f6,
+       0x00d6, 0x20a1, 0x020b, 0x080c, 0x710e, 0x7810, 0x2068, 0x20a3,
+       0x2414, 0x20a3, 0x0018, 0x20a3, 0x0800, 0x683c, 0x20a2, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x6850,
+       0x20a2, 0x6854, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
+       0x0018, 0x080c, 0x7821, 0x00de, 0x0005, 0x00d6, 0x7818, 0x2068,
+       0x68a0, 0x2069, 0xad00, 0x6ad0, 0xd2ac, 0x1110, 0xd0bc, 0x0110,
+       0xa085, 0x0001, 0x00de, 0x0005, 0x00d6, 0x20a1, 0x020b, 0x080c,
+       0x710e, 0x20a3, 0x0500, 0x20a3, 0x0000, 0x7810, 0xa0e8, 0x000f,
+       0x6808, 0x20a2, 0x680c, 0x20a2, 0x6810, 0x20a2, 0x6814, 0x20a2,
+       0x6818, 0x20a2, 0x681c, 0x20a2, 0x60c3, 0x0010, 0x080c, 0x7821,
+       0x00de, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x710e,
+       0x20a3, 0x7800, 0x20a3, 0x0000, 0x7808, 0x8007, 0x20a2, 0x20a3,
+       0x0000, 0x60c3, 0x0008, 0x080c, 0x7821, 0x014e, 0x015e, 0x0005,
+       0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0200,
+       0x20a3, 0x0000, 0x20a3, 0xdf10, 0x20a3, 0x0034, 0x2099, 0xad05,
+       0x20a9, 0x0004, 0x53a6, 0x2099, 0xad01, 0x20a9, 0x0004, 0x53a6,
+       0x2099, 0xafad, 0x20a9, 0x001a, 0x3304, 0x8007, 0x20a2, 0x9398,
+       0x1f04, 0x6e64, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x004c,
+       0x080c, 0x7821, 0x014e, 0x015e, 0x0005, 0x2001, 0xad14, 0x2004,
+       0x609a, 0x080c, 0x7821, 0x0005, 0x20a1, 0x020b, 0x080c, 0x710e,
+       0x20a3, 0x5200, 0x20a3, 0x0000, 0x00d6, 0x2069, 0xad51, 0x6804,
+       0xd084, 0x0150, 0x6828, 0x20a3, 0x0000, 0x0016, 0x080c, 0x268a,
+       0x21a2, 0x001e, 0x00de, 0x0028, 0x00de, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x20a9, 0x0004, 0x2099, 0xad05, 0x53a6, 0x20a9, 0x0004,
+       0x2099, 0xad01, 0x53a6, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x1138,
+       0x7818, 0xa080, 0x0028, 0x2004, 0xa082, 0x007f, 0x0238, 0x2001,
+       0xad1b, 0x20a6, 0x2001, 0xad1c, 0x20a6, 0x0040, 0x20a3, 0x0000,
+       0x2001, 0xad14, 0x2004, 0xa084, 0x00ff, 0x20a2, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x60c3, 0x001c, 0x080c, 0x7821, 0x0005, 0x20a1,
+       0x020b, 0x080c, 0x710e, 0x20a3, 0x0500, 0x20a3, 0x0000, 0x2001,
+       0xad34, 0x2004, 0xd0ac, 0x1138, 0x7818, 0xa080, 0x0028, 0x2004,
+       0xa082, 0x007f, 0x0238, 0x2001, 0xad1b, 0x20a6, 0x2001, 0xad1c,
+       0x20a6, 0x0040, 0x20a3, 0x0000, 0x2001, 0xad14, 0x2004, 0xa084,
+       0x00ff, 0x20a2, 0x20a9, 0x0004, 0x2099, 0xad05, 0x53a6, 0x60c3,
+       0x0010, 0x080c, 0x7821, 0x0005, 0x20a1, 0x020b, 0x080c, 0x710e,
+       0x00c6, 0x7818, 0x2060, 0x2001, 0x0000, 0x080c, 0x5037, 0x00ce,
+       0x7818, 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x1130, 0x20a3,
+       0x0400, 0x620c, 0xc2b4, 0x620e, 0x0010, 0x20a3, 0x0300, 0x20a3,
+       0x0000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x1904,
+       0x6f83, 0x2001, 0xad34, 0x2004, 0xd0a4, 0x01c8, 0x2099, 0xaf8d,
+       0x33a6, 0x9398, 0x20a3, 0x0000, 0x9398, 0x3304, 0xa084, 0x2000,
+       0x20a2, 0x9398, 0x33a6, 0x9398, 0x20a3, 0x0000, 0x9398, 0x2001,
+       0x2710, 0x20a2, 0x9398, 0x33a6, 0x9398, 0x33a6, 0x00d0, 0x2099,
+       0xaf8d, 0x33a6, 0x9398, 0x33a6, 0x9398, 0x3304, 0x080c, 0x574f,
+       0x1118, 0xa084, 0x37ff, 0x0010, 0xa084, 0x3fff, 0x20a2, 0x9398,
+       0x33a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x20a9, 0x0004, 0x2099, 0xad05, 0x53a6, 0x20a9, 0x0004,
+       0x2099, 0xad01, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04,
+       0x6f5d, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, 0x6f63, 0x2099,
+       0xaf95, 0x3304, 0xc0dd, 0x20a2, 0x2001, 0xad71, 0x2004, 0xd0e4,
+       0x0158, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x9398, 0x9398, 0x9398,
+       0x33a6, 0x20a9, 0x0004, 0x0010, 0x20a9, 0x0007, 0x20a3, 0x0000,
+       0x1f04, 0x6f7e, 0x0468, 0x2001, 0xad34, 0x2004, 0xd0a4, 0x0140,
+       0x2001, 0xaf8e, 0x2004, 0x60e3, 0x0000, 0x080c, 0x26cb, 0x60e2,
+       0x2099, 0xaf8d, 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0004, 0x2099,
+       0xad05, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xad01, 0x53a6, 0x20a9,
+       0x0008, 0x20a3, 0x0000, 0x1f04, 0x6fa1, 0x20a9, 0x0008, 0x20a3,
+       0x0000, 0x1f04, 0x6fa7, 0x2099, 0xaf95, 0x20a9, 0x0008, 0x53a6,
+       0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, 0x6fb2, 0x20a9, 0x000a,
+       0x20a3, 0x0000, 0x1f04, 0x6fb8, 0x60c3, 0x0074, 0x080c, 0x7821,
+       0x0005, 0x20a1, 0x020b, 0x080c, 0x710e, 0x20a3, 0x2010, 0x20a3,
+       0x0014, 0x20a3, 0x0800, 0x20a3, 0x2000, 0xa006, 0x20a2, 0x20a2,
+       0x20a2, 0x20a2, 0x20a2, 0x00f6, 0x2079, 0xad51, 0x7904, 0x00fe,
+       0xd1ac, 0x1110, 0xa085, 0x0020, 0xd1a4, 0x0110, 0xa085, 0x0010,
+       0xa085, 0x0002, 0x00d6, 0x0804, 0x7099, 0x20a2, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x7821, 0x0005, 0x20a1,
+       0x020b, 0x080c, 0x710e, 0x20a3, 0x5000, 0x0804, 0x6f0f, 0x20a1,
+       0x020b, 0x080c, 0x710e, 0x20a3, 0x2110, 0x20a3, 0x0014, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x7821, 0x0005,
+       0x20a1, 0x020b, 0x080c, 0x71a2, 0x0020, 0x20a1, 0x020b, 0x080c,
+       0x71aa, 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x60c3, 0x0004, 0x080c, 0x7821, 0x0005, 0x20a1, 0x020b,
+       0x080c, 0x71aa, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003,
+       0x20a3, 0x2a00, 0x60c3, 0x0008, 0x080c, 0x7821, 0x0005, 0x20a1,
+       0x020b, 0x080c, 0x71aa, 0x20a3, 0x0200, 0x0804, 0x6f0f, 0x20a1,
+       0x020b, 0x080c, 0x71aa, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828,
+       0xa005, 0x0110, 0x20a2, 0x0010, 0x20a3, 0x0003, 0x7810, 0x20a2,
+       0x60c3, 0x0008, 0x080c, 0x7821, 0x0005, 0x00d6, 0x20a1, 0x020b,
+       0x080c, 0x71aa, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, 0x0800,
+       0x7818, 0x2068, 0x6894, 0xa086, 0x0014, 0x1178, 0x6998, 0xa184,
+       0xc000, 0x1140, 0xd1ec, 0x0118, 0x20a3, 0x2100, 0x0040, 0x20a3,
+       0x0100, 0x0028, 0x20a3, 0x0400, 0x0010, 0x20a3, 0x0700, 0xa006,
+       0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x00f6, 0x2079, 0xad51,
+       0x7904, 0x00fe, 0xd1ac, 0x1110, 0xa085, 0x0020, 0xd1a4, 0x0110,
+       0xa085, 0x0010, 0x2009, 0xad73, 0x210c, 0xd184, 0x1110, 0xa085,
+       0x0002, 0x0026, 0x2009, 0xad71, 0x210c, 0xd1e4, 0x0130, 0xc0c5,
+       0xa094, 0x0030, 0xa296, 0x0010, 0x0140, 0xd1ec, 0x0130, 0xa094,
+       0x0030, 0xa296, 0x0010, 0x0108, 0xc0bd, 0x002e, 0x20a2, 0x20a2,
+       0x20a2, 0x60c3, 0x0014, 0x080c, 0x7821, 0x00de, 0x0005, 0x20a1,
+       0x020b, 0x080c, 0x71aa, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3,
+       0x0000, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x7821, 0x0005,
+       0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0200, 0x0804, 0x6e82,
+       0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0100, 0x20a3, 0x0000,
+       0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x080c, 0x7821,
+       0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a1, 0x020b, 0x080c,
+       0x71aa, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x000b, 0x20a3,
+       0x0000, 0x60c3, 0x0008, 0x080c, 0x7821, 0x0005, 0x0026, 0x0036,
+       0x0046, 0x2019, 0x3200, 0x2021, 0x0800, 0x0038, 0x0026, 0x0036,
+       0x0046, 0x2019, 0x2200, 0x2021, 0x0100, 0x20e1, 0x9080, 0x20e1,
+       0x4000, 0x7818, 0xa080, 0x0028, 0x2014, 0xa286, 0x007e, 0x11a0,
+       0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffe, 0x20a3, 0x0000, 0x2011,
+       0xad14, 0x2214, 0x2001, 0xaf9d, 0x2004, 0xa005, 0x0118, 0x2011,
+       0xad1c, 0x2214, 0x22a2, 0x04d0, 0xa286, 0x007f, 0x1138, 0x00d6,
+       0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffd, 0x00c8, 0x2001, 0xad34,
+       0x2004, 0xd0ac, 0x1110, 0xd2bc, 0x01c8, 0xa286, 0x0080, 0x00d6,
+       0x1130, 0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffc, 0x0040, 0xa2e8,
+       0xae34, 0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069,
+       0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0080, 0x00d6, 0xa2e8,
+       0xae34, 0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x00de,
+       0x20a3, 0x0000, 0x2011, 0xad14, 0x2214, 0x22a2, 0xa485, 0x0029,
+       0x20a2, 0x004e, 0x003e, 0x20a3, 0x0000, 0x080c, 0x7810, 0x22a2,
+       0x20a3, 0x0000, 0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x002e, 0x0005, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000,
+       0x20a3, 0x02ff, 0x2011, 0xfffc, 0x22a2, 0x00d6, 0x2069, 0xad1b,
+       0x2da6, 0x8d68, 0x2da6, 0x00de, 0x20a3, 0x2029, 0x20a3, 0x0000,
+       0x08e0, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3,
+       0x0000, 0x0005, 0x0026, 0x0036, 0x0046, 0x2019, 0x3300, 0x2021,
+       0x0800, 0x0038, 0x0026, 0x0036, 0x0046, 0x2019, 0x2300, 0x2021,
+       0x0100, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+       0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e,
+       0x02d8, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa305, 0x20a2,
+       0x6814, 0x20a2, 0x6810, 0xa005, 0x1140, 0x6814, 0xa005, 0x1128,
+       0x20a3, 0x00ff, 0x20a3, 0xfffe, 0x0028, 0x2069, 0xad1b, 0x2da6,
+       0x8d68, 0x2da6, 0x00de, 0x0080, 0x00d6, 0xa0e8, 0xae34, 0x2d6c,
+       0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000,
+       0x2011, 0xad14, 0x2214, 0x22a2, 0xa485, 0x0098, 0x20a2, 0x20a3,
+       0x0000, 0x004e, 0x003e, 0x080c, 0x7810, 0x22a2, 0x20a3, 0x0000,
+       0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e,
+       0x0005, 0x080c, 0x7810, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2,
+       0x7810, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005,
+       0x00c6, 0x00f6, 0x6004, 0xa08a, 0x0085, 0x0a0c, 0x14f6, 0xa08a,
+       0x008c, 0x1a0c, 0x14f6, 0x6118, 0x2178, 0x79a0, 0x2011, 0xad34,
+       0x2214, 0xd2ac, 0x1110, 0xd1bc, 0x0150, 0x7900, 0xd1f4, 0x0120,
+       0x7914, 0xa18c, 0x00ff, 0x0040, 0x2009, 0x0000, 0x0028, 0xa1f8,
+       0x2be6, 0x2f0d, 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a,
+       0xa082, 0x0085, 0x001b, 0x00fe, 0x00ce, 0x0005, 0x7247, 0x7251,
+       0x726c, 0x7245, 0x7245, 0x7245, 0x7247, 0x080c, 0x14f6, 0x0146,
+       0x20a1, 0x020b, 0x04a1, 0x60c3, 0x0000, 0x080c, 0x7821, 0x014e,
+       0x0005, 0x0146, 0x20a1, 0x020b, 0x080c, 0x72b8, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x7808, 0x20a2, 0x7810, 0x20a2, 0x20a3, 0x0000,
+       0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c,
+       0x080c, 0x7821, 0x014e, 0x0005, 0x0146, 0x20a1, 0x020b, 0x080c,
+       0x72f2, 0x20a3, 0x0003, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x60c3, 0x0004, 0x080c, 0x7821, 0x014e, 0x0005, 0x0026,
+       0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004,
+       0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x0288,
+       0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2,
+       0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de,
+       0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x8100,
+       0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14,
+       0x2214, 0x22a2, 0x20a3, 0x0009, 0x20a3, 0x0000, 0x0804, 0x7175,
+       0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+       0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e,
+       0x0288, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x8400,
+       0x20a2, 0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6,
+       0x00de, 0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085,
+       0x8400, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011,
+       0xad14, 0x2214, 0x22a2, 0x2001, 0x0099, 0x20a2, 0x20a3, 0x0000,
+       0x0804, 0x7201, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818,
+       0xa080, 0x0028, 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118,
+       0xa092, 0x007e, 0x0288, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810,
+       0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6,
+       0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c,
+       0x6810, 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3,
+       0x0000, 0x2011, 0xad14, 0x2214, 0x22a2, 0x2001, 0x0099, 0x20a2,
+       0x20a3, 0x0000, 0x0804, 0x7201, 0x00c6, 0x00f6, 0x2c78, 0x7804,
+       0xa08a, 0x0040, 0x0a0c, 0x14f6, 0xa08a, 0x0053, 0x1a0c, 0x14f6,
+       0x7918, 0x2160, 0x61a0, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110,
+       0xd1bc, 0x0150, 0x6100, 0xd1f4, 0x0120, 0x6114, 0xa18c, 0x00ff,
+       0x0040, 0x2009, 0x0000, 0x0028, 0xa1e0, 0x2be6, 0x2c0d, 0xa18c,
+       0x00ff, 0x2061, 0x0100, 0x619a, 0xa082, 0x0040, 0x001b, 0x00fe,
+       0x00ce, 0x0005, 0x736f, 0x747b, 0x7418, 0x761a, 0x736d, 0x736d,
+       0x736d, 0x736d, 0x736d, 0x736d, 0x736d, 0x7b41, 0x7b51, 0x7b61,
+       0x7b71, 0x736d, 0x7f79, 0x736d, 0x7b30, 0x080c, 0x14f6, 0x00d6,
+       0x0156, 0x0146, 0x780b, 0xffff, 0x20a1, 0x020b, 0x080c, 0x73cf,
+       0x7910, 0x2168, 0x6948, 0x7952, 0x21a2, 0xa016, 0x22a2, 0x22a2,
+       0x22a2, 0x694c, 0xa184, 0x000f, 0x1118, 0x2001, 0x0005, 0x0040,
+       0xd184, 0x0118, 0x2001, 0x0004, 0x0018, 0xa084, 0x0006, 0x8004,
+       0x0016, 0x2008, 0x7858, 0xa084, 0x00ff, 0x8007, 0xa105, 0x001e,
+       0x20a2, 0xd1ac, 0x0118, 0x20a3, 0x0002, 0x0048, 0xd1b4, 0x0118,
+       0x20a3, 0x0001, 0x0020, 0x20a3, 0x0000, 0x2230, 0x0010, 0x6a80,
+       0x6e7c, 0x20a9, 0x0008, 0x0136, 0xad88, 0x0017, 0x2198, 0x20a1,
+       0x021b, 0x53a6, 0x013e, 0x20a1, 0x020b, 0x22a2, 0x26a2, 0x60c3,
+       0x0020, 0x20e1, 0x9080, 0x6014, 0xa084, 0x0004, 0xa085, 0x0009,
+       0x6016, 0x2001, 0xafe3, 0x2003, 0x07d0, 0x2001, 0xafe2, 0x2003,
+       0x0009, 0x080c, 0x17bf, 0x014e, 0x015e, 0x00de, 0x0005, 0x20e1,
+       0x9080, 0x20e1, 0x4000, 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210,
+       0xa294, 0x00ff, 0x2202, 0x8217, 0x7818, 0xa080, 0x0028, 0x2004,
+       0x2019, 0xad34, 0x231c, 0xd3ac, 0x1110, 0xd0bc, 0x0188, 0x00d6,
+       0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2, 0x6814,
+       0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088,
+       0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2,
+       0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2009, 0xad14, 0x210c,
+       0x21a2, 0x20a3, 0x0829, 0x20a3, 0x0000, 0x22a2, 0x20a3, 0x0000,
+       0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x0005,
+       0x00d6, 0x0156, 0x0136, 0x0146, 0x20a1, 0x020b, 0x00c1, 0x7810,
+       0x2068, 0x6860, 0x20a2, 0x685c, 0x20a2, 0x6880, 0x20a2, 0x687c,
+       0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x000c,
+       0x080c, 0x7821, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0026,
+       0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004,
+       0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188, 0x00d6,
+       0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2, 0x6814,
+       0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088,
+       0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2,
+       0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14, 0x2214,
+       0x22a2, 0x20a3, 0x0889, 0x20a3, 0x0000, 0x080c, 0x7810, 0x22a2,
+       0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x002e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x7810,
+       0xa06d, 0x080c, 0x5025, 0x0148, 0x684c, 0xa084, 0x2020, 0xa086,
+       0x2020, 0x1118, 0x7820, 0xc0cd, 0x7822, 0x20a1, 0x020b, 0x080c,
+       0x75d0, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x7810,
+       0xa084, 0xf000, 0x1130, 0x7810, 0xa084, 0x0700, 0x8007, 0x0043,
+       0x0010, 0xa006, 0x002b, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005,
+       0x74b2, 0x7547, 0x7550, 0x7579, 0x758c, 0x75a7, 0x75b0, 0x74b0,
+       0x080c, 0x14f6, 0x0016, 0x0036, 0x694c, 0xa18c, 0x0003, 0x0118,
+       0xa186, 0x0003, 0x1170, 0x6b78, 0x7820, 0xd0cc, 0x0108, 0xc3e5,
+       0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x003e, 0x001e, 0x0804,
+       0x7583, 0xa186, 0x0001, 0x190c, 0x14f6, 0x6b78, 0x7820, 0xd0cc,
+       0x0108, 0xc3e5, 0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x22a2,
+       0x6874, 0x20a2, 0x22a2, 0x687c, 0x20a2, 0x2009, 0x0018, 0xa384,
+       0x0300, 0x0904, 0x7541, 0xd3c4, 0x0110, 0x687c, 0xa108, 0xd3cc,
+       0x0110, 0x6874, 0xa108, 0x0156, 0x20a9, 0x000d, 0xad80, 0x0020,
+       0x201c, 0x831f, 0x23a2, 0x8000, 0x1f04, 0x74f0, 0x015e, 0x22a2,
+       0x22a2, 0x22a2, 0xa184, 0x0003, 0x0904, 0x7541, 0x20a1, 0x020b,
+       0x20e1, 0x9080, 0x20e1, 0x4000, 0x0006, 0x7818, 0xa080, 0x0028,
+       0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188,
+       0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2,
+       0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de,
+       0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0700,
+       0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14,
+       0x2214, 0x22a2, 0x000e, 0x7b20, 0xd3cc, 0x0118, 0x20a3, 0x0889,
+       0x0010, 0x20a3, 0x0898, 0x20a2, 0x080c, 0x7810, 0x22a2, 0x20a3,
+       0x0000, 0x61c2, 0x003e, 0x001e, 0x080c, 0x7821, 0x0005, 0x2011,
+       0x0008, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0xa016, 0x0488,
+       0x2011, 0x0302, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0xa016,
+       0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x0012, 0x22a2, 0x20a3, 0x0008,
+       0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x7000, 0x20a3, 0x0500,
+       0x22a2, 0x20a3, 0x000a, 0x22a2, 0x22a2, 0x20a3, 0x2500, 0x22a2,
+       0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0032, 0x080c, 0x7821,
+       0x0005, 0x2011, 0x0028, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2,
+       0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3,
+       0x0018, 0x080c, 0x7821, 0x0005, 0x2011, 0x0100, 0x7820, 0xd0cc,
+       0x0108, 0xc2e5, 0x22a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2,
+       0x22a2, 0x20a3, 0x0008, 0x22a2, 0x7854, 0xa084, 0x00ff, 0x20a2,
+       0x22a2, 0x22a2, 0x60c3, 0x0020, 0x080c, 0x7821, 0x0005, 0x2011,
+       0x0008, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0xa016, 0x0888,
+       0x0036, 0x7b10, 0xa384, 0xff00, 0x7812, 0xa384, 0x00ff, 0x8001,
+       0x1138, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0x003e, 0x0808,
+       0x0046, 0x2021, 0x0800, 0x0006, 0x7820, 0xd0cc, 0x000e, 0x0108,
+       0xc4e5, 0x24a2, 0x004e, 0x22a2, 0x20a2, 0x003e, 0x0804, 0x7583,
+       0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+       0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188,
+       0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2,
+       0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de,
+       0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0700,
+       0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14,
+       0x2214, 0x22a2, 0x7820, 0xd0cc, 0x0118, 0x20a3, 0x0889, 0x0010,
+       0x20a3, 0x0898, 0x20a3, 0x0000, 0x080c, 0x7810, 0x22a2, 0x20a3,
+       0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000,
+       0x002e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x0016, 0x0036,
+       0x7810, 0xa084, 0x0700, 0x8007, 0x003b, 0x003e, 0x001e, 0x014e,
+       0x013e, 0x015e, 0x00de, 0x0005, 0x7634, 0x7634, 0x7636, 0x7634,
+       0x7634, 0x7634, 0x7658, 0x7634, 0x080c, 0x14f6, 0x7910, 0xa18c,
+       0xf8ff, 0xa18d, 0x0600, 0x7912, 0x20a1, 0x020b, 0x2009, 0x0003,
+       0x00f9, 0x00d6, 0x2069, 0xad51, 0x6804, 0xd0bc, 0x0130, 0x682c,
+       0xa084, 0x00ff, 0x8007, 0x20a2, 0x0010, 0x20a3, 0x3f00, 0x00de,
+       0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0001, 0x080c, 0x7821, 0x0005,
+       0x20a1, 0x020b, 0x2009, 0x0003, 0x0019, 0x20a3, 0x7f00, 0x0c80,
+       0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+       0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188,
+       0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0100, 0x20a2,
+       0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de,
+       0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0100,
+       0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14,
+       0x2214, 0x22a2, 0x20a3, 0x0888, 0xa18d, 0x0008, 0x21a2, 0x080c,
+       0x7810, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, 0x00e6, 0x00d6, 0x00c6,
+       0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0xad00, 0x7150,
+       0x7818, 0x2068, 0x68a0, 0x2028, 0x76d0, 0xd6ac, 0x1130, 0xd0bc,
+       0x1120, 0x6910, 0x6a14, 0x7450, 0x0020, 0x6910, 0x6a14, 0x736c,
+       0x7470, 0x781c, 0xa0be, 0x0006, 0x0904, 0x775b, 0xa0be, 0x000a,
+       0x15e8, 0xa185, 0x0200, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073,
+       0x2029, 0x6077, 0x0000, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e,
+       0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086,
+       0x7810, 0x2070, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6,
+       0x7008, 0x60ca, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000,
+       0x609f, 0x0000, 0x080c, 0x8014, 0x2009, 0x07d0, 0x60c4, 0xa084,
+       0xfff0, 0xa005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x6586, 0x003e,
+       0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x70d0, 0xd0ac,
+       0x1110, 0xd5bc, 0x0138, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a,
+       0x646e, 0x0038, 0xa185, 0x0100, 0x6062, 0x6266, 0x606b, 0x0000,
+       0x646e, 0x6073, 0x0809, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084,
+       0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082,
+       0x7808, 0x6086, 0x7810, 0x2070, 0x7014, 0x608a, 0x7010, 0x608e,
+       0x700c, 0x60c6, 0x7008, 0x60ca, 0x686c, 0x60ce, 0x60af, 0x95d5,
+       0x60d7, 0x0000, 0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120,
+       0x6a14, 0xa294, 0x00ff, 0x0010, 0x2011, 0x0000, 0x629e, 0x080c,
+       0x8014, 0x2009, 0x07d0, 0x60c4, 0xa084, 0xfff0, 0xa005, 0x0110,
+       0x2009, 0x1b58, 0x080c, 0x6586, 0x003e, 0x004e, 0x005e, 0x00ce,
+       0x00de, 0x00ee, 0x0005, 0x7810, 0x2070, 0x704c, 0xa084, 0x0003,
+       0xa086, 0x0002, 0x0904, 0x77b1, 0x2001, 0xad34, 0x2004, 0xd0ac,
+       0x1110, 0xd5bc, 0x0138, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a,
+       0x646e, 0x0038, 0xa185, 0x0100, 0x6062, 0x6266, 0x606b, 0x0000,
+       0x646e, 0x6073, 0x0880, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084,
+       0x00ff, 0x688e, 0x8007, 0x607a, 0x7834, 0x607e, 0x2f00, 0x6086,
+       0x7808, 0x6082, 0x7060, 0x608a, 0x705c, 0x608e, 0x7080, 0x60c6,
+       0x707c, 0x60ca, 0x707c, 0x792c, 0xa108, 0x792e, 0x7080, 0x7928,
+       0xa109, 0x792a, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000,
+       0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120, 0x6a14, 0xa294,
+       0x00ff, 0x0010, 0x2011, 0x0000, 0x629e, 0x080c, 0x8011, 0x0804,
+       0x7749, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x1110, 0xd5bc, 0x0138,
+       0xa185, 0x0700, 0x6062, 0x6266, 0x636a, 0x646e, 0x0038, 0xa185,
+       0x0700, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, 0x080c, 0x5025,
+       0x0180, 0x00d6, 0x7810, 0xa06d, 0x684c, 0x00de, 0xa084, 0x2020,
+       0xa086, 0x2020, 0x1130, 0x7820, 0xc0cd, 0x7822, 0x6073, 0x0889,
+       0x0010, 0x6073, 0x0898, 0x6077, 0x0000, 0x688c, 0x8000, 0xa084,
+       0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086,
+       0x7808, 0x6082, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6,
+       0x7008, 0x60ca, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000,
+       0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120, 0x6a14, 0xa294,
+       0x00ff, 0x0010, 0x2011, 0x0000, 0x629e, 0x7820, 0xd0cc, 0x0120,
+       0x080c, 0x8014, 0x0804, 0x7749, 0x080c, 0x8011, 0x0804, 0x7749,
+       0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202,
+       0x8217, 0x0005, 0x00d6, 0x2069, 0xafc7, 0x6843, 0x0001, 0x00de,
+       0x0005, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x0019,
+       0x080c, 0x6578, 0x0005, 0x0006, 0x6014, 0xa084, 0x0004, 0xa085,
+       0x0009, 0x6016, 0x000e, 0x0005, 0x0006, 0x00c6, 0x2061, 0x0100,
+       0x6014, 0xa084, 0x0004, 0xa085, 0x0008, 0x6016, 0x00ce, 0x000e,
+       0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061, 0x0100, 0x2069,
+       0x0140, 0x080c, 0x574f, 0x1178, 0x2001, 0xafe3, 0x2004, 0xa005,
+       0x1598, 0x080c, 0x57d1, 0x1118, 0x080c, 0x6578, 0x0468, 0x00c6,
+       0x2061, 0xafc7, 0x00d8, 0x6904, 0xa194, 0x4000, 0x0550, 0x08a1,
+       0x6803, 0x1000, 0x6803, 0x0000, 0x00c6, 0x2061, 0xafc7, 0x6128,
+       0xa192, 0x00c8, 0x1258, 0x8108, 0x612a, 0x6124, 0x00ce, 0x81ff,
+       0x0198, 0x080c, 0x6578, 0x080c, 0x782b, 0x0070, 0x6124, 0xa1e5,
+       0x0000, 0x0140, 0x080c, 0xaca2, 0x2009, 0x0014, 0x080c, 0x80a7,
+       0x080c, 0x6581, 0x00ce, 0x0000, 0x002e, 0x001e, 0x00de, 0x00ce,
+       0x0005, 0x2001, 0xafe3, 0x2004, 0xa005, 0x1db0, 0x00c6, 0x2061,
+       0xafc7, 0x6128, 0xa192, 0x0003, 0x1e08, 0x8108, 0x612a, 0x00ce,
+       0x080c, 0x6578, 0x080c, 0x485e, 0x0c38, 0x00c6, 0x00d6, 0x00e6,
+       0x0016, 0x0026, 0x080c, 0x658e, 0x2071, 0xafc7, 0x713c, 0x81ff,
+       0x0570, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x574f, 0x1188,
+       0x0036, 0x2019, 0x0001, 0x080c, 0x7a64, 0x003e, 0x713c, 0x2160,
+       0x080c, 0xaca2, 0x2009, 0x004a, 0x080c, 0x80a7, 0x080c, 0x57d1,
+       0x00b0, 0x6904, 0xa194, 0x4000, 0x01c0, 0x6803, 0x1000, 0x6803,
+       0x0000, 0x0036, 0x2019, 0x0001, 0x080c, 0x7a64, 0x003e, 0x713c,
+       0x2160, 0x080c, 0xaca2, 0x2009, 0x004a, 0x080c, 0x80a7, 0x002e,
+       0x001e, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0c58, 0x00e6, 0x00d6,
+       0x00c6, 0x0066, 0x0056, 0x0046, 0x0006, 0x0126, 0x2091, 0x8000,
+       0x6018, 0x2068, 0x6ca0, 0x2071, 0xafc7, 0x7018, 0x2068, 0x8dff,
+       0x0198, 0x68a0, 0xa406, 0x0118, 0x6854, 0x2068, 0x0cc0, 0x6010,
+       0x2060, 0x643c, 0x6540, 0x6e48, 0x2d60, 0x080c, 0x4e41, 0x0120,
+       0x080c, 0x7b88, 0xa085, 0x0001, 0x012e, 0x000e, 0x004e, 0x005e,
+       0x006e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x20a1, 0x020b, 0x080c,
+       0x710e, 0x20a3, 0x1200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x781c,
+       0xa086, 0x0004, 0x1110, 0x6098, 0x0018, 0x2001, 0xad14, 0x2004,
+       0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a9, 0x0010, 0xa006,
+       0x20a2, 0x1f04, 0x7928, 0x20a2, 0x20a2, 0x60c3, 0x002c, 0x080c,
+       0x7821, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x710e,
+       0x20a3, 0x0f00, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2,
+       0x60c3, 0x0008, 0x080c, 0x7821, 0x014e, 0x015e, 0x0005, 0x0156,
+       0x0146, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0200, 0x20a3,
+       0x0000, 0x20a9, 0x0006, 0x2011, 0xad40, 0x2019, 0xad41, 0x23a6,
+       0x22a6, 0xa398, 0x0002, 0xa290, 0x0002, 0x1f04, 0x7957, 0x20a3,
+       0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x080c, 0x7821, 0x014e,
+       0x015e, 0x0005, 0x0156, 0x0146, 0x0016, 0x0026, 0x20a1, 0x020b,
+       0x080c, 0x7183, 0x080c, 0x7199, 0x7810, 0xa080, 0x0000, 0x2004,
+       0xa080, 0x0015, 0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6,
+       0xa080, 0x0004, 0x8003, 0x60c2, 0x080c, 0x7821, 0x002e, 0x001e,
+       0x014e, 0x015e, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c,
+       0x710e, 0x20a3, 0x6200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808,
+       0x20a2, 0x60c3, 0x0008, 0x080c, 0x7821, 0x014e, 0x015e, 0x0005,
+       0x0156, 0x0146, 0x0016, 0x0026, 0x20a1, 0x020b, 0x080c, 0x710e,
+       0x7810, 0xa080, 0x0000, 0x2004, 0xa080, 0x0017, 0x2098, 0x7808,
+       0xa088, 0x0002, 0x21a8, 0x53a6, 0x8003, 0x60c2, 0x080c, 0x7821,
+       0x002e, 0x001e, 0x014e, 0x015e, 0x0005, 0x00e6, 0x00c6, 0x0006,
+       0x0126, 0x2091, 0x8000, 0x2071, 0xafc7, 0x700c, 0x2060, 0x8cff,
+       0x0178, 0x080c, 0x9789, 0x1110, 0x080c, 0x85f3, 0x600c, 0x0006,
+       0x080c, 0x994e, 0x080c, 0x8078, 0x080c, 0x7b88, 0x00ce, 0x0c78,
+       0x700f, 0x0000, 0x700b, 0x0000, 0x012e, 0x000e, 0x00ce, 0x00ee,
+       0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0026,
+       0x0016, 0x0006, 0x2091, 0x8000, 0x2069, 0x0100, 0x2079, 0x0140,
+       0x2071, 0xafc7, 0x7024, 0x2060, 0x8cff, 0x05a0, 0x080c, 0x7834,
+       0x68c3, 0x0000, 0x080c, 0x6581, 0x2009, 0x0013, 0x080c, 0x80a7,
+       0x20a9, 0x01f4, 0x6824, 0xd094, 0x0158, 0x6827, 0x0004, 0x7804,
+       0xa084, 0x4000, 0x01a0, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078,
+       0xd084, 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04, 0x7a02, 0x7804,
+       0xa084, 0x1000, 0x0120, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824,
+       0x000e, 0x001e, 0x002e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e,
+       0x012e, 0x0005, 0x2001, 0xad00, 0x2004, 0xa096, 0x0001, 0x0550,
+       0xa096, 0x0004, 0x0538, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011,
+       0x481b, 0x080c, 0x650d, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0158,
+       0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x01a0, 0x7803, 0x1000,
+       0x7803, 0x0000, 0x0078, 0xd084, 0x0118, 0x6827, 0x0001, 0x0010,
+       0x1f04, 0x7a3d, 0x7804, 0xa084, 0x1000, 0x0120, 0x7803, 0x0100,
+       0x7803, 0x0000, 0x000e, 0x001e, 0x002e, 0x00ce, 0x00de, 0x00ee,
+       0x00fe, 0x015e, 0x012e, 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6,
+       0x00d6, 0x00c6, 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2069,
+       0x0100, 0x2079, 0x0140, 0x2071, 0xafc7, 0x703c, 0x2060, 0x8cff,
+       0x0904, 0x7ad5, 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x1df0,
+       0x68c7, 0x0000, 0x68cb, 0x0008, 0x080c, 0x658e, 0x080c, 0x20b5,
+       0x0046, 0x2009, 0x017f, 0x200b, 0x00a5, 0x2021, 0x0169, 0x2404,
+       0xa084, 0x000f, 0xa086, 0x0004, 0x11b0, 0x68c7, 0x0000, 0x68cb,
+       0x0008, 0x00e6, 0x00f6, 0x2079, 0x0020, 0x2071, 0xb01e, 0x6814,
+       0xa084, 0x0184, 0xa085, 0x0012, 0x6816, 0x7803, 0x0008, 0x7003,
+       0x0000, 0x00fe, 0x00ee, 0x200b, 0x0000, 0x004e, 0xa39d, 0x0000,
+       0x1120, 0x2009, 0x0049, 0x080c, 0x80a7, 0x20a9, 0x03e8, 0x6824,
+       0xd094, 0x0158, 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x01a0,
+       0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0xd08c, 0x0118, 0x6827,
+       0x0002, 0x0010, 0x1f04, 0x7ab7, 0x7804, 0xa084, 0x1000, 0x0120,
+       0x7803, 0x0100, 0x7803, 0x0000, 0x6824, 0x000e, 0x001e, 0x002e,
+       0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6,
+       0x0126, 0x2091, 0x8000, 0x2069, 0xafc7, 0x6a06, 0x012e, 0x00de,
+       0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, 0xafc7, 0x6a32,
+       0x012e, 0x00de, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0006,
+       0x0126, 0x2071, 0xafc7, 0x7614, 0x2660, 0x2678, 0x2091, 0x8000,
+       0x8cff, 0x0538, 0x601c, 0xa206, 0x1500, 0x7014, 0xac36, 0x1110,
+       0x660c, 0x7616, 0x7010, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118,
+       0x2f00, 0x7012, 0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00,
+       0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c,
+       0x974e, 0x080c, 0x7b88, 0x00ce, 0x08d8, 0x2c78, 0x600c, 0x2060,
+       0x08b8, 0x012e, 0x000e, 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005,
+       0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810, 0x20a2,
+       0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x1000, 0x0804,
+       0x7b80, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810,
+       0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x4000,
+       0x0478, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810,
+       0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x2000,
+       0x00f8, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810,
+       0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0400,
+       0x0078, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810,
+       0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200,
+       0x0089, 0x60c3, 0x0020, 0x080c, 0x7821, 0x014e, 0x015e, 0x0005,
+       0x00e6, 0x2071, 0xafc7, 0x7020, 0xa005, 0x0110, 0x8001, 0x7022,
+       0x00ee, 0x0005, 0x20a9, 0x0008, 0x20a2, 0x1f04, 0x7b94, 0x20a2,
+       0x20a2, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066,
+       0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0xafc7, 0x7614, 0x2660,
+       0x2678, 0x2039, 0x0001, 0x87ff, 0x0904, 0x7c24, 0x8cff, 0x0904,
+       0x7c24, 0x601c, 0xa086, 0x0006, 0x1904, 0x7c1f, 0x88ff, 0x0138,
+       0x2800, 0xac06, 0x1904, 0x7c1f, 0x2039, 0x0000, 0x0050, 0x6018,
+       0xa206, 0x1904, 0x7c1f, 0x85ff, 0x0120, 0x6050, 0xa106, 0x1904,
+       0x7c1f, 0x7024, 0xac06, 0x1538, 0x2069, 0x0100, 0x68c0, 0xa005,
+       0x01f0, 0x080c, 0x6581, 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c,
+       0x7ca8, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384,
+       0x1000, 0x0120, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100,
+       0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0020, 0x6003,
+       0x0009, 0x630a, 0x0460, 0x7014, 0xac36, 0x1110, 0x660c, 0x7616,
+       0x7010, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7012,
+       0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110,
+       0x7e0e, 0x0008, 0x2678, 0x89ff, 0x1158, 0x600f, 0x0000, 0x6010,
+       0x2068, 0x080c, 0x9596, 0x0110, 0x080c, 0xa91f, 0x080c, 0x974e,
+       0x080c, 0x7b88, 0x88ff, 0x1190, 0x00ce, 0x0804, 0x7bab, 0x2c78,
+       0x600c, 0x2060, 0x0804, 0x7bab, 0xa006, 0x012e, 0x000e, 0x006e,
+       0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6017, 0x0000,
+       0x00ce, 0xa8c5, 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6, 0x00c6,
+       0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0xafc7,
+       0x7638, 0x2660, 0x2678, 0x8cff, 0x0904, 0x7c98, 0x601c, 0xa086,
+       0x0006, 0x1904, 0x7c93, 0x87ff, 0x0128, 0x2700, 0xac06, 0x1904,
+       0x7c93, 0x0040, 0x6018, 0xa206, 0x15f0, 0x85ff, 0x0118, 0x6050,
+       0xa106, 0x15c8, 0x703c, 0xac06, 0x1170, 0x0036, 0x2019, 0x0001,
+       0x080c, 0x7a64, 0x7033, 0x0000, 0x703f, 0x0000, 0x7043, 0x0000,
+       0x7047, 0x0000, 0x003e, 0x7038, 0xac36, 0x1110, 0x660c, 0x763a,
+       0x7034, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7036,
+       0x0010, 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110,
+       0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x080c,
+       0x9596, 0x0110, 0x080c, 0xa91f, 0x080c, 0x974e, 0x87ff, 0x1190,
+       0x00ce, 0x0804, 0x7c43, 0x2c78, 0x600c, 0x2060, 0x0804, 0x7c43,
+       0xa006, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee,
+       0x00fe, 0x0005, 0x6017, 0x0000, 0x00ce, 0xa7bd, 0x0001, 0x0c88,
+       0x00e6, 0x2071, 0xafc7, 0x2001, 0xad00, 0x2004, 0xa086, 0x0002,
+       0x1118, 0x7007, 0x0005, 0x0010, 0x7007, 0x0000, 0x00ee, 0x0005,
+       0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091,
+       0x8000, 0x2071, 0xafc7, 0x2c10, 0x7638, 0x2660, 0x2678, 0x8cff,
+       0x0518, 0x2200, 0xac06, 0x11e0, 0x7038, 0xac36, 0x1110, 0x660c,
+       0x763a, 0x7034, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00,
+       0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x2c00, 0xaf06, 0x0110,
+       0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0xa085, 0x0001, 0x0020,
+       0x2c78, 0x600c, 0x2060, 0x08d8, 0x012e, 0x000e, 0x002e, 0x006e,
+       0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6,
+       0x0066, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0xafc7, 0x760c,
+       0x2660, 0x2678, 0x8cff, 0x0904, 0x7d7e, 0x6018, 0xa080, 0x0028,
+       0x2004, 0xa206, 0x1904, 0x7d79, 0x7024, 0xac06, 0x1508, 0x2069,
+       0x0100, 0x68c0, 0xa005, 0x0904, 0x7d55, 0x080c, 0x7834, 0x68c3,
+       0x0000, 0x080c, 0x7ca8, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140,
+       0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, 0x0000,
+       0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e,
+       0x700c, 0xac36, 0x1110, 0x660c, 0x760e, 0x7008, 0xac36, 0x1140,
+       0x2c00, 0xaf36, 0x0118, 0x2f00, 0x700a, 0x0010, 0x700b, 0x0000,
+       0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678,
+       0x600f, 0x0000, 0x080c, 0x9778, 0x1158, 0x080c, 0x2aff, 0x080c,
+       0x9789, 0x11f0, 0x080c, 0x85f3, 0x00d8, 0x080c, 0x7ca8, 0x08c0,
+       0x080c, 0x9789, 0x1118, 0x080c, 0x85f3, 0x0090, 0x6010, 0x2068,
+       0x080c, 0x9596, 0x0168, 0x601c, 0xa086, 0x0003, 0x11f8, 0x6837,
+       0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x510c, 0x080c, 0x9742,
+       0x080c, 0x994e, 0x080c, 0x974e, 0x080c, 0x7b88, 0x00ce, 0x0804,
+       0x7d02, 0x2c78, 0x600c, 0x2060, 0x0804, 0x7d02, 0x012e, 0x000e,
+       0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086,
+       0x0006, 0x1d30, 0x080c, 0xa91f, 0x0c18, 0x0036, 0x0156, 0x0136,
+       0x0146, 0x3908, 0xa006, 0xa190, 0x0020, 0x221c, 0xa39e, 0x28f9,
+       0x1118, 0x8210, 0x8000, 0x0cc8, 0xa005, 0x0138, 0x20a9, 0x0020,
+       0x2198, 0xa110, 0x22a0, 0x22c8, 0x53a3, 0x014e, 0x013e, 0x015e,
+       0x003e, 0x0005, 0x00d6, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3,
+       0x0200, 0x20a3, 0x0014, 0x60c3, 0x0014, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x2099, 0xafa6, 0x20a9, 0x0004, 0x53a6, 0x20a3, 0x0004,
+       0x20a3, 0x7878, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x080c, 0x7821,
+       0x00de, 0x0005, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0214,
+       0x20a3, 0x0018, 0x20a3, 0x0800, 0x7810, 0xa084, 0xff00, 0x20a2,
+       0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
+       0x7810, 0xa084, 0x00ff, 0x20a2, 0x7828, 0x20a2, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x60c3, 0x0018, 0x080c, 0x7821, 0x0005, 0x00d6,
+       0x0016, 0x2f68, 0x2009, 0x0035, 0x080c, 0x9a34, 0x1904, 0x7e5d,
+       0x20a1, 0x020b, 0x080c, 0x710e, 0x20a3, 0x1300, 0x20a3, 0x0000,
+       0x7828, 0x2068, 0x681c, 0xa086, 0x0003, 0x0580, 0x7818, 0xa080,
+       0x0028, 0x2014, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x11d0, 0xa286,
+       0x007e, 0x1128, 0x20a3, 0x00ff, 0x20a3, 0xfffe, 0x04b8, 0xa286,
+       0x007f, 0x1128, 0x20a3, 0x00ff, 0x20a3, 0xfffd, 0x0478, 0xd2bc,
+       0x0180, 0xa286, 0x0080, 0x1128, 0x20a3, 0x00ff, 0x20a3, 0xfffc,
+       0x0428, 0xa2e8, 0xae34, 0x2d6c, 0x6810, 0x20a2, 0x6814, 0x20a2,
+       0x00e8, 0x20a3, 0x0000, 0x6098, 0x20a2, 0x00c0, 0x2001, 0xad34,
+       0x2004, 0xd0ac, 0x1138, 0x7818, 0xa080, 0x0028, 0x2004, 0xa082,
+       0x007e, 0x0240, 0x00d6, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6,
+       0x00de, 0x0020, 0x20a3, 0x0000, 0x6034, 0x20a2, 0x7834, 0x20a2,
+       0x7838, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c,
+       0x080c, 0x7821, 0x001e, 0x00de, 0x0005, 0x7817, 0x0001, 0x7803,
+       0x0006, 0x001e, 0x00de, 0x0005, 0x00d6, 0x0026, 0x7928, 0x2168,
+       0x691c, 0xa186, 0x0006, 0x01c0, 0xa186, 0x0003, 0x0904, 0x7ed3,
+       0xa186, 0x0005, 0x0904, 0x7ebc, 0xa186, 0x0004, 0x05b8, 0xa186,
+       0x0008, 0x0904, 0x7ec4, 0x7807, 0x0037, 0x7813, 0x1700, 0x080c,
+       0x7f3b, 0x002e, 0x00de, 0x0005, 0x080c, 0x7ef7, 0x2009, 0x4000,
+       0x6800, 0x0002, 0x7e9d, 0x7ea8, 0x7e9f, 0x7ea8, 0x7ea4, 0x7e9d,
+       0x7e9d, 0x7ea8, 0x7ea8, 0x7ea8, 0x7ea8, 0x7e9d, 0x7e9d, 0x7e9d,
+       0x7e9d, 0x7e9d, 0x7ea8, 0x7e9d, 0x7ea8, 0x080c, 0x14f6, 0x6820,
+       0xd0e4, 0x0110, 0xd0cc, 0x0110, 0xa00e, 0x0010, 0x2009, 0x2000,
+       0x6828, 0x20a2, 0x682c, 0x20a2, 0x0804, 0x7eed, 0x080c, 0x7ef7,
+       0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000, 0x6a00, 0xa286,
+       0x0002, 0x1108, 0xa00e, 0x0488, 0x04d1, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x2009, 0x4000, 0x0448, 0x0491, 0x20a3, 0x0000, 0x20a3,
+       0x0000, 0x2009, 0x4000, 0xa286, 0x0005, 0x0118, 0xa286, 0x0002,
+       0x1108, 0xa00e, 0x00d0, 0x0419, 0x6810, 0x2068, 0x697c, 0x6810,
+       0xa112, 0x6980, 0x6814, 0xa103, 0x20a2, 0x22a2, 0x7928, 0xa180,
+       0x0000, 0x2004, 0xa08e, 0x0002, 0x0130, 0xa08e, 0x0004, 0x0118,
+       0x2009, 0x4000, 0x0010, 0x2009, 0x0000, 0x21a2, 0x20a3, 0x0000,
+       0x60c3, 0x0018, 0x080c, 0x7821, 0x002e, 0x00de, 0x0005, 0x0036,
+       0x0046, 0x0056, 0x0066, 0x20a1, 0x020b, 0x080c, 0x71aa, 0xa006,
+       0x20a3, 0x0200, 0x20a2, 0x7934, 0x21a2, 0x7938, 0x21a2, 0x7818,
+       0xa080, 0x0028, 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118,
+       0xa092, 0x007e, 0x0268, 0x00d6, 0x2069, 0xad1b, 0x2d2c, 0x8d68,
+       0x2d34, 0xa0e8, 0xae34, 0x2d6c, 0x6b10, 0x6c14, 0x00de, 0x0030,
+       0x2019, 0x0000, 0x6498, 0x2029, 0x0000, 0x6634, 0x7828, 0xa080,
+       0x0007, 0x2004, 0xa086, 0x0003, 0x1128, 0x25a2, 0x26a2, 0x23a2,
+       0x24a2, 0x0020, 0x23a2, 0x24a2, 0x25a2, 0x26a2, 0x006e, 0x005e,
+       0x004e, 0x003e, 0x0005, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3,
+       0x0100, 0x20a3, 0x0000, 0x20a3, 0x0009, 0x7810, 0x20a2, 0x60c3,
+       0x0008, 0x080c, 0x7821, 0x0005, 0x20a1, 0x020b, 0x080c, 0x7106,
+       0x20a3, 0x1400, 0x20a3, 0x0000, 0x7834, 0x20a2, 0x7838, 0x20a2,
+       0x7828, 0x20a2, 0x782c, 0x20a2, 0x7830, 0xa084, 0x00ff, 0x8007,
+       0x20a2, 0x20a3, 0x0000, 0x60c3, 0x0010, 0x080c, 0x7821, 0x0005,
+       0x20a1, 0x020b, 0x080c, 0x71a2, 0x20a3, 0x0100, 0x20a3, 0x0000,
+       0x7828, 0x20a2, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x080c, 0x7821,
+       0x0005, 0x0146, 0x20a1, 0x020b, 0x0031, 0x60c3, 0x0000, 0x080c,
+       0x7821, 0x014e, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818,
+       0xa080, 0x0028, 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110,
+       0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085,
+       0x0300, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68,
+       0x2da6, 0x00de, 0x0078, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810,
+       0xa085, 0x0300, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000,
+       0x6234, 0x22a2, 0x20a3, 0x0819, 0x20a3, 0x0000, 0x080c, 0x7810,
+       0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x7a08, 0x22a2, 0x20a3, 0x0000,
+       0x20a3, 0x0000, 0x0005, 0x20a1, 0x020b, 0x0079, 0x7910, 0x21a2,
+       0x20a3, 0x0000, 0x60c3, 0x0000, 0x20e1, 0x9080, 0x60a7, 0x9575,
+       0x080c, 0x782b, 0x080c, 0x6578, 0x0005, 0x0156, 0x0136, 0x0036,
+       0x00d6, 0x00e6, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7854, 0x2068,
+       0xadf0, 0x000f, 0x7210, 0xa296, 0x00c0, 0xa294, 0xfffd, 0x7212,
+       0x7214, 0xa294, 0x0300, 0x7216, 0x7100, 0xa194, 0x00ff, 0x7308,
+       0xa384, 0x00ff, 0xa08d, 0xc200, 0x7102, 0xa384, 0xff00, 0xa215,
+       0x720a, 0x7004, 0x720c, 0x700e, 0x7206, 0x20a9, 0x000a, 0x2e98,
+       0x53a6, 0x60a3, 0x0035, 0x6a38, 0xa294, 0x7000, 0xa286, 0x3000,
+       0x0110, 0x60a3, 0x0037, 0x00ee, 0x00de, 0x003e, 0x013e, 0x015e,
+       0x0005, 0x2009, 0x0092, 0x0010, 0x2009, 0x0096, 0x60ab, 0x0036,
+       0x6116, 0x0005, 0x2061, 0xb400, 0x2a70, 0x7064, 0x7046, 0x704b,
+       0xb400, 0x0005, 0x00e6, 0x0126, 0x2071, 0xad00, 0x2091, 0x8000,
+       0x7544, 0xa582, 0x0010, 0x0608, 0x7048, 0x2060, 0x6000, 0xa086,
+       0x0000, 0x0148, 0xace0, 0x0018, 0x7058, 0xac02, 0x1208, 0x0cb0,
+       0x2061, 0xb400, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7546, 0xaca8,
+       0x0018, 0x7058, 0xa502, 0x1230, 0x754a, 0xa085, 0x0001, 0x012e,
+       0x00ee, 0x0005, 0x704b, 0xb400, 0x0cc0, 0xa006, 0x0cc0, 0x00e6,
+       0x2071, 0xad00, 0x7544, 0xa582, 0x0010, 0x0600, 0x7048, 0x2060,
+       0x6000, 0xa086, 0x0000, 0x0148, 0xace0, 0x0018, 0x7058, 0xac02,
+       0x1208, 0x0cb0, 0x2061, 0xb400, 0x0c98, 0x6003, 0x0008, 0x8529,
+       0x7546, 0xaca8, 0x0018, 0x7058, 0xa502, 0x1228, 0x754a, 0xa085,
+       0x0001, 0x00ee, 0x0005, 0x704b, 0xb400, 0x0cc8, 0xa006, 0x0cc8,
+       0xac82, 0xb400, 0x0a0c, 0x14f6, 0x2001, 0xad16, 0x2004, 0xac02,
+       0x1a0c, 0x14f6, 0xa006, 0x6006, 0x600a, 0x600e, 0x6012, 0x6016,
+       0x601a, 0x601f, 0x0000, 0x6003, 0x0000, 0x6052, 0x6056, 0x6022,
+       0x6026, 0x602a, 0x602e, 0x6032, 0x6036, 0x603a, 0x603e, 0x2061,
+       0xad00, 0x6044, 0x8000, 0x6046, 0xa086, 0x0001, 0x0108, 0x0005,
+       0x0126, 0x2091, 0x8000, 0x080c, 0x6c50, 0x012e, 0x0cc0, 0x601c,
+       0xa084, 0x000f, 0x0002, 0x80b6, 0x80c5, 0x80e0, 0x80fb, 0x9a61,
+       0x9a7c, 0x9a97, 0x80b6, 0x80c5, 0x80b6, 0x8116, 0xa186, 0x0013,
+       0x1128, 0x080c, 0x6b73, 0x080c, 0x6c50, 0x0005, 0xa18e, 0x0047,
+       0x1118, 0xa016, 0x080c, 0x1824, 0x0005, 0x0066, 0x6000, 0xa0b2,
+       0x0010, 0x1a0c, 0x14f6, 0x0013, 0x006e, 0x0005, 0x80de, 0x8478,
+       0x862d, 0x80de, 0x86a2, 0x81cf, 0x80de, 0x80de, 0x840a, 0x8a91,
+       0x80de, 0x80de, 0x80de, 0x80de, 0x80de, 0x80de, 0x080c, 0x14f6,
+       0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x14f6, 0x0013, 0x006e,
+       0x0005, 0x80f9, 0x909a, 0x80f9, 0x80f9, 0x80f9, 0x80f9, 0x80f9,
+       0x80f9, 0x9045, 0x9200, 0x80f9, 0x90c7, 0x913e, 0x90c7, 0x913e,
+       0x80f9, 0x080c, 0x14f6, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c,
+       0x14f6, 0x0013, 0x006e, 0x0005, 0x8114, 0x8ad2, 0x8b98, 0x8cb8,
+       0x8e12, 0x8114, 0x8114, 0x8114, 0x8aac, 0x8ff5, 0x8ff8, 0x8114,
+       0x8114, 0x8114, 0x8114, 0x9022, 0x080c, 0x14f6, 0x0066, 0x6000,
+       0xa0b2, 0x0010, 0x1a0c, 0x14f6, 0x0013, 0x006e, 0x0005, 0x812f,
+       0x812f, 0x812f, 0x8152, 0x81a5, 0x812f, 0x812f, 0x812f, 0x8131,
+       0x812f, 0x812f, 0x812f, 0x812f, 0x812f, 0x812f, 0x812f, 0x080c,
+       0x14f6, 0xa186, 0x0003, 0x190c, 0x14f6, 0x00d6, 0x6003, 0x0003,
+       0x6106, 0x6010, 0x2068, 0x684f, 0x0040, 0x687c, 0x680a, 0x6880,
+       0x680e, 0x6813, 0x0000, 0x6817, 0x0000, 0x00de, 0x2c10, 0x080c,
+       0x1e6e, 0x080c, 0x680b, 0x0126, 0x2091, 0x8000, 0x080c, 0x6d0d,
+       0x012e, 0x0005, 0xa182, 0x0047, 0x0002, 0x815e, 0x815e, 0x8160,
+       0x817f, 0x815e, 0x815e, 0x815e, 0x815e, 0x8191, 0x080c, 0x14f6,
+       0x00d6, 0x0016, 0x080c, 0x6c05, 0x080c, 0x6d0d, 0x6003, 0x0004,
+       0x6110, 0x2168, 0x6854, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116,
+       0x684f, 0x0020, 0x685c, 0x685a, 0x6874, 0x687e, 0x6878, 0x6882,
+       0x6897, 0x0000, 0x689b, 0x0000, 0x001e, 0x00de, 0x0005, 0x080c,
+       0x6c05, 0x00d6, 0x6110, 0x2168, 0x080c, 0x9596, 0x0120, 0x684b,
+       0x0006, 0x080c, 0x510c, 0x00de, 0x080c, 0x8078, 0x080c, 0x6d0d,
+       0x0005, 0x080c, 0x6c05, 0x080c, 0x2ad9, 0x00d6, 0x6110, 0x2168,
+       0x080c, 0x9596, 0x0120, 0x684b, 0x0029, 0x080c, 0x510c, 0x00de,
+       0x080c, 0x8078, 0x080c, 0x6d0d, 0x0005, 0xa182, 0x0047, 0x0002,
+       0x81b3, 0x81c2, 0x81b1, 0x81b1, 0x81b1, 0x81b1, 0x81b1, 0x81b1,
+       0x81b1, 0x080c, 0x14f6, 0x00d6, 0x6010, 0x2068, 0x684c, 0xc0f4,
+       0x684e, 0x00de, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c,
+       0x1824, 0x0005, 0x00d6, 0x6110, 0x2168, 0x684b, 0x0000, 0x6853,
+       0x0000, 0x080c, 0x510c, 0x00de, 0x080c, 0x8078, 0x0005, 0xa1b6,
+       0x0015, 0x1118, 0x080c, 0x8078, 0x0030, 0xa1b6, 0x0016, 0x190c,
+       0x14f6, 0x080c, 0x8078, 0x0005, 0x20a9, 0x000e, 0x2e98, 0x6010,
+       0x20a0, 0x53a3, 0x20a9, 0x0006, 0x3310, 0x3420, 0x9398, 0x94a0,
+       0x3318, 0x3428, 0x222e, 0x2326, 0xa290, 0x0002, 0xa5a8, 0x0002,
+       0xa398, 0x0002, 0xa4a0, 0x0002, 0x1f04, 0x81ea, 0x00e6, 0x080c,
+       0x9596, 0x0130, 0x6010, 0x2070, 0x7007, 0x0000, 0x7037, 0x0103,
+       0x00ee, 0x080c, 0x8078, 0x0005, 0x00d6, 0x0036, 0x7330, 0xa386,
+       0x0200, 0x1130, 0x6018, 0x2068, 0x6813, 0x00ff, 0x6817, 0xfffd,
+       0x6010, 0xa005, 0x0130, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103,
+       0x6b32, 0x080c, 0x8078, 0x003e, 0x00de, 0x0005, 0x0016, 0x20a9,
+       0x002a, 0xae80, 0x000c, 0x2098, 0x6010, 0xa080, 0x0002, 0x20a0,
+       0x53a3, 0x20a9, 0x002a, 0x6010, 0xa080, 0x0001, 0x2004, 0xa080,
+       0x0002, 0x20a0, 0x53a3, 0x00e6, 0x6010, 0x2004, 0x2070, 0x7037,
+       0x0103, 0x00ee, 0x080c, 0x8078, 0x001e, 0x0005, 0x0016, 0x2009,
+       0x0000, 0x7030, 0xa086, 0x0100, 0x0140, 0x7038, 0xa084, 0x00ff,
+       0x808e, 0x703c, 0xa084, 0x00ff, 0x8086, 0xa080, 0x0004, 0xa108,
+       0x21a8, 0xae80, 0x000c, 0x2098, 0x6010, 0xa080, 0x0002, 0x20a0,
+       0x080c, 0x48be, 0x00e6, 0x080c, 0x9596, 0x0140, 0x6010, 0x2070,
+       0x7007, 0x0000, 0x7034, 0x70b2, 0x7037, 0x0103, 0x00ee, 0x080c,
+       0x8078, 0x001e, 0x0005, 0x00e6, 0x00d6, 0x603f, 0x0000, 0x2c68,
+       0x0016, 0x2009, 0x0035, 0x080c, 0x9a34, 0x001e, 0x1168, 0x0026,
+       0x6228, 0x2268, 0x002e, 0x2071, 0xb28c, 0x6b1c, 0xa386, 0x0003,
+       0x0130, 0xa386, 0x0006, 0x0128, 0x080c, 0x8078, 0x0020, 0x0031,
+       0x0010, 0x080c, 0x8323, 0x00de, 0x00ee, 0x0005, 0x00f6, 0x6810,
+       0x2078, 0xa186, 0x0015, 0x0904, 0x830c, 0xa18e, 0x0016, 0x1904,
+       0x8321, 0x700c, 0xa084, 0xff00, 0xa086, 0x1700, 0x1904, 0x82eb,
+       0x8fff, 0x0904, 0x831f, 0x6808, 0xa086, 0xffff, 0x1904, 0x830e,
+       0x784c, 0xa084, 0x0060, 0xa086, 0x0020, 0x1150, 0x797c, 0x7810,
+       0xa106, 0x1904, 0x830e, 0x7980, 0x7814, 0xa106, 0x1904, 0x830e,
+       0x080c, 0x9742, 0x6858, 0x7852, 0x784c, 0xc0dc, 0xc0f4, 0xc0d4,
+       0x784e, 0x0026, 0xa00e, 0x6a14, 0x2001, 0x000a, 0x080c, 0x6665,
+       0x7854, 0xa20a, 0x0208, 0x8011, 0x7a56, 0x82ff, 0x002e, 0x1138,
+       0x00c6, 0x2d60, 0x080c, 0x9374, 0x00ce, 0x0804, 0x831f, 0x00c6,
+       0x00d6, 0x2f68, 0x6838, 0xd0fc, 0x1118, 0x080c, 0x4993, 0x0010,
+       0x080c, 0x4b7c, 0x00de, 0x00ce, 0x1548, 0x00c6, 0x2d60, 0x080c,
+       0x8078, 0x00ce, 0x04a0, 0x7008, 0xa086, 0x000b, 0x11a0, 0x6018,
+       0x200c, 0xc1bc, 0x2102, 0x00c6, 0x2d60, 0x7853, 0x0003, 0x6007,
+       0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c, 0x67a8, 0x080c,
+       0x6c50, 0x00ce, 0x00e0, 0x700c, 0xa086, 0x2a00, 0x1138, 0x2001,
+       0xafa5, 0x2004, 0x683e, 0x0098, 0x0471, 0x0098, 0x8fff, 0x090c,
+       0x14f6, 0x00c6, 0x00d6, 0x2d60, 0x2f68, 0x684b, 0x0003, 0x080c,
+       0x926f, 0x080c, 0x9742, 0x080c, 0x974e, 0x00de, 0x00ce, 0x080c,
+       0x8078, 0x00fe, 0x0005, 0xa186, 0x0015, 0x1128, 0x2001, 0xafa5,
+       0x2004, 0x683e, 0x0068, 0xa18e, 0x0016, 0x1160, 0x00c6, 0x2d00,
+       0x2060, 0x080c, 0xabb4, 0x080c, 0x6618, 0x080c, 0x8078, 0x00ce,
+       0x080c, 0x8078, 0x0005, 0x0026, 0x0036, 0x0046, 0x7228, 0x7c80,
+       0x7b7c, 0xd2f4, 0x0130, 0x2001, 0xafa5, 0x2004, 0x683e, 0x0804,
+       0x839d, 0x00c6, 0x2d60, 0x080c, 0x928f, 0x00ce, 0x6804, 0xa086,
+       0x0050, 0x1168, 0x00c6, 0x2d00, 0x2060, 0x6003, 0x0001, 0x6007,
+       0x0050, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x00ce, 0x04f0, 0x6800,
+       0xa086, 0x000f, 0x01c8, 0x8fff, 0x090c, 0x14f6, 0x6820, 0xd0dc,
+       0x1198, 0x6800, 0xa086, 0x0004, 0x1198, 0x784c, 0xd0ac, 0x0180,
+       0x784c, 0xc0dc, 0xc0f4, 0x784e, 0x7850, 0xc0f4, 0xc0fc, 0x7852,
+       0x2001, 0x0001, 0x682e, 0x00e0, 0x2001, 0x0007, 0x682e, 0x00c0,
+       0x784c, 0xd0b4, 0x1130, 0xd0ac, 0x0db8, 0x784c, 0xd0f4, 0x1da0,
+       0x0c38, 0xd2ec, 0x1d88, 0x7024, 0xa306, 0x1118, 0x7020, 0xa406,
+       0x0d58, 0x7020, 0x6836, 0x7024, 0x683a, 0x2001, 0x0005, 0x682e,
+       0x080c, 0x9894, 0x080c, 0x6c50, 0x0010, 0x080c, 0x8078, 0x004e,
+       0x003e, 0x002e, 0x0005, 0x00e6, 0x00d6, 0x0026, 0x6034, 0x2068,
+       0x6a1c, 0xa286, 0x0007, 0x0904, 0x83ee, 0xa286, 0x0002, 0x05f0,
+       0xa286, 0x0000, 0x05d8, 0x6808, 0x6338, 0xa306, 0x15b8, 0x2071,
+       0xb28c, 0xa186, 0x0015, 0x0560, 0xa18e, 0x0016, 0x1190, 0x6030,
+       0xa084, 0x00ff, 0xa086, 0x0001, 0x1160, 0x700c, 0xa086, 0x2a00,
+       0x1140, 0x6034, 0xa080, 0x0008, 0x200c, 0xc1dd, 0xc1f5, 0x2102,
+       0x00b8, 0x00c6, 0x6034, 0x2060, 0x6010, 0x2068, 0x080c, 0x9596,
+       0x090c, 0x14f6, 0x6853, 0x0003, 0x6007, 0x0085, 0x6003, 0x000b,
+       0x601f, 0x0002, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x00ce, 0x0030,
+       0x6034, 0x2070, 0x2001, 0xafa5, 0x2004, 0x703e, 0x080c, 0x8078,
+       0x002e, 0x00de, 0x00ee, 0x0005, 0x00d6, 0x20a9, 0x000e, 0x2e98,
+       0x6010, 0x20a0, 0x53a3, 0xa1b6, 0x0015, 0x1148, 0x6018, 0x2068,
+       0x7038, 0x680a, 0x703c, 0x680e, 0x6800, 0xc08d, 0x6802, 0x00de,
+       0x0804, 0x81f6, 0x2100, 0xa1b2, 0x0080, 0x1a0c, 0x14f6, 0xa1b2,
+       0x0040, 0x1a04, 0x846e, 0x0002, 0x8462, 0x8456, 0x8462, 0x8462,
+       0x8462, 0x8462, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454,
+       0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454,
+       0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454,
+       0x8454, 0x8454, 0x8454, 0x8462, 0x8454, 0x8462, 0x8462, 0x8454,
+       0x8454, 0x8454, 0x8454, 0x8454, 0x8462, 0x8454, 0x8454, 0x8454,
+       0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8462, 0x8462,
+       0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454,
+       0x8454, 0x8462, 0x8454, 0x8454, 0x080c, 0x14f6, 0x6003, 0x0001,
+       0x6106, 0x080c, 0x67ee, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c50,
+       0x012e, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x67ee, 0x0126,
+       0x2091, 0x8000, 0x080c, 0x6c50, 0x012e, 0x0005, 0x2600, 0x0002,
+       0x8462, 0x8476, 0x8476, 0x8462, 0x8462, 0x8476, 0x080c, 0x14f6,
+       0x6004, 0xa0b2, 0x0080, 0x1a0c, 0x14f6, 0xa1b6, 0x0013, 0x0904,
+       0x8518, 0xa1b6, 0x0027, 0x1904, 0x84de, 0x080c, 0x6b73, 0x6004,
+       0x080c, 0x9778, 0x0188, 0x080c, 0x9789, 0x0904, 0x84d8, 0xa08e,
+       0x0021, 0x0904, 0x84db, 0xa08e, 0x0022, 0x0904, 0x84d8, 0xa08e,
+       0x003d, 0x0904, 0x84db, 0x04a8, 0x080c, 0x2aff, 0x2001, 0x0007,
+       0x080c, 0x4c30, 0x6018, 0xa080, 0x0028, 0x200c, 0x080c, 0x85f3,
+       0xa186, 0x007e, 0x1148, 0x2001, 0xad34, 0x2014, 0xc285, 0x080c,
+       0x574f, 0x1108, 0xc2ad, 0x2202, 0x0016, 0x0026, 0x0036, 0x2110,
+       0x2019, 0x0028, 0x080c, 0x68e7, 0x0076, 0x2039, 0x0000, 0x080c,
+       0x681d, 0x00c6, 0x6018, 0xa065, 0x0110, 0x080c, 0x4ecf, 0x00ce,
+       0x2c08, 0x080c, 0xa712, 0x007e, 0x003e, 0x002e, 0x001e, 0x080c,
+       0x4c9f, 0x080c, 0x994e, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005,
+       0x080c, 0x85f3, 0x0cb0, 0x080c, 0x8621, 0x0c98, 0xa186, 0x0014,
+       0x1db0, 0x080c, 0x6b73, 0x080c, 0x2ad9, 0x080c, 0x9778, 0x1188,
+       0x080c, 0x2aff, 0x6018, 0xa080, 0x0028, 0x200c, 0x080c, 0x85f3,
+       0xa186, 0x007e, 0x1128, 0x2001, 0xad34, 0x200c, 0xc185, 0x2102,
+       0x08c0, 0x080c, 0x9789, 0x1118, 0x080c, 0x85f3, 0x0890, 0x6004,
+       0xa08e, 0x0032, 0x1158, 0x00e6, 0x00f6, 0x2071, 0xad81, 0x2079,
+       0x0000, 0x080c, 0x2df1, 0x00fe, 0x00ee, 0x0818, 0x6004, 0xa08e,
+       0x0021, 0x0d50, 0xa08e, 0x0022, 0x090c, 0x85f3, 0x0804, 0x84d1,
+       0xa0b2, 0x0040, 0x1a04, 0x85db, 0x2008, 0x0002, 0x8560, 0x8561,
+       0x8564, 0x8567, 0x856a, 0x856d, 0x855e, 0x855e, 0x855e, 0x855e,
+       0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e,
+       0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e,
+       0x855e, 0x855e, 0x855e, 0x855e, 0x8570, 0x857f, 0x855e, 0x8581,
+       0x857f, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x857f, 0x857f,
+       0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e,
+       0x85bb, 0x857f, 0x855e, 0x857b, 0x855e, 0x855e, 0x855e, 0x857c,
+       0x855e, 0x855e, 0x855e, 0x857f, 0x85b2, 0x855e, 0x080c, 0x14f6,
+       0x00f0, 0x2001, 0x000b, 0x0460, 0x2001, 0x0003, 0x0448, 0x2001,
+       0x0005, 0x0430, 0x2001, 0x0001, 0x0418, 0x2001, 0x0009, 0x0400,
+       0x080c, 0x6b73, 0x6003, 0x0005, 0x2001, 0xafa5, 0x2004, 0x603e,
+       0x080c, 0x6c50, 0x00a0, 0x0018, 0x0010, 0x080c, 0x4c30, 0x0804,
+       0x85cc, 0x080c, 0x6b73, 0x2001, 0xafa3, 0x2004, 0x6016, 0x2001,
+       0xafa5, 0x2004, 0x603e, 0x6003, 0x0004, 0x080c, 0x6c50, 0x0005,
+       0x080c, 0x4c30, 0x080c, 0x6b73, 0x6003, 0x0002, 0x2001, 0xafa5,
+       0x2004, 0x603e, 0x0036, 0x2019, 0xad5c, 0x2304, 0xa084, 0xff00,
+       0x1120, 0x2001, 0xafa3, 0x201c, 0x0040, 0x8007, 0xa09a, 0x0004,
+       0x0ec0, 0x8003, 0x801b, 0x831b, 0xa318, 0x6316, 0x003e, 0x080c,
+       0x6c50, 0x08e8, 0x080c, 0x6b73, 0x080c, 0x994e, 0x080c, 0x8078,
+       0x080c, 0x6c50, 0x08a0, 0x00e6, 0x00f6, 0x2071, 0xad81, 0x2079,
+       0x0000, 0x080c, 0x2df1, 0x00fe, 0x00ee, 0x080c, 0x6b73, 0x080c,
+       0x8078, 0x080c, 0x6c50, 0x0818, 0x080c, 0x6b73, 0x2001, 0xafa5,
+       0x2004, 0x603e, 0x6003, 0x0002, 0x2001, 0xafa3, 0x2004, 0x6016,
+       0x080c, 0x6c50, 0x0005, 0x2600, 0x2008, 0x0002, 0x85e6, 0x85e4,
+       0x85e4, 0x85cc, 0x85cc, 0x85e4, 0x080c, 0x14f6, 0x080c, 0x6b73,
+       0x00d6, 0x6010, 0x2068, 0x080c, 0x15f0, 0x00de, 0x080c, 0x8078,
+       0x080c, 0x6c50, 0x0005, 0x00e6, 0x0026, 0x0016, 0x080c, 0x9596,
+       0x0508, 0x6010, 0x2070, 0x7034, 0xa086, 0x0139, 0x1148, 0x2001,
+       0x0030, 0x2009, 0x0000, 0x2011, 0x4005, 0x080c, 0x9a05, 0x0090,
+       0x7038, 0xd0fc, 0x0178, 0x7007, 0x0000, 0x0016, 0x6004, 0xa08e,
+       0x0021, 0x0160, 0xa08e, 0x003d, 0x0148, 0x001e, 0x7037, 0x0103,
+       0x7033, 0x0100, 0x001e, 0x002e, 0x00ee, 0x0005, 0x001e, 0x0009,
+       0x0cc8, 0x00e6, 0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070, 0x7037,
+       0x0103, 0x7023, 0x8001, 0x00ee, 0x0005, 0x00d6, 0x6618, 0x2668,
+       0x6804, 0xa084, 0x00ff, 0x00de, 0xa0b2, 0x000c, 0x1a0c, 0x14f6,
+       0x6604, 0xa6b6, 0x0043, 0x1120, 0x080c, 0x99c1, 0x0804, 0x8692,
+       0x6604, 0xa6b6, 0x0033, 0x1120, 0x080c, 0x9971, 0x0804, 0x8692,
+       0x6604, 0xa6b6, 0x0028, 0x1120, 0x080c, 0x97b9, 0x0804, 0x8692,
+       0x6604, 0xa6b6, 0x0029, 0x1118, 0x080c, 0x97d0, 0x04d8, 0x6604,
+       0xa6b6, 0x001f, 0x1118, 0x080c, 0x81dc, 0x04a0, 0x6604, 0xa6b6,
+       0x0000, 0x1118, 0x080c, 0x83f4, 0x0468, 0x6604, 0xa6b6, 0x0022,
+       0x1118, 0x080c, 0x8204, 0x0430, 0x6604, 0xa6b6, 0x0035, 0x1118,
+       0x080c, 0x826b, 0x00f8, 0x6604, 0xa6b6, 0x0039, 0x1118, 0x080c,
+       0x83a3, 0x00c0, 0x6604, 0xa6b6, 0x003d, 0x1118, 0x080c, 0x821e,
+       0x0088, 0x6604, 0xa6b6, 0x0044, 0x1118, 0x080c, 0x823e, 0x0050,
+       0xa1b6, 0x0015, 0x1110, 0x0053, 0x0028, 0xa1b6, 0x0016, 0x1118,
+       0x0804, 0x883f, 0x0005, 0x080c, 0x80be, 0x0ce0, 0x86b9, 0x86bc,
+       0x86b9, 0x86fe, 0x86b9, 0x87cc, 0x884d, 0x86b9, 0x86b9, 0x881b,
+       0x86b9, 0x882f, 0xa1b6, 0x0048, 0x0140, 0x20e1, 0x0005, 0x3d18,
+       0x3e20, 0x2c10, 0x080c, 0x1824, 0x0005, 0x00e6, 0xacf0, 0x0004,
+       0x2e74, 0x7000, 0x2070, 0x7037, 0x0103, 0x00ee, 0x080c, 0x8078,
+       0x0005, 0xe000, 0xe000, 0x0005, 0x00e6, 0x2071, 0xad00, 0x7080,
+       0xa086, 0x0074, 0x1530, 0x080c, 0xa6e9, 0x11b0, 0x00d6, 0x6018,
+       0x2068, 0x7030, 0xd08c, 0x0128, 0x6800, 0xd0bc, 0x0110, 0xc0c5,
+       0x6802, 0x00d9, 0x00de, 0x2001, 0x0006, 0x080c, 0x4c30, 0x080c,
+       0x2aff, 0x080c, 0x8078, 0x0078, 0x2001, 0x000a, 0x080c, 0x4c30,
+       0x080c, 0x2aff, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x67ee,
+       0x0010, 0x080c, 0x87bd, 0x00ee, 0x0005, 0x6800, 0xd084, 0x0168,
+       0x2001, 0x0000, 0x080c, 0x4c1e, 0x2069, 0xad51, 0x6804, 0xd0a4,
+       0x0120, 0x2001, 0x0006, 0x080c, 0x4c5d, 0x0005, 0x00d6, 0x2011,
+       0xad20, 0x2204, 0xa086, 0x0074, 0x1904, 0x87ba, 0x6018, 0x2068,
+       0x6aa0, 0xa286, 0x007e, 0x1120, 0x080c, 0x894d, 0x0804, 0x875e,
+       0x080c, 0x8943, 0x6018, 0x2068, 0xa080, 0x0028, 0x2014, 0xa286,
+       0x0080, 0x11c0, 0x6813, 0x00ff, 0x6817, 0xfffc, 0x6010, 0xa005,
+       0x0138, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6833, 0x0200,
+       0x2001, 0x0006, 0x080c, 0x4c30, 0x080c, 0x2aff, 0x080c, 0x8078,
+       0x0804, 0x87bb, 0x00e6, 0x2071, 0xad34, 0x2e04, 0xd09c, 0x0188,
+       0x2071, 0xb280, 0x7108, 0x720c, 0xa18c, 0x00ff, 0x1118, 0xa284,
+       0xff00, 0x0138, 0x6018, 0x2070, 0x70a0, 0xd0bc, 0x1110, 0x7112,
+       0x7216, 0x00ee, 0x6010, 0xa005, 0x0128, 0x2068, 0x6838, 0xd0f4,
+       0x0108, 0x0880, 0x2001, 0x0004, 0x080c, 0x4c30, 0x6003, 0x0001,
+       0x6007, 0x0003, 0x080c, 0x67ee, 0x0804, 0x87bb, 0x685c, 0xd0e4,
+       0x01d0, 0x080c, 0x9903, 0x080c, 0x574f, 0x0110, 0xd0dc, 0x1900,
+       0x2011, 0xad34, 0x2204, 0xc0ad, 0x2012, 0x2001, 0xaf8e, 0x2004,
+       0x00f6, 0x2079, 0x0100, 0x78e3, 0x0000, 0x080c, 0x26cb, 0x78e2,
+       0x00fe, 0x0804, 0x8728, 0x080c, 0x9937, 0x2011, 0xad34, 0x2204,
+       0xc0a5, 0x2012, 0x0006, 0x080c, 0xa801, 0x000e, 0x1904, 0x8728,
+       0xc0b5, 0x2012, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x00c6, 0x2009,
+       0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x7932, 0x7936, 0x00fe,
+       0x080c, 0x26a0, 0x00f6, 0x2079, 0xad00, 0x7972, 0x2100, 0x2009,
+       0x0000, 0x080c, 0x2676, 0x794e, 0x00fe, 0x8108, 0x080c, 0x4c80,
+       0x2c00, 0x00ce, 0x1904, 0x8728, 0x601a, 0x2001, 0x0002, 0x080c,
+       0x4c30, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c,
+       0x67ee, 0x0008, 0x0011, 0x00de, 0x0005, 0x2001, 0xad00, 0x2004,
+       0xa086, 0x0003, 0x0120, 0x2001, 0x0007, 0x080c, 0x4c30, 0x080c,
+       0x2aff, 0x080c, 0x8078, 0x0005, 0x00e6, 0x0026, 0x0016, 0x2071,
+       0xad00, 0x7080, 0xa086, 0x0014, 0x15f0, 0x7000, 0xa086, 0x0003,
+       0x1128, 0x6010, 0xa005, 0x1110, 0x080c, 0x3cce, 0x00d6, 0x6018,
+       0x2068, 0x080c, 0x4d72, 0x080c, 0x86ed, 0x00de, 0x080c, 0x89f7,
+       0x1550, 0x00d6, 0x6018, 0x2068, 0x6890, 0x00de, 0xa005, 0x0518,
+       0x2001, 0x0006, 0x080c, 0x4c30, 0x00e6, 0x6010, 0xa075, 0x01a8,
+       0x7034, 0xa084, 0x00ff, 0xa086, 0x0039, 0x1148, 0x2001, 0x0000,
+       0x2009, 0x0000, 0x2011, 0x4000, 0x080c, 0x9a05, 0x0030, 0x7007,
+       0x0000, 0x7037, 0x0103, 0x7033, 0x0200, 0x00ee, 0x080c, 0x2aff,
+       0x080c, 0x8078, 0x0020, 0x080c, 0x85f3, 0x080c, 0x87bd, 0x001e,
+       0x002e, 0x00ee, 0x0005, 0x2011, 0xad20, 0x2204, 0xa086, 0x0014,
+       0x1158, 0x2001, 0x0002, 0x080c, 0x4c30, 0x6003, 0x0001, 0x6007,
+       0x0001, 0x080c, 0x67ee, 0x0010, 0x080c, 0x87bd, 0x0005, 0x2011,
+       0xad20, 0x2204, 0xa086, 0x0004, 0x1138, 0x2001, 0x0007, 0x080c,
+       0x4c30, 0x080c, 0x8078, 0x0010, 0x080c, 0x87bd, 0x0005, 0x000b,
+       0x0005, 0x86b9, 0x8854, 0x86b9, 0x888a, 0x86b9, 0x88ff, 0x884d,
+       0x86b9, 0x86b9, 0x8912, 0x86b9, 0x8922, 0x6604, 0xa6b6, 0x001e,
+       0x1110, 0x080c, 0x8078, 0x0005, 0x00d6, 0x00c6, 0x080c, 0x8932,
+       0x1178, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x2001, 0x0002, 0x080c,
+       0x4c30, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x67ee, 0x00f8,
+       0x2009, 0xb28e, 0x2104, 0xa086, 0x0009, 0x1160, 0x6018, 0x2068,
+       0x6840, 0xa084, 0x00ff, 0xa005, 0x0180, 0x8001, 0x6842, 0x6017,
+       0x000a, 0x0068, 0x2009, 0xb28f, 0x2104, 0xa084, 0xff00, 0xa086,
+       0x1900, 0x1118, 0x080c, 0x8078, 0x0010, 0x080c, 0x87bd, 0x00ce,
+       0x00de, 0x0005, 0x080c, 0x8940, 0x00d6, 0x2069, 0xaf9d, 0x2d04,
+       0xa005, 0x0168, 0x6018, 0x2068, 0x68a0, 0xa086, 0x007e, 0x1138,
+       0x2069, 0xad1c, 0x2d04, 0x8000, 0x206a, 0x00de, 0x0010, 0x00de,
+       0x0078, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x2001, 0x0002, 0x080c,
+       0x4c30, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x67ee, 0x0428,
+       0x080c, 0x85f3, 0x2009, 0xb28e, 0x2134, 0xa6b4, 0x00ff, 0xa686,
+       0x0005, 0x01e0, 0xa686, 0x000b, 0x01b0, 0x2009, 0xb28f, 0x2104,
+       0xa084, 0xff00, 0x1118, 0xa686, 0x0009, 0x0180, 0xa086, 0x1900,
+       0x1150, 0xa686, 0x0009, 0x0150, 0x2001, 0x0004, 0x080c, 0x4c30,
+       0x080c, 0x8078, 0x0010, 0x080c, 0x87bd, 0x0005, 0x00d6, 0x6010,
+       0x2068, 0x080c, 0x9596, 0x0128, 0x6838, 0xd0fc, 0x0110, 0x00de,
+       0x0c90, 0x6018, 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0140,
+       0x8001, 0x6842, 0x6017, 0x000a, 0x6007, 0x0016, 0x00de, 0x0c28,
+       0x68a0, 0xa086, 0x007e, 0x1138, 0x00e6, 0x2071, 0xad00, 0x080c,
+       0x48f5, 0x00ee, 0x0010, 0x080c, 0x2ad9, 0x00de, 0x08a0, 0x080c,
+       0x8940, 0x1158, 0x2001, 0x0004, 0x080c, 0x4c30, 0x6003, 0x0001,
+       0x6007, 0x0003, 0x080c, 0x67ee, 0x0020, 0x080c, 0x85f3, 0x080c,
+       0x87bd, 0x0005, 0x0469, 0x1158, 0x2001, 0x0008, 0x080c, 0x4c30,
+       0x6003, 0x0001, 0x6007, 0x0005, 0x080c, 0x67ee, 0x0010, 0x080c,
+       0x87bd, 0x0005, 0x00e9, 0x1158, 0x2001, 0x000a, 0x080c, 0x4c30,
+       0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x67ee, 0x0010, 0x080c,
+       0x87bd, 0x0005, 0x2009, 0xb28e, 0x2104, 0xa086, 0x0003, 0x1138,
+       0x2009, 0xb28f, 0x2104, 0xa084, 0xff00, 0xa086, 0x2a00, 0x0005,
+       0xa085, 0x0001, 0x0005, 0x00c6, 0x0016, 0xac88, 0x0006, 0x2164,
+       0x080c, 0x4ceb, 0x001e, 0x00ce, 0x0005, 0x00f6, 0x00e6, 0x00d6,
+       0x0036, 0x0016, 0x6018, 0x2068, 0x2071, 0xad34, 0x2e04, 0xa085,
+       0x0003, 0x2072, 0x080c, 0x89cc, 0x0538, 0x2001, 0xad52, 0x2004,
+       0xd0a4, 0x0158, 0xa006, 0x2020, 0x2009, 0x002a, 0x080c, 0xa96c,
+       0x2001, 0xad0c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009,
+       0x0001, 0x080c, 0x2aac, 0x2071, 0xad00, 0x080c, 0x28fa, 0x00c6,
+       0x0156, 0x20a9, 0x0081, 0x2009, 0x007f, 0x080c, 0x2bc9, 0x8108,
+       0x1f04, 0x897d, 0x015e, 0x00ce, 0x080c, 0x8943, 0x6813, 0x00ff,
+       0x6817, 0xfffe, 0x2071, 0xb280, 0x2079, 0x0100, 0x2e04, 0xa084,
+       0x00ff, 0x2069, 0xad1b, 0x206a, 0x78e6, 0x0006, 0x8e70, 0x2e04,
+       0x2069, 0xad1c, 0x206a, 0x78ea, 0x7832, 0x7836, 0x2010, 0xa084,
+       0xff00, 0x001e, 0xa105, 0x2009, 0xad27, 0x200a, 0x2200, 0xa084,
+       0x00ff, 0x2008, 0x080c, 0x26a0, 0x080c, 0x574f, 0x0170, 0x2069,
+       0xb28e, 0x2071, 0xaf9f, 0x6810, 0x2072, 0x6814, 0x7006, 0x6818,
+       0x700a, 0x681c, 0x700e, 0x080c, 0x9903, 0x0040, 0x2001, 0x0006,
+       0x080c, 0x4c30, 0x080c, 0x2aff, 0x080c, 0x8078, 0x001e, 0x003e,
+       0x00de, 0x00ee, 0x00fe, 0x0005, 0x0026, 0x0036, 0x00e6, 0x0156,
+       0x2019, 0xad27, 0x231c, 0x83ff, 0x01e8, 0x2071, 0xb280, 0x2e14,
+       0xa294, 0x00ff, 0x7004, 0xa084, 0xff00, 0xa205, 0xa306, 0x1190,
+       0x2011, 0xb296, 0xad98, 0x000a, 0x20a9, 0x0004, 0x080c, 0x8a7c,
+       0x1148, 0x2011, 0xb29a, 0xad98, 0x0006, 0x20a9, 0x0004, 0x080c,
+       0x8a7c, 0x1100, 0x015e, 0x00ee, 0x003e, 0x002e, 0x0005, 0x00e6,
+       0x2071, 0xb28c, 0x7004, 0xa086, 0x0014, 0x11a8, 0x7008, 0xa086,
+       0x0800, 0x1188, 0x700c, 0xd0ec, 0x0160, 0xa084, 0x0f00, 0xa086,
+       0x0100, 0x1138, 0x7024, 0xd0a4, 0x1110, 0xd0ac, 0x0110, 0xa006,
+       0x0010, 0xa085, 0x0001, 0x00ee, 0x0005, 0x00e6, 0x00d6, 0x00c6,
+       0x0076, 0x0056, 0x0046, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000,
+       0x2029, 0xafd0, 0x252c, 0x2021, 0xafd6, 0x2424, 0x2061, 0xb400,
+       0x2071, 0xad00, 0x7244, 0x7064, 0xa202, 0x16f0, 0x080c, 0xa990,
+       0x05a0, 0x671c, 0xa786, 0x0001, 0x0580, 0xa786, 0x0007, 0x0568,
+       0x2500, 0xac06, 0x0550, 0x2400, 0xac06, 0x0538, 0x00c6, 0x6000,
+       0xa086, 0x0004, 0x1110, 0x080c, 0x190b, 0xa786, 0x0008, 0x1148,
+       0x080c, 0x9789, 0x1130, 0x00ce, 0x080c, 0x85f3, 0x080c, 0x974e,
+       0x00a0, 0x6010, 0x2068, 0x080c, 0x9596, 0x0160, 0xa786, 0x0003,
+       0x11e8, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x510c,
+       0x080c, 0x9742, 0x080c, 0x974e, 0x00ce, 0xace0, 0x0018, 0x7058,
+       0xac02, 0x1210, 0x0804, 0x8a2a, 0x012e, 0x000e, 0x002e, 0x004e,
+       0x005e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0xa786, 0x0006,
+       0x1d00, 0x080c, 0xa91f, 0x0c30, 0x220c, 0x2304, 0xa106, 0x1130,
+       0x8210, 0x8318, 0x1f04, 0x8a7c, 0xa006, 0x0005, 0x2304, 0xa102,
+       0x0218, 0x2001, 0x0001, 0x0010, 0x2001, 0x0000, 0xa18d, 0x0001,
+       0x0005, 0x6004, 0xa08a, 0x0080, 0x1a0c, 0x14f6, 0x080c, 0x9778,
+       0x0120, 0x080c, 0x9789, 0x0168, 0x0028, 0x080c, 0x2aff, 0x080c,
+       0x9789, 0x0138, 0x080c, 0x6b73, 0x080c, 0x8078, 0x080c, 0x6c50,
+       0x0005, 0x080c, 0x85f3, 0x0cb0, 0xa182, 0x0040, 0x0002, 0x8ac2,
+       0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2,
+       0x8ac2, 0x8ac2, 0x8ac4, 0x8ac4, 0x8ac4, 0x8ac4, 0x8ac2, 0x8ac2,
+       0x8ac2, 0x8ac4, 0x080c, 0x14f6, 0x600b, 0xffff, 0x6003, 0x0001,
+       0x6106, 0x080c, 0x67a8, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c50,
+       0x012e, 0x0005, 0xa186, 0x0013, 0x1128, 0x6004, 0xa082, 0x0040,
+       0x0804, 0x8b5e, 0xa186, 0x0027, 0x11e8, 0x080c, 0x6b73, 0x080c,
+       0x2ad9, 0x00d6, 0x6110, 0x2168, 0x080c, 0x9596, 0x0168, 0x6837,
+       0x0103, 0x684b, 0x0029, 0x6847, 0x0000, 0x694c, 0xc1c5, 0x694e,
+       0x080c, 0x510c, 0x080c, 0x9742, 0x00de, 0x080c, 0x8078, 0x080c,
+       0x6c50, 0x0005, 0xa186, 0x0014, 0x1120, 0x6004, 0xa082, 0x0040,
+       0x0428, 0xa186, 0x0046, 0x0138, 0xa186, 0x0045, 0x0120, 0xa186,
+       0x0047, 0x190c, 0x14f6, 0x2001, 0x0109, 0x2004, 0xd084, 0x0198,
+       0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x080c, 0x6699,
+       0x002e, 0x001e, 0x000e, 0x012e, 0xe000, 0x6000, 0xa086, 0x0002,
+       0x1110, 0x0804, 0x8b98, 0x080c, 0x80be, 0x0005, 0x0002, 0x8b3c,
+       0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a,
+       0x8b3a, 0x8b3a, 0x8b57, 0x8b57, 0x8b57, 0x8b57, 0x8b3a, 0x8b57,
+       0x8b3a, 0x8b57, 0x080c, 0x14f6, 0x080c, 0x6b73, 0x00d6, 0x6110,
+       0x2168, 0x080c, 0x9596, 0x0168, 0x6837, 0x0103, 0x684b, 0x0006,
+       0x6847, 0x0000, 0x6850, 0xc0ec, 0x6852, 0x080c, 0x510c, 0x080c,
+       0x9742, 0x00de, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005, 0x080c,
+       0x6b73, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005, 0x0002, 0x8b74,
+       0x8b72, 0x8b72, 0x8b72, 0x8b72, 0x8b72, 0x8b72, 0x8b72, 0x8b72,
+       0x8b72, 0x8b72, 0x8b86, 0x8b86, 0x8b86, 0x8b86, 0x8b72, 0x8b91,
+       0x8b72, 0x8b86, 0x080c, 0x14f6, 0x080c, 0x6b73, 0x2001, 0xafa5,
+       0x2004, 0x603e, 0x6003, 0x0002, 0x080c, 0x6c50, 0x6010, 0xa088,
+       0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x0005, 0x080c, 0x6b73,
+       0x2001, 0xafa5, 0x2004, 0x603e, 0x6003, 0x000f, 0x080c, 0x6c50,
+       0x0005, 0x080c, 0x6b73, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005,
+       0xa182, 0x0040, 0x0002, 0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x8bae,
+       0x8bb0, 0x8c88, 0x8ca9, 0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x8bae,
+       0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x080c, 0x14f6,
+       0x00e6, 0x00d6, 0x603f, 0x0000, 0x2071, 0xb280, 0x7124, 0x610a,
+       0x2071, 0xb28c, 0x6110, 0x2168, 0x7614, 0xa6b4, 0x0fff, 0x86ff,
+       0x0904, 0x8c54, 0xa68c, 0x0c00, 0x01e8, 0x00f6, 0x2c78, 0x080c,
+       0x5029, 0x00fe, 0x0198, 0x684c, 0xd0ac, 0x0180, 0x6020, 0xd0dc,
+       0x1168, 0x6850, 0xd0bc, 0x1150, 0x7318, 0x6814, 0xa306, 0x1904,
+       0x8c66, 0x731c, 0x6810, 0xa306, 0x1904, 0x8c66, 0x7318, 0x6b62,
+       0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0518, 0xa186,
+       0x0028, 0x1128, 0x080c, 0x9767, 0x684b, 0x001c, 0x00e8, 0xd6dc,
+       0x01a0, 0x684b, 0x0015, 0x684c, 0xd0ac, 0x0170, 0x6914, 0x6a10,
+       0x2100, 0xa205, 0x0148, 0x7018, 0xa106, 0x1118, 0x701c, 0xa206,
+       0x0118, 0x6962, 0x6a5e, 0xc6dc, 0x0038, 0xd6d4, 0x0118, 0x684b,
+       0x0007, 0x0010, 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46, 0xa01e,
+       0xd6c4, 0x01f0, 0xa686, 0x0100, 0x1140, 0x2001, 0xb299, 0x2004,
+       0xa005, 0x1118, 0xc6c4, 0x0804, 0x8bbf, 0x7328, 0x732c, 0x6b56,
+       0x83ff, 0x0170, 0xa38a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036,
+       0x2308, 0x2019, 0xb298, 0xad90, 0x0019, 0x080c, 0x927f, 0x003e,
+       0xd6cc, 0x0904, 0x8c79, 0x7124, 0x695a, 0x81ff, 0x0904, 0x8c79,
+       0xa192, 0x0021, 0x1250, 0x2071, 0xb298, 0x831c, 0x2300, 0xae18,
+       0xad90, 0x001d, 0x080c, 0x927f, 0x04a0, 0x6838, 0xd0fc, 0x0120,
+       0x2009, 0x0020, 0x695a, 0x0c78, 0x00f6, 0x2d78, 0x080c, 0x9224,
+       0x00fe, 0x080c, 0x926f, 0x0438, 0x00f6, 0x2c78, 0x080c, 0x5029,
+       0x00fe, 0x0188, 0x684c, 0xd0ac, 0x0170, 0x6020, 0xd0dc, 0x1158,
+       0x6850, 0xd0bc, 0x1140, 0x684c, 0xd0f4, 0x1128, 0x080c, 0x9866,
+       0x00de, 0x00ee, 0x00e0, 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46,
+       0x684c, 0xd0ac, 0x0130, 0x6810, 0x6914, 0xa115, 0x0110, 0x080c,
+       0x8e04, 0x080c, 0x510c, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e,
+       0x080c, 0x9834, 0x00de, 0x00ee, 0x1110, 0x080c, 0x8078, 0x0005,
+       0x00f6, 0x6003, 0x0003, 0x2079, 0xb28c, 0x7c04, 0x7b00, 0x7e0c,
+       0x7d08, 0x6010, 0x2078, 0x784c, 0xd0ac, 0x0120, 0x6003, 0x0002,
+       0x00fe, 0x0005, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e, 0x00fe, 0x603f,
+       0x0000, 0x2c10, 0x080c, 0x1e6e, 0x080c, 0x680b, 0x080c, 0x6d0d,
+       0x0005, 0x2001, 0xafa5, 0x2004, 0x603e, 0x6003, 0x0004, 0x6110,
+       0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1824, 0x0005,
+       0xa182, 0x0040, 0x0002, 0x8cce, 0x8cce, 0x8cce, 0x8cce, 0x8cce,
+       0x8cd0, 0x8d61, 0x8cce, 0x8cce, 0x8d77, 0x8ddb, 0x8cce, 0x8cce,
+       0x8cce, 0x8cce, 0x8dea, 0x8cce, 0x8cce, 0x8cce, 0x080c, 0x14f6,
+       0x0076, 0x00f6, 0x00e6, 0x00d6, 0x2071, 0xb28c, 0x6110, 0x2178,
+       0x7614, 0xa6b4, 0x0fff, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218,
+       0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0904, 0x8d5c, 0xa694,
+       0xff00, 0xa284, 0x0c00, 0x0120, 0x7018, 0x7862, 0x701c, 0x785e,
+       0xa284, 0x0300, 0x0904, 0x8d5c, 0x080c, 0x15d9, 0x090c, 0x14f6,
+       0x2d00, 0x784a, 0x7f4c, 0xc7cd, 0x7f4e, 0x6837, 0x0103, 0x7838,
+       0x683a, 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00,
+       0x0120, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186,
+       0x0002, 0x0180, 0xa186, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060,
+       0xd6dc, 0x0118, 0x684b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0x684b,
+       0x0007, 0x0010, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854,
+       0x6856, 0xa01e, 0xd6c4, 0x0198, 0x7328, 0x732c, 0x6b56, 0x83ff,
+       0x0170, 0xa38a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308,
+       0x2019, 0xb298, 0xad90, 0x0019, 0x080c, 0x927f, 0x003e, 0xd6cc,
+       0x01d8, 0x7124, 0x695a, 0x81ff, 0x01b8, 0xa192, 0x0021, 0x1250,
+       0x2071, 0xb298, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x080c,
+       0x927f, 0x0050, 0x7838, 0xd0fc, 0x0120, 0x2009, 0x0020, 0x695a,
+       0x0c78, 0x2d78, 0x080c, 0x9224, 0x00de, 0x00ee, 0x00fe, 0x007e,
+       0x0005, 0x00f6, 0x6003, 0x0003, 0x2079, 0xb28c, 0x7c04, 0x7b00,
+       0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e,
+       0x00fe, 0x2c10, 0x080c, 0x1e6e, 0x080c, 0x781a, 0x0005, 0x00d6,
+       0x00f6, 0x2c78, 0x080c, 0x5029, 0x00fe, 0x0120, 0x2001, 0xafa5,
+       0x2004, 0x603e, 0x6003, 0x0002, 0x080c, 0x6c05, 0x080c, 0x6d0d,
+       0x6110, 0x2168, 0x694c, 0xd1e4, 0x0904, 0x8dd9, 0xd1cc, 0x0540,
+       0x6948, 0x6838, 0xd0fc, 0x01e8, 0x0016, 0x684c, 0x0006, 0x6850,
+       0x0006, 0xad90, 0x000d, 0xa198, 0x000d, 0x2009, 0x0020, 0x0156,
+       0x21a8, 0x2304, 0x2012, 0x8318, 0x8210, 0x1f04, 0x8da1, 0x015e,
+       0x000e, 0x6852, 0x000e, 0x684e, 0x001e, 0x2168, 0x080c, 0x1600,
+       0x0418, 0x0016, 0x080c, 0x1600, 0x00de, 0x080c, 0x926f, 0x00e0,
+       0x6837, 0x0103, 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0180,
+       0xa086, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060, 0xd1dc, 0x0118,
+       0x684b, 0x0015, 0x0038, 0xd1d4, 0x0118, 0x684b, 0x0007, 0x0010,
+       0x684b, 0x0000, 0x080c, 0x510c, 0x080c, 0x9834, 0x1110, 0x080c,
+       0x8078, 0x00de, 0x0005, 0x2019, 0x0001, 0x080c, 0x7a64, 0x6003,
+       0x0002, 0x2001, 0xafa5, 0x2004, 0x603e, 0x080c, 0x6c05, 0x080c,
+       0x6d0d, 0x0005, 0x080c, 0x6c05, 0x080c, 0x2ad9, 0x00d6, 0x6110,
+       0x2168, 0x080c, 0x9596, 0x0150, 0x6837, 0x0103, 0x684b, 0x0029,
+       0x6847, 0x0000, 0x080c, 0x510c, 0x080c, 0x9742, 0x00de, 0x080c,
+       0x8078, 0x080c, 0x6d0d, 0x0005, 0x684b, 0x0015, 0xd1fc, 0x0138,
+       0x684b, 0x0007, 0x8002, 0x8000, 0x810a, 0xa189, 0x0000, 0x6962,
+       0x685e, 0x0005, 0xa182, 0x0040, 0x0002, 0x8e28, 0x8e28, 0x8e28,
+       0x8e28, 0x8e28, 0x8e2a, 0x8e28, 0x8ee3, 0x8eef, 0x8e28, 0x8e28,
+       0x8e28, 0x8e28, 0x8e28, 0x8e28, 0x8e28, 0x8e28, 0x8e28, 0x8e28,
+       0x080c, 0x14f6, 0x0076, 0x00f6, 0x00e6, 0x00d6, 0x2071, 0xb28c,
+       0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x00f6, 0x2c78, 0x080c,
+       0x5029, 0x00fe, 0x0150, 0xa684, 0x00ff, 0x1138, 0x6020, 0xd0f4,
+       0x0120, 0x080c, 0x9866, 0x0804, 0x8ede, 0x7e46, 0x7f4c, 0xc7e5,
+       0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0904,
+       0x8ed4, 0xa694, 0xff00, 0xa284, 0x0c00, 0x0120, 0x7018, 0x7862,
+       0x701c, 0x785e, 0xa284, 0x0300, 0x0904, 0x8ed2, 0xa686, 0x0100,
+       0x1140, 0x2001, 0xb299, 0x2004, 0xa005, 0x1118, 0xc6c4, 0x7e46,
+       0x0c28, 0x080c, 0x15d9, 0x090c, 0x14f6, 0x2d00, 0x784a, 0x7f4c,
+       0xa7bd, 0x0200, 0x7f4e, 0x6837, 0x0103, 0x7838, 0x683a, 0x783c,
+       0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00, 0x0120, 0x7318,
+       0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0180,
+       0xa186, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060, 0xd6dc, 0x0118,
+       0x684b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0x684b, 0x0007, 0x0010,
+       0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854, 0x6856, 0xa01e,
+       0xd6c4, 0x0198, 0x7328, 0x732c, 0x6b56, 0x83ff, 0x0170, 0xa38a,
+       0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0xb298,
+       0xad90, 0x0019, 0x080c, 0x927f, 0x003e, 0xd6cc, 0x01d8, 0x7124,
+       0x695a, 0x81ff, 0x01b8, 0xa192, 0x0021, 0x1250, 0x2071, 0xb298,
+       0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x080c, 0x927f, 0x0050,
+       0x7838, 0xd0fc, 0x0120, 0x2009, 0x0020, 0x695a, 0x0c78, 0x2d78,
+       0x080c, 0x9224, 0xd6dc, 0x1110, 0xa006, 0x0030, 0x2001, 0x0001,
+       0x2071, 0xb28c, 0x7218, 0x731c, 0x080c, 0x186f, 0x00de, 0x00ee,
+       0x00fe, 0x007e, 0x0005, 0x2001, 0xafa5, 0x2004, 0x603e, 0x20e1,
+       0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1824, 0x0005, 0x2001,
+       0xafa5, 0x2004, 0x603e, 0x00d6, 0x6003, 0x0002, 0x6110, 0x2168,
+       0x694c, 0xd1e4, 0x0904, 0x8ff3, 0x603f, 0x0000, 0x00f6, 0x2c78,
+       0x080c, 0x5029, 0x00fe, 0x0548, 0x6814, 0x6910, 0xa115, 0x0528,
+       0x6a60, 0xa206, 0x1118, 0x685c, 0xa106, 0x01f8, 0x684c, 0xc0e4,
+       0x684e, 0x6847, 0x0000, 0x6863, 0x0000, 0x685f, 0x0000, 0x697c,
+       0x6810, 0xa102, 0x603a, 0x6980, 0x6814, 0xa103, 0x6036, 0x6020,
+       0xc0f5, 0x6022, 0x00d6, 0x6018, 0x2068, 0x683c, 0x8000, 0x683e,
+       0x00de, 0x080c, 0x9866, 0x0804, 0x8ff3, 0x694c, 0xd1cc, 0x0904,
+       0x8fc3, 0x6948, 0x6838, 0xd0fc, 0x0904, 0x8f88, 0x0016, 0x684c,
+       0x0006, 0x6850, 0x0006, 0x00f6, 0x2178, 0x7944, 0xa184, 0x00ff,
+       0xa0b6, 0x0002, 0x01e0, 0xa086, 0x0028, 0x1128, 0x684b, 0x001c,
+       0x784b, 0x001c, 0x00e8, 0xd1dc, 0x0158, 0x684b, 0x0015, 0x784b,
+       0x0015, 0x080c, 0x99ee, 0x0118, 0x7944, 0xc1dc, 0x7946, 0x0080,
+       0xd1d4, 0x0128, 0x684b, 0x0007, 0x784b, 0x0007, 0x0048, 0x684c,
+       0xd0ac, 0x0130, 0x6810, 0x6914, 0xa115, 0x0110, 0x080c, 0x8e04,
+       0x6848, 0x784a, 0x6860, 0x7862, 0x685c, 0x785e, 0xad90, 0x000d,
+       0xaf98, 0x000d, 0x2009, 0x0020, 0x0156, 0x21a8, 0x2304, 0x2012,
+       0x8318, 0x8210, 0x1f04, 0x8f76, 0x015e, 0x00fe, 0x000e, 0x6852,
+       0x000e, 0x684e, 0x001e, 0x2168, 0x080c, 0x1600, 0x0804, 0x8fee,
+       0x0016, 0x00f6, 0x2178, 0x7944, 0xa184, 0x00ff, 0xa0b6, 0x0002,
+       0x01e0, 0xa086, 0x0028, 0x1128, 0x684b, 0x001c, 0x784b, 0x001c,
+       0x00e8, 0xd1dc, 0x0158, 0x684b, 0x0015, 0x784b, 0x0015, 0x080c,
+       0x99ee, 0x0118, 0x7944, 0xc1dc, 0x7946, 0x0080, 0xd1d4, 0x0128,
+       0x684b, 0x0007, 0x784b, 0x0007, 0x0048, 0x684c, 0xd0ac, 0x0130,
+       0x6810, 0x6914, 0xa115, 0x0110, 0x080c, 0x8e04, 0x6860, 0x7862,
+       0x685c, 0x785e, 0x684c, 0x784e, 0x00fe, 0x080c, 0x1600, 0x00de,
+       0x080c, 0x926f, 0x0458, 0x6837, 0x0103, 0x6944, 0xa184, 0x00ff,
+       0xa0b6, 0x0002, 0x01b0, 0xa086, 0x0028, 0x1118, 0x684b, 0x001c,
+       0x00d8, 0xd1dc, 0x0148, 0x684b, 0x0015, 0x080c, 0x99ee, 0x0118,
+       0x6944, 0xc1dc, 0x6946, 0x0080, 0xd1d4, 0x0118, 0x684b, 0x0007,
+       0x0058, 0x684b, 0x0000, 0x684c, 0xd0ac, 0x0130, 0x6810, 0x6914,
+       0xa115, 0x0110, 0x080c, 0x8e04, 0x080c, 0x510c, 0x080c, 0x9834,
+       0x1110, 0x080c, 0x8078, 0x00de, 0x0005, 0x080c, 0x6b73, 0x0010,
+       0x080c, 0x6c05, 0x080c, 0x9596, 0x01c0, 0x00d6, 0x6110, 0x2168,
+       0x6837, 0x0103, 0x2009, 0xad0c, 0x210c, 0xd18c, 0x11c0, 0xd184,
+       0x1198, 0x6108, 0x694a, 0xa18e, 0x0029, 0x1110, 0x080c, 0xabfa,
+       0x6847, 0x0000, 0x080c, 0x510c, 0x00de, 0x080c, 0x8078, 0x080c,
+       0x6c50, 0x080c, 0x6d0d, 0x0005, 0x684b, 0x0004, 0x0c88, 0x684b,
+       0x0004, 0x0c70, 0xa182, 0x0040, 0x0002, 0x9038, 0x9038, 0x9038,
+       0x9038, 0x9038, 0x903a, 0x9038, 0x903d, 0x9038, 0x9038, 0x9038,
+       0x9038, 0x9038, 0x9038, 0x9038, 0x9038, 0x9038, 0x9038, 0x9038,
+       0x080c, 0x14f6, 0x080c, 0x8078, 0x0005, 0x0006, 0x0026, 0xa016,
+       0x080c, 0x1824, 0x002e, 0x000e, 0x0005, 0xa182, 0x0085, 0x0002,
+       0x9051, 0x904f, 0x904f, 0x905d, 0x904f, 0x904f, 0x904f, 0x080c,
+       0x14f6, 0x6003, 0x0001, 0x6106, 0x080c, 0x67a8, 0x0126, 0x2091,
+       0x8000, 0x080c, 0x6c50, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6,
+       0x00e6, 0x2071, 0xb280, 0x7224, 0x6212, 0x7220, 0x080c, 0x9586,
+       0x01a0, 0x2268, 0x6800, 0xa086, 0x0000, 0x0178, 0x6018, 0x6d18,
+       0xa52e, 0x1158, 0x00c6, 0x2d60, 0x080c, 0x928f, 0x00ce, 0x0128,
+       0x6803, 0x0002, 0x6007, 0x0086, 0x0010, 0x6007, 0x0087, 0x6003,
+       0x0001, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x00f6, 0x2278, 0x080c,
+       0x5029, 0x00fe, 0x0150, 0x6820, 0xd0ec, 0x0138, 0x00c6, 0x2260,
+       0x603f, 0x0000, 0x080c, 0x9866, 0x00ce, 0x00ee, 0x00de, 0x005e,
+       0x002e, 0x0005, 0xa186, 0x0013, 0x1160, 0x6004, 0xa08a, 0x0085,
+       0x0a0c, 0x14f6, 0xa08a, 0x008c, 0x1a0c, 0x14f6, 0xa082, 0x0085,
+       0x0072, 0xa186, 0x0027, 0x0120, 0xa186, 0x0014, 0x190c, 0x14f6,
+       0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005, 0x90be,
+       0x90c0, 0x90c0, 0x90be, 0x90be, 0x90be, 0x90be, 0x080c, 0x14f6,
+       0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005, 0xa186,
+       0x0013, 0x1128, 0x6004, 0xa082, 0x0085, 0x2008, 0x04a8, 0xa186,
+       0x0027, 0x11e8, 0x080c, 0x6b73, 0x080c, 0x2ad9, 0x00d6, 0x6010,
+       0x2068, 0x080c, 0x9596, 0x0150, 0x6837, 0x0103, 0x6847, 0x0000,
+       0x684b, 0x0029, 0x080c, 0x510c, 0x080c, 0x9742, 0x00de, 0x080c,
+       0x8078, 0x080c, 0x6c50, 0x0005, 0x080c, 0x80be, 0x0ce0, 0xa186,
+       0x0014, 0x1dd0, 0x080c, 0x6b73, 0x00d6, 0x6010, 0x2068, 0x080c,
+       0x9596, 0x0d60, 0x6837, 0x0103, 0x6847, 0x0000, 0x684b, 0x0006,
+       0x6850, 0xc0ec, 0x6852, 0x08f0, 0x0002, 0x910e, 0x910c, 0x910c,
+       0x910c, 0x910c, 0x910c, 0x9126, 0x080c, 0x14f6, 0x080c, 0x6b73,
+       0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0118, 0xa186,
+       0x0035, 0x1118, 0x2001, 0xafa3, 0x0010, 0x2001, 0xafa4, 0x2004,
+       0x6016, 0x6003, 0x000c, 0x080c, 0x6c50, 0x0005, 0x080c, 0x6b73,
+       0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0118, 0xa186,
+       0x0035, 0x1118, 0x2001, 0xafa3, 0x0010, 0x2001, 0xafa4, 0x2004,
+       0x6016, 0x6003, 0x000e, 0x080c, 0x6c50, 0x0005, 0xa182, 0x008c,
+       0x1220, 0xa182, 0x0085, 0x0208, 0x001a, 0x080c, 0x80be, 0x0005,
+       0x914f, 0x914f, 0x914f, 0x914f, 0x9151, 0x91a4, 0x914f, 0x080c,
+       0x14f6, 0x00d6, 0x00f6, 0x2c78, 0x080c, 0x5029, 0x00fe, 0x0168,
+       0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0118, 0xa186,
+       0x0035, 0x1118, 0x00de, 0x0804, 0x91b7, 0x080c, 0x9742, 0x080c,
+       0x9596, 0x01c8, 0x6010, 0x2068, 0x6837, 0x0103, 0x6850, 0xd0b4,
+       0x0128, 0x684b, 0x0006, 0xc0ec, 0x6852, 0x0048, 0xd0bc, 0x0118,
+       0x684b, 0x0002, 0x0020, 0x684b, 0x0005, 0x080c, 0x9803, 0x6847,
+       0x0000, 0x080c, 0x510c, 0x2c68, 0x080c, 0x8022, 0x01c0, 0x6003,
+       0x0001, 0x6007, 0x001e, 0x600b, 0xffff, 0x2009, 0xb28e, 0x210c,
+       0x6136, 0x2009, 0xb28f, 0x210c, 0x613a, 0x6918, 0x611a, 0x080c,
+       0x9956, 0x6950, 0x6152, 0x601f, 0x0001, 0x080c, 0x67a8, 0x2d60,
+       0x080c, 0x8078, 0x00de, 0x0005, 0x00f6, 0x2c78, 0x080c, 0x5029,
+       0x00fe, 0x0598, 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0035,
+       0x0130, 0xa186, 0x001e, 0x0118, 0xa186, 0x0039, 0x1530, 0x00d6,
+       0x2c68, 0x080c, 0x9a34, 0x1904, 0x91fc, 0x080c, 0x8022, 0x01d8,
+       0x6106, 0x6003, 0x0001, 0x601f, 0x0001, 0x6918, 0x611a, 0x6928,
+       0x612a, 0x692c, 0x612e, 0x6930, 0xa18c, 0x00ff, 0x6132, 0x6934,
+       0x6136, 0x6938, 0x613a, 0x6950, 0x6152, 0x080c, 0x9956, 0x080c,
+       0x67a8, 0x080c, 0x6c50, 0x2d60, 0x00f8, 0x00d6, 0x6010, 0x2068,
+       0x080c, 0x9596, 0x01c8, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0128,
+       0xc0ec, 0x6852, 0x684b, 0x0006, 0x0048, 0xd0bc, 0x0118, 0x684b,
+       0x0002, 0x0020, 0x684b, 0x0005, 0x080c, 0x9803, 0x6847, 0x0000,
+       0x080c, 0x510c, 0x080c, 0x9742, 0x00de, 0x080c, 0x8078, 0x0005,
+       0x0016, 0x00d6, 0x6010, 0x2068, 0x080c, 0x9596, 0x0140, 0x6837,
+       0x0103, 0x684b, 0x0028, 0x6847, 0x0000, 0x080c, 0x510c, 0x00de,
+       0x001e, 0xa186, 0x0013, 0x0148, 0xa186, 0x0014, 0x0130, 0xa186,
+       0x0027, 0x0118, 0x080c, 0x80be, 0x0030, 0x080c, 0x6b73, 0x080c,
+       0x974e, 0x080c, 0x6c50, 0x0005, 0x0056, 0x0066, 0x00d6, 0x00f6,
+       0x2029, 0x0001, 0xa182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100,
+       0x2130, 0x2069, 0xb298, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020,
+       0xaf90, 0x001d, 0x080c, 0x927f, 0xa6b2, 0x0020, 0x7804, 0xa06d,
+       0x0110, 0x080c, 0x1600, 0x080c, 0x15d9, 0x0500, 0x8528, 0x6837,
+       0x0110, 0x683b, 0x0000, 0x2d20, 0x7c06, 0xa68a, 0x003d, 0x1228,
+       0x2608, 0xad90, 0x000f, 0x0459, 0x0088, 0xa6b2, 0x003c, 0x2009,
+       0x003c, 0x2d78, 0xad90, 0x000f, 0x0411, 0x0c28, 0x00fe, 0x852f,
+       0xa5ad, 0x0003, 0x7d36, 0xa5ac, 0x0000, 0x0028, 0x00fe, 0x852f,
+       0xa5ad, 0x0003, 0x7d36, 0x00de, 0x006e, 0x005e, 0x0005, 0x00f6,
+       0x8dff, 0x0158, 0x6804, 0xa07d, 0x0130, 0x6807, 0x0000, 0x080c,
+       0x510c, 0x2f68, 0x0cb8, 0x080c, 0x510c, 0x00fe, 0x0005, 0x0156,
+       0xa184, 0x0001, 0x0108, 0x8108, 0x810c, 0x21a8, 0x2304, 0x8007,
+       0x2012, 0x8318, 0x8210, 0x1f04, 0x9286, 0x015e, 0x0005, 0x0066,
+       0x0126, 0x2091, 0x8000, 0x2031, 0x0001, 0x601c, 0xa084, 0x000f,
+       0x0083, 0x012e, 0x006e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0066,
+       0x2031, 0x0000, 0x601c, 0xa084, 0x000f, 0x001b, 0x006e, 0x012e,
+       0x0005, 0x92c3, 0x92c3, 0x92be, 0x92e5, 0x92b1, 0x92be, 0x92e5,
+       0x92be, 0x080c, 0x14f6, 0x0036, 0x2019, 0x0010, 0x080c, 0xa566,
+       0x601f, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0xa006, 0x0005,
+       0xa085, 0x0001, 0x0005, 0x00d6, 0x86ff, 0x11d8, 0x6010, 0x2068,
+       0x080c, 0x9596, 0x01c0, 0x6834, 0xa086, 0x0139, 0x1128, 0x684b,
+       0x0005, 0x6853, 0x0000, 0x0028, 0xa00e, 0x2001, 0x0005, 0x080c,
+       0x51df, 0x080c, 0x9803, 0x080c, 0x510c, 0x080c, 0x8078, 0xa085,
+       0x0001, 0x00de, 0x0005, 0xa006, 0x0ce0, 0x6000, 0xa08a, 0x0010,
+       0x1a0c, 0x14f6, 0x000b, 0x0005, 0x92fc, 0x9319, 0x92fe, 0x9338,
+       0x9316, 0x92fc, 0x92be, 0x92c3, 0x92c3, 0x92be, 0x92be, 0x92be,
+       0x92be, 0x92be, 0x92be, 0x92be, 0x080c, 0x14f6, 0x86ff, 0x1198,
+       0x00d6, 0x6010, 0x2068, 0x080c, 0x9596, 0x0110, 0x080c, 0x9803,
+       0x00de, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c,
+       0x67a8, 0x080c, 0x6c50, 0xa085, 0x0001, 0x0005, 0x080c, 0x190b,
+       0x0c28, 0x00e6, 0x2071, 0xafc7, 0x7024, 0xac06, 0x1110, 0x080c,
+       0x79e1, 0x601c, 0xa084, 0x000f, 0xa086, 0x0006, 0x1150, 0x0086,
+       0x0096, 0x2049, 0x0001, 0x2c40, 0x080c, 0x7b9a, 0x009e, 0x008e,
+       0x0010, 0x080c, 0x78de, 0x00ee, 0x1948, 0x080c, 0x92be, 0x0005,
+       0x0036, 0x00e6, 0x2071, 0xafc7, 0x703c, 0xac06, 0x1140, 0x2019,
+       0x0000, 0x080c, 0x7a64, 0x00ee, 0x003e, 0x0804, 0x92fe, 0x080c,
+       0x7cb8, 0x00ee, 0x003e, 0x1904, 0x92fe, 0x080c, 0x92be, 0x0005,
+       0x00c6, 0x601c, 0xa084, 0x000f, 0x0013, 0x00ce, 0x0005, 0x9369,
+       0x93d3, 0x9501, 0x9374, 0x974e, 0x9369, 0xa558, 0x8078, 0x93d3,
+       0x9362, 0x955f, 0x080c, 0x14f6, 0x080c, 0x9789, 0x1110, 0x080c,
+       0x85f3, 0x0005, 0x080c, 0x6b73, 0x080c, 0x6c50, 0x080c, 0x8078,
+       0x0005, 0x6017, 0x0001, 0x0005, 0x6010, 0xa080, 0x0019, 0x2c02,
+       0x6000, 0xa08a, 0x0010, 0x1a0c, 0x14f6, 0x000b, 0x0005, 0x938f,
+       0x9391, 0x93b1, 0x93c3, 0x93d0, 0x938f, 0x9369, 0x9369, 0x9369,
+       0x93c3, 0x93c3, 0x938f, 0x938f, 0x938f, 0x938f, 0x93cd, 0x080c,
+       0x14f6, 0x00e6, 0x6010, 0x2070, 0x7050, 0xc0b5, 0x7052, 0x2071,
+       0xafc7, 0x7024, 0xac06, 0x0190, 0x080c, 0x78de, 0x6007, 0x0085,
+       0x6003, 0x000b, 0x601f, 0x0002, 0x2001, 0xafa4, 0x2004, 0x6016,
+       0x080c, 0x67a8, 0x080c, 0x6c50, 0x00ee, 0x0005, 0x6017, 0x0001,
+       0x0cd8, 0x00d6, 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852, 0x00de,
+       0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c, 0x67a8,
+       0x080c, 0x6c50, 0x0005, 0x00d6, 0x6017, 0x0001, 0x6010, 0x2068,
+       0x6850, 0xc0b5, 0x6852, 0x00de, 0x0005, 0x080c, 0x8078, 0x0005,
+       0x080c, 0x190b, 0x08f0, 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x14f6,
+       0x000b, 0x0005, 0x93ea, 0x9371, 0x93ec, 0x93ea, 0x93ec, 0x93ec,
+       0x936a, 0x93ea, 0x9364, 0x9364, 0x93ea, 0x93ea, 0x93ea, 0x93ea,
+       0x93ea, 0x93ea, 0x080c, 0x14f6, 0x00d6, 0x6018, 0x2068, 0x6804,
+       0xa084, 0x00ff, 0x00de, 0xa08a, 0x000c, 0x1a0c, 0x14f6, 0x000b,
+       0x0005, 0x9405, 0x94a7, 0x9407, 0x9441, 0x9407, 0x9441, 0x9407,
+       0x9411, 0x9405, 0x9441, 0x9405, 0x942d, 0x080c, 0x14f6, 0x6004,
+       0xa08e, 0x0016, 0x0588, 0xa08e, 0x0004, 0x0570, 0xa08e, 0x0002,
+       0x0558, 0x6004, 0x080c, 0x9789, 0x0904, 0x94c0, 0xa08e, 0x0021,
+       0x0904, 0x94c4, 0xa08e, 0x0022, 0x0904, 0x94c0, 0xa08e, 0x003d,
+       0x0904, 0x94c4, 0xa08e, 0x0039, 0x0904, 0x94c8, 0xa08e, 0x0035,
+       0x0904, 0x94c8, 0xa08e, 0x001e, 0x0188, 0xa08e, 0x0001, 0x1150,
+       0x00d6, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x00de, 0xa086,
+       0x0006, 0x0110, 0x080c, 0x2ad9, 0x080c, 0x85f3, 0x080c, 0x974e,
+       0x0005, 0x00c6, 0x00d6, 0x6104, 0xa186, 0x0016, 0x0904, 0x9498,
+       0xa186, 0x0002, 0x1518, 0x6018, 0x2068, 0x2001, 0xad34, 0x2004,
+       0xd0ac, 0x1904, 0x94ea, 0x68a0, 0xd0bc, 0x1904, 0x94ea, 0x6840,
+       0xa084, 0x00ff, 0xa005, 0x0190, 0x8001, 0x6842, 0x6013, 0x0000,
+       0x601f, 0x0007, 0x6017, 0x0398, 0x603f, 0x0000, 0x080c, 0x8022,
+       0x0128, 0x2d00, 0x601a, 0x601f, 0x0001, 0x0450, 0x00de, 0x00ce,
+       0x6004, 0xa08e, 0x0002, 0x11a8, 0x6018, 0xa080, 0x0028, 0x2004,
+       0xa086, 0x007e, 0x1170, 0x2009, 0xad34, 0x2104, 0xc085, 0x200a,
+       0x00e6, 0x2071, 0xad00, 0x080c, 0x48f5, 0x00ee, 0x080c, 0x85f3,
+       0x0020, 0x080c, 0x85f3, 0x080c, 0x2ad9, 0x00e6, 0x0126, 0x2091,
+       0x8000, 0x080c, 0x2aff, 0x012e, 0x00ee, 0x080c, 0x974e, 0x0005,
+       0x2001, 0x0002, 0x080c, 0x4c30, 0x6003, 0x0001, 0x6007, 0x0002,
+       0x080c, 0x67ee, 0x080c, 0x6c50, 0x00de, 0x00ce, 0x0c80, 0x00c6,
+       0x00d6, 0x6104, 0xa186, 0x0016, 0x0d58, 0x6018, 0x2068, 0x6840,
+       0xa084, 0x00ff, 0xa005, 0x0904, 0x946e, 0x8001, 0x6842, 0x6003,
+       0x0001, 0x080c, 0x67ee, 0x080c, 0x6c50, 0x00de, 0x00ce, 0x08b8,
+       0x080c, 0x85f3, 0x0804, 0x943e, 0x080c, 0x8621, 0x0804, 0x943e,
+       0x00d6, 0x2c68, 0x6104, 0x080c, 0x9a34, 0x00de, 0x0118, 0x080c,
+       0x8078, 0x00b8, 0x6004, 0x8007, 0x6130, 0xa18c, 0x00ff, 0xa105,
+       0x6032, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x6038,
+       0x600a, 0x2001, 0xafa4, 0x2004, 0x6016, 0x080c, 0x67a8, 0x080c,
+       0x6c50, 0x0005, 0x00de, 0x00ce, 0x080c, 0x85f3, 0x080c, 0x2ad9,
+       0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x2aff, 0x6013, 0x0000,
+       0x601f, 0x0007, 0x6017, 0x0398, 0x603f, 0x0000, 0x012e, 0x00ee,
+       0x0005, 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x14f6, 0x000b, 0x0005,
+       0x9518, 0x9518, 0x9518, 0x9518, 0x9518, 0x9518, 0x9518, 0x9518,
+       0x9518, 0x9369, 0x9518, 0x9371, 0x951a, 0x9371, 0x9527, 0x9518,
+       0x080c, 0x14f6, 0x6004, 0xa086, 0x008b, 0x0148, 0x6007, 0x008b,
+       0x6003, 0x000d, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0005, 0x080c,
+       0x9742, 0x080c, 0x9596, 0x0580, 0x080c, 0x2ad9, 0x00d6, 0x080c,
+       0x9596, 0x0168, 0x6010, 0x2068, 0x6837, 0x0103, 0x684b, 0x0006,
+       0x6847, 0x0000, 0x6850, 0xc0ed, 0x6852, 0x080c, 0x510c, 0x2c68,
+       0x080c, 0x8022, 0x0150, 0x6818, 0x601a, 0x080c, 0x9956, 0x00c6,
+       0x2d60, 0x080c, 0x974e, 0x00ce, 0x0008, 0x2d60, 0x00de, 0x6013,
+       0x0000, 0x601f, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c,
+       0x67ee, 0x080c, 0x6c50, 0x0010, 0x080c, 0x974e, 0x0005, 0x6000,
+       0xa08a, 0x0010, 0x1a0c, 0x14f6, 0x000b, 0x0005, 0x9576, 0x9576,
+       0x9576, 0x9578, 0x9579, 0x9576, 0x9576, 0x9576, 0x9576, 0x9576,
+       0x9576, 0x9576, 0x9576, 0x9576, 0x9576, 0x9576, 0x080c, 0x14f6,
+       0x0005, 0x080c, 0x7cb8, 0x190c, 0x14f6, 0x6110, 0x2168, 0x684b,
+       0x0006, 0x080c, 0x510c, 0x080c, 0x8078, 0x0005, 0xa284, 0x0007,
+       0x1158, 0xa282, 0xb400, 0x0240, 0x2001, 0xad16, 0x2004, 0xa202,
+       0x1218, 0xa085, 0x0001, 0x0005, 0xa006, 0x0ce8, 0x0026, 0x6210,
+       0xa294, 0xf000, 0x002e, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0006,
+       0x0126, 0x2091, 0x8000, 0x2061, 0xb400, 0x2071, 0xad00, 0x7344,
+       0x7064, 0xa302, 0x12a8, 0x601c, 0xa206, 0x1160, 0x080c, 0x98e3,
+       0x0148, 0x080c, 0x9789, 0x1110, 0x080c, 0x85f3, 0x00c6, 0x080c,
+       0x8078, 0x00ce, 0xace0, 0x0018, 0x7058, 0xac02, 0x1208, 0x0c38,
+       0x012e, 0x000e, 0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6,
+       0x0016, 0xa188, 0xae34, 0x210c, 0x81ff, 0x0170, 0x2061, 0xb400,
+       0x2071, 0xad00, 0x0016, 0x080c, 0x8022, 0x001e, 0x0138, 0x611a,
+       0x080c, 0x2ad9, 0x080c, 0x8078, 0xa006, 0x0010, 0xa085, 0x0001,
+       0x001e, 0x00ce, 0x00ee, 0x0005, 0x00c6, 0x0056, 0x0126, 0x2091,
+       0x8000, 0x00c6, 0x080c, 0x8022, 0x005e, 0x0180, 0x6612, 0x651a,
+       0x080c, 0x9956, 0x601f, 0x0003, 0x2009, 0x004b, 0x080c, 0x80a7,
+       0xa085, 0x0001, 0x012e, 0x005e, 0x00ce, 0x0005, 0xa006, 0x0cd0,
+       0x00c6, 0x0056, 0x0126, 0x2091, 0x8000, 0x62a0, 0x00c6, 0x080c,
+       0x8022, 0x005e, 0x0508, 0x6013, 0x0000, 0x651a, 0x080c, 0x9956,
+       0x601f, 0x0003, 0x00c6, 0x2560, 0x080c, 0x4ecf, 0x00ce, 0x080c,
+       0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x2c08, 0x080c,
+       0xa712, 0x007e, 0x2009, 0x004c, 0x080c, 0x80a7, 0xa085, 0x0001,
+       0x012e, 0x005e, 0x00ce, 0x0005, 0xa006, 0x0cd0, 0x00f6, 0x00c6,
+       0x0046, 0x00c6, 0x080c, 0x8022, 0x2c78, 0x00ce, 0x0180, 0x7e12,
+       0x2c00, 0x781a, 0x781f, 0x0003, 0x2021, 0x0005, 0x080c, 0x9683,
+       0x2f60, 0x2009, 0x004d, 0x080c, 0x80a7, 0xa085, 0x0001, 0x004e,
+       0x00ce, 0x00fe, 0x0005, 0x00f6, 0x00c6, 0x0046, 0x00c6, 0x080c,
+       0x8022, 0x2c78, 0x00ce, 0x0178, 0x7e12, 0x2c00, 0x781a, 0x781f,
+       0x0003, 0x2021, 0x0005, 0x0439, 0x2f60, 0x2009, 0x004e, 0x080c,
+       0x80a7, 0xa085, 0x0001, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6,
+       0x00c6, 0x0046, 0x00c6, 0x080c, 0x8022, 0x2c78, 0x00ce, 0x0178,
+       0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003, 0x2021, 0x0004, 0x0059,
+       0x2f60, 0x2009, 0x0052, 0x080c, 0x80a7, 0xa085, 0x0001, 0x004e,
+       0x00ce, 0x00fe, 0x0005, 0x0096, 0x0076, 0x0126, 0x2091, 0x8000,
+       0x080c, 0x4e71, 0x0118, 0x2001, 0x9688, 0x0028, 0x080c, 0x4e43,
+       0x0158, 0x2001, 0x968e, 0x0006, 0xa00e, 0x2400, 0x080c, 0x51df,
+       0x080c, 0x510c, 0x000e, 0x0807, 0x2418, 0x080c, 0x6b15, 0x62a0,
+       0x0086, 0x2041, 0x0001, 0x2039, 0x0001, 0x2608, 0x080c, 0x6900,
+       0x008e, 0x080c, 0x681d, 0x2f08, 0x2648, 0x080c, 0xa712, 0x613c,
+       0x81ff, 0x090c, 0x69a9, 0x012e, 0x007e, 0x009e, 0x0005, 0x00c6,
+       0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0188,
+       0x660a, 0x611a, 0x080c, 0x9956, 0x601f, 0x0001, 0x2d00, 0x6012,
+       0x2009, 0x001f, 0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce,
+       0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6,
+       0x080c, 0x8022, 0x001e, 0x0188, 0x660a, 0x611a, 0x080c, 0x9956,
+       0x601f, 0x0008, 0x2d00, 0x6012, 0x2009, 0x0021, 0x080c, 0x80a7,
+       0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6,
+       0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0188,
+       0x660a, 0x611a, 0x080c, 0x9956, 0x601f, 0x0001, 0x2d00, 0x6012,
+       0x2009, 0x003d, 0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce,
+       0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6,
+       0x080c, 0x9807, 0x001e, 0x0180, 0x611a, 0x080c, 0x9956, 0x601f,
+       0x0001, 0x2d00, 0x6012, 0x2009, 0x0000, 0x080c, 0x80a7, 0xa085,
+       0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126,
+       0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0188, 0x660a,
+       0x611a, 0x080c, 0x9956, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009,
+       0x0044, 0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005,
+       0xa006, 0x0cd8, 0x0026, 0x00d6, 0x6218, 0x2268, 0x6a3c, 0x82ff,
+       0x0110, 0x8211, 0x6a3e, 0x00de, 0x002e, 0x0005, 0x0006, 0x6000,
+       0xa086, 0x0000, 0x0190, 0x6013, 0x0000, 0x601f, 0x0007, 0x2001,
+       0xafa3, 0x2004, 0x0006, 0xa082, 0x0051, 0x000e, 0x0208, 0x8004,
+       0x6016, 0x080c, 0xabb4, 0x603f, 0x0000, 0x000e, 0x0005, 0x0066,
+       0x00c6, 0x00d6, 0x2031, 0xad52, 0x2634, 0xd6e4, 0x0128, 0x6618,
+       0x2660, 0x6e48, 0x080c, 0x4dfc, 0x00de, 0x00ce, 0x006e, 0x0005,
+       0x0006, 0x0016, 0x6004, 0xa08e, 0x0002, 0x0140, 0xa08e, 0x0003,
+       0x0128, 0xa08e, 0x0004, 0x0110, 0xa085, 0x0001, 0x001e, 0x000e,
+       0x0005, 0x0006, 0x00d6, 0x6010, 0xa06d, 0x0148, 0x6834, 0xa086,
+       0x0139, 0x0138, 0x6838, 0xd0fc, 0x0110, 0xa006, 0x0010, 0xa085,
+       0x0001, 0x00de, 0x000e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000,
+       0x00c6, 0x080c, 0x8022, 0x001e, 0x0190, 0x611a, 0x080c, 0x9956,
+       0x601f, 0x0001, 0x2d00, 0x6012, 0x080c, 0x2ad9, 0x2009, 0x0028,
+       0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006,
+       0x0cd8, 0xa186, 0x0015, 0x1178, 0x2011, 0xad20, 0x2204, 0xa086,
+       0x0074, 0x1148, 0x080c, 0x8943, 0x6003, 0x0001, 0x6007, 0x0029,
+       0x080c, 0x67ee, 0x0020, 0x080c, 0x85f3, 0x080c, 0x8078, 0x0005,
+       0xa186, 0x0016, 0x1128, 0x2001, 0x0004, 0x080c, 0x4c30, 0x00e8,
+       0xa186, 0x0015, 0x11e8, 0x2011, 0xad20, 0x2204, 0xa086, 0x0014,
+       0x11b8, 0x00d6, 0x6018, 0x2068, 0x080c, 0x4d72, 0x00de, 0x080c,
+       0x89f7, 0x1170, 0x00d6, 0x6018, 0x2068, 0x6890, 0x00de, 0xa005,
+       0x0138, 0x2001, 0x0006, 0x080c, 0x4c30, 0x080c, 0x81f6, 0x0020,
+       0x080c, 0x85f3, 0x080c, 0x8078, 0x0005, 0x6848, 0xa086, 0x0005,
+       0x1108, 0x0009, 0x0005, 0x6850, 0xc0ad, 0x6852, 0x0005, 0x00e6,
+       0x0126, 0x2071, 0xad00, 0x2091, 0x8000, 0x7544, 0xa582, 0x0001,
+       0x0608, 0x7048, 0x2060, 0x6000, 0xa086, 0x0000, 0x0148, 0xace0,
+       0x0018, 0x7058, 0xac02, 0x1208, 0x0cb0, 0x2061, 0xb400, 0x0c98,
+       0x6003, 0x0008, 0x8529, 0x7546, 0xaca8, 0x0018, 0x7058, 0xa502,
+       0x1230, 0x754a, 0xa085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x704b,
+       0xb400, 0x0cc0, 0xa006, 0x0cc0, 0x00e6, 0x2071, 0xb28c, 0x7014,
+       0xd0e4, 0x0150, 0x6013, 0x0000, 0x6003, 0x0001, 0x6007, 0x0050,
+       0x080c, 0x67a8, 0x080c, 0x6c50, 0x00ee, 0x0005, 0x00c6, 0x00f6,
+       0x2c78, 0x080c, 0x5029, 0x00fe, 0x0120, 0x601c, 0xa084, 0x000f,
+       0x0013, 0x00ce, 0x0005, 0x9369, 0x985e, 0x9861, 0x9864, 0xa9a7,
+       0xa9c2, 0xa9c5, 0x9369, 0x9369, 0x080c, 0x14f6, 0xe000, 0xe000,
+       0x0005, 0xe000, 0xe000, 0x0005, 0x0009, 0x0005, 0x00f6, 0x2c78,
+       0x080c, 0x5029, 0x0538, 0x080c, 0x8022, 0x1128, 0x2001, 0xafa5,
+       0x2004, 0x783e, 0x00f8, 0x7818, 0x601a, 0x080c, 0x9956, 0x781c,
+       0xa086, 0x0003, 0x0128, 0x7808, 0x6036, 0x2f00, 0x603a, 0x0020,
+       0x7808, 0x603a, 0x2f00, 0x6036, 0x602a, 0x601f, 0x0001, 0x6007,
+       0x0035, 0x6003, 0x0001, 0x7950, 0x6152, 0x080c, 0x67a8, 0x080c,
+       0x6c50, 0x2f60, 0x00fe, 0x0005, 0x0016, 0x00f6, 0x682c, 0x6032,
+       0xa08e, 0x0001, 0x0138, 0xa086, 0x0005, 0x0140, 0xa006, 0x602a,
+       0x602e, 0x00a0, 0x6820, 0xc0f4, 0xc0d5, 0x6822, 0x6810, 0x2078,
+       0x787c, 0x6938, 0xa102, 0x7880, 0x6934, 0xa103, 0x1e78, 0x6834,
+       0x602a, 0x6838, 0xa084, 0xfffc, 0x683a, 0x602e, 0x2d00, 0x6036,
+       0x6808, 0x603a, 0x6918, 0x611a, 0x6950, 0x6152, 0x601f, 0x0001,
+       0x6007, 0x0039, 0x6003, 0x0001, 0x080c, 0x67a8, 0x6803, 0x0002,
+       0x00fe, 0x001e, 0x0005, 0x00f6, 0x2c78, 0x080c, 0x5029, 0x1118,
+       0xa085, 0x0001, 0x0070, 0x6020, 0xd0f4, 0x1150, 0xc0f5, 0x6022,
+       0x6010, 0x2078, 0x7828, 0x603a, 0x782c, 0x6036, 0x080c, 0x190b,
+       0xa006, 0x00fe, 0x0005, 0x0006, 0x0016, 0x6004, 0xa08e, 0x0034,
+       0x01b8, 0xa08e, 0x0035, 0x01a0, 0xa08e, 0x0036, 0x0188, 0xa08e,
+       0x0037, 0x0170, 0xa08e, 0x0038, 0x0158, 0xa08e, 0x0039, 0x0140,
+       0xa08e, 0x003a, 0x0128, 0xa08e, 0x003b, 0x0110, 0xa085, 0x0001,
+       0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6,
+       0x2001, 0xaf9f, 0x200c, 0x8000, 0x2014, 0x2001, 0x0032, 0x080c,
+       0x6665, 0x2001, 0xafa3, 0x82ff, 0x1110, 0x2011, 0x0002, 0x2202,
+       0x2001, 0xafa1, 0x200c, 0x8000, 0x2014, 0x2071, 0xaf8d, 0x711a,
+       0x721e, 0x2001, 0x0064, 0x080c, 0x6665, 0x2001, 0xafa4, 0x82ff,
+       0x1110, 0x2011, 0x0002, 0x2202, 0x2009, 0xafa5, 0xa280, 0x000a,
+       0x200a, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x0006,
+       0x00e6, 0x2001, 0xafa3, 0x2003, 0x0028, 0x2001, 0xafa4, 0x2003,
+       0x0014, 0x2071, 0xaf8d, 0x701b, 0x0000, 0x701f, 0x07d0, 0x2001,
+       0xafa5, 0x2003, 0x001e, 0x00ee, 0x000e, 0x0005, 0x00d6, 0x6054,
+       0xa06d, 0x0110, 0x080c, 0x15f0, 0x00de, 0x0005, 0x0005, 0x00c6,
+       0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0178,
+       0x611a, 0x0ca1, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0033,
+       0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006,
+       0x0cd8, 0x00d6, 0x00e6, 0x00f6, 0x2071, 0xad00, 0xa186, 0x0015,
+       0x1500, 0x7080, 0xa086, 0x0018, 0x11e0, 0x6010, 0x2068, 0x6a3c,
+       0xd2e4, 0x1160, 0x2c78, 0x080c, 0x6e05, 0x01d8, 0x706c, 0x6a50,
+       0xa206, 0x1160, 0x7070, 0x6a54, 0xa206, 0x1140, 0x6218, 0xa290,
+       0x0028, 0x2214, 0x2009, 0x0000, 0x080c, 0x2b1e, 0x080c, 0x81f6,
+       0x0020, 0x080c, 0x85f3, 0x080c, 0x8078, 0x00fe, 0x00ee, 0x00de,
+       0x0005, 0x7050, 0x6a54, 0xa206, 0x0d48, 0x0c80, 0x00c6, 0x0126,
+       0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0180, 0x611a,
+       0x080c, 0x9956, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0043,
+       0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006,
+       0x0cd8, 0x00d6, 0x00e6, 0x00f6, 0x2071, 0xad00, 0xa186, 0x0015,
+       0x11c0, 0x7080, 0xa086, 0x0004, 0x11a0, 0x6010, 0xa0e8, 0x000f,
+       0x2c78, 0x080c, 0x6e05, 0x01a8, 0x706c, 0x6a08, 0xa206, 0x1130,
+       0x7070, 0x6a0c, 0xa206, 0x1110, 0x080c, 0x2ad9, 0x080c, 0x81f6,
+       0x0020, 0x080c, 0x85f3, 0x080c, 0x8078, 0x00fe, 0x00ee, 0x00de,
+       0x0005, 0x7050, 0x6a0c, 0xa206, 0x0d78, 0x0c80, 0x0016, 0x0026,
+       0x684c, 0xd0ac, 0x0178, 0x6914, 0x6a10, 0x2100, 0xa205, 0x0150,
+       0x6860, 0xa106, 0x1118, 0x685c, 0xa206, 0x0120, 0x6962, 0x6a5e,
+       0xa085, 0x0001, 0x002e, 0x001e, 0x0005, 0x00d6, 0x0036, 0x6310,
+       0x2368, 0x684a, 0x6952, 0xa29e, 0x4000, 0x1188, 0x00c6, 0x6318,
+       0x2360, 0x2009, 0x0000, 0x080c, 0x4f6e, 0x1108, 0xc185, 0x6000,
+       0xd0bc, 0x0108, 0xc18d, 0x6a66, 0x696a, 0x00ce, 0x0080, 0x6a66,
+       0x3918, 0xa398, 0x0006, 0x231c, 0x686b, 0x0004, 0x6b72, 0x00c6,
+       0x6318, 0x2360, 0x6004, 0xa084, 0x00ff, 0x686e, 0x00ce, 0x080c,
+       0x510c, 0x003e, 0x00de, 0x0005, 0x00c6, 0x0026, 0x0016, 0xa186,
+       0x0035, 0x0110, 0x6a34, 0x0008, 0x6a28, 0x080c, 0x9586, 0x01f0,
+       0x2260, 0x611c, 0xa186, 0x0003, 0x0118, 0xa186, 0x0006, 0x1190,
+       0x6834, 0xa206, 0x0140, 0x6838, 0xa206, 0x1160, 0x6108, 0x6834,
+       0xa106, 0x1140, 0x0020, 0x6008, 0x6938, 0xa106, 0x1118, 0x6018,
+       0x6918, 0xa106, 0x001e, 0x002e, 0x00ce, 0x0005, 0xa085, 0x0001,
+       0x0cc8, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x14f6, 0x0013,
+       0x006e, 0x0005, 0x9a7a, 0x9eff, 0xa027, 0x9a7a, 0x9a7a, 0x9a7a,
+       0x9a7a, 0x9a7a, 0x9ab2, 0xa0a3, 0x9a7a, 0x9a7a, 0x9a7a, 0x9a7a,
+       0x9a7a, 0x9a7a, 0x080c, 0x14f6, 0x0066, 0x6000, 0xa0b2, 0x0010,
+       0x1a0c, 0x14f6, 0x0013, 0x006e, 0x0005, 0x9a95, 0xa4fd, 0x9a95,
+       0x9a95, 0x9a95, 0x9a95, 0x9a95, 0x9a95, 0xa4c1, 0xa545, 0x9a95,
+       0xaaea, 0xab1a, 0xaaea, 0xab1a, 0x9a95, 0x080c, 0x14f6, 0x0066,
+       0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x14f6, 0x0013, 0x006e, 0x0005,
+       0x9ab0, 0xa1d8, 0xa295, 0xa2c2, 0xa346, 0x9ab0, 0xa433, 0xa3de,
+       0xa0af, 0xa497, 0xa4ac, 0x9ab0, 0x9ab0, 0x9ab0, 0x9ab0, 0x9ab0,
+       0x080c, 0x14f6, 0xa1b2, 0x0080, 0x1a0c, 0x14f6, 0x2100, 0xa1b2,
+       0x0040, 0x1a04, 0x9e79, 0x0002, 0x9afc, 0x9cab, 0x9afc, 0x9afc,
+       0x9afc, 0x9cb2, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc,
+       0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc,
+       0x9afc, 0x9afc, 0x9afc, 0x9afe, 0x9b5a, 0x9b65, 0x9ba6, 0x9bc0,
+       0x9c3e, 0x9c9c, 0x9afc, 0x9afc, 0x9cb5, 0x9afc, 0x9afc, 0x9cc4,
+       0x9ccb, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9d42, 0x9afc,
+       0x9afc, 0x9d4d, 0x9afc, 0x9afc, 0x9d18, 0x9afc, 0x9afc, 0x9afc,
+       0x9d61, 0x9afc, 0x9afc, 0x9afc, 0x9dd5, 0x9afc, 0x9afc, 0x9afc,
+       0x9afc, 0x9afc, 0x9afc, 0x9e40, 0x080c, 0x14f6, 0x080c, 0x502d,
+       0x1140, 0x2001, 0xad34, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008,
+       0x1140, 0x6007, 0x0009, 0x602b, 0x0009, 0x6013, 0x0000, 0x0804,
+       0x9ca6, 0x080c, 0x501d, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016,
+       0x6218, 0x2270, 0x72a0, 0x0026, 0x2019, 0x0029, 0x080c, 0x68e7,
+       0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x2c08, 0x080c, 0xa712,
+       0x007e, 0x001e, 0x2e60, 0x080c, 0x4ecf, 0x001e, 0x002e, 0x003e,
+       0x00ce, 0x00ee, 0x6618, 0x00c6, 0x2660, 0x080c, 0x4ceb, 0x00ce,
+       0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x0278,
+       0x080c, 0xa656, 0x1904, 0x9ba0, 0x080c, 0xa5f6, 0x1120, 0x6007,
+       0x0008, 0x0804, 0x9ca6, 0x6007, 0x0009, 0x0804, 0x9ca6, 0x080c,
+       0xa801, 0x0128, 0x080c, 0xa656, 0x0d78, 0x0804, 0x9ba0, 0x6013,
+       0x1900, 0x0c88, 0x6106, 0x080c, 0xa5a6, 0x6007, 0x0006, 0x0804,
+       0x9ca6, 0x6007, 0x0007, 0x0804, 0x9ca6, 0x080c, 0xab4e, 0x1904,
+       0x9e76, 0x00d6, 0x6618, 0x2668, 0x6e04, 0xa6b4, 0xff00, 0x8637,
+       0xa686, 0x0006, 0x0188, 0xa686, 0x0004, 0x0170, 0x6e04, 0xa6b4,
+       0x00ff, 0xa686, 0x0006, 0x0140, 0xa686, 0x0004, 0x0128, 0xa686,
+       0x0005, 0x0110, 0x00de, 0x00e0, 0x080c, 0xa6b4, 0x11a0, 0xa686,
+       0x0006, 0x1150, 0x0026, 0x6218, 0xa290, 0x0028, 0x2214, 0x2009,
+       0x0000, 0x080c, 0x2b1e, 0x002e, 0x080c, 0x4d72, 0x6007, 0x000a,
+       0x00de, 0x0804, 0x9ca6, 0x6007, 0x000b, 0x00de, 0x0804, 0x9ca6,
+       0x080c, 0x2ad9, 0x6007, 0x0001, 0x0804, 0x9ca6, 0x080c, 0xab4e,
+       0x1904, 0x9e76, 0x6618, 0x00d6, 0x2668, 0x6e04, 0x00de, 0xa686,
+       0x0707, 0x0d70, 0x0026, 0x6218, 0xa290, 0x0028, 0x2214, 0x2009,
+       0x0000, 0x080c, 0x2b1e, 0x002e, 0x6007, 0x000c, 0x0804, 0x9ca6,
+       0x080c, 0x502d, 0x1140, 0x2001, 0xad34, 0x2004, 0xa084, 0x0009,
+       0xa086, 0x0008, 0x1110, 0x0804, 0x9b09, 0x080c, 0x501d, 0x6618,
+       0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x06e8,
+       0x1138, 0x0026, 0x2001, 0x0006, 0x080c, 0x4c5d, 0x002e, 0x0050,
+       0xa6b4, 0xff00, 0x8637, 0xa686, 0x0004, 0x0120, 0xa686, 0x0006,
+       0x1904, 0x9ba0, 0x080c, 0xa6c1, 0x1120, 0x6007, 0x000e, 0x0804,
+       0x9ca6, 0x0046, 0x6418, 0xa4a0, 0x0028, 0x2424, 0xa4a4, 0x00ff,
+       0x8427, 0x0046, 0x080c, 0x2ad9, 0x004e, 0x0016, 0xa006, 0x2009,
+       0xad52, 0x210c, 0xd1a4, 0x0158, 0x2009, 0x0029, 0x080c, 0xa96c,
+       0x6018, 0x00d6, 0x2068, 0x6800, 0xc0e5, 0x6802, 0x00de, 0x001e,
+       0x004e, 0x6007, 0x0001, 0x0804, 0x9ca6, 0x2001, 0x0001, 0x080c,
+       0x4c1e, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019,
+       0xad05, 0x2011, 0xb290, 0x080c, 0x8a7c, 0x003e, 0x002e, 0x001e,
+       0x015e, 0xa005, 0x0168, 0xa6b4, 0xff00, 0x8637, 0xa682, 0x0004,
+       0x0a04, 0x9ba0, 0xa682, 0x0007, 0x0a04, 0x9bea, 0x0804, 0x9ba0,
+       0x6013, 0x1900, 0x6007, 0x0009, 0x0804, 0x9ca6, 0x080c, 0x502d,
+       0x1140, 0x2001, 0xad34, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008,
+       0x1110, 0x0804, 0x9b09, 0x080c, 0x501d, 0x6618, 0xa6b0, 0x0001,
+       0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x06b0, 0xa6b4, 0xff00,
+       0x8637, 0xa686, 0x0004, 0x0120, 0xa686, 0x0006, 0x1904, 0x9ba0,
+       0x080c, 0xa6e9, 0x1130, 0x080c, 0xa5f6, 0x1118, 0x6007, 0x0010,
+       0x04e8, 0x0046, 0x6418, 0xa4a0, 0x0028, 0x2424, 0xa4a4, 0x00ff,
+       0x8427, 0x0046, 0x080c, 0x2ad9, 0x004e, 0x0016, 0xa006, 0x2009,
+       0xad52, 0x210c, 0xd1a4, 0x0158, 0x2009, 0x0029, 0x080c, 0xa96c,
+       0x6018, 0x00d6, 0x2068, 0x6800, 0xc0e5, 0x6802, 0x00de, 0x001e,
+       0x004e, 0x6007, 0x0001, 0x00d0, 0x080c, 0xa801, 0x0140, 0xa6b4,
+       0xff00, 0x8637, 0xa686, 0x0006, 0x0958, 0x0804, 0x9ba0, 0x6013,
+       0x1900, 0x6007, 0x0009, 0x0050, 0x080c, 0xab4e, 0x1904, 0x9e76,
+       0x080c, 0x9e98, 0x1904, 0x9ba0, 0x6007, 0x0012, 0x6003, 0x0001,
+       0x080c, 0x67ee, 0x0005, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c,
+       0x67ee, 0x0cc0, 0x6007, 0x0005, 0x0cc0, 0x080c, 0xab4e, 0x1904,
+       0x9e76, 0x080c, 0x9e98, 0x1904, 0x9ba0, 0x6007, 0x0020, 0x6003,
+       0x0001, 0x080c, 0x67ee, 0x0005, 0x6007, 0x0023, 0x6003, 0x0001,
+       0x080c, 0x67ee, 0x0005, 0x080c, 0xab4e, 0x1904, 0x9e76, 0x080c,
+       0x9e98, 0x1904, 0x9ba0, 0x0016, 0x0026, 0x2011, 0xb291, 0x2214,
+       0xa286, 0xffff, 0x0190, 0x2c08, 0x080c, 0x9586, 0x01d8, 0x2260,
+       0x2011, 0xb290, 0x2214, 0x6008, 0xa206, 0x11a0, 0x6018, 0xa190,
+       0x0006, 0x2214, 0xa206, 0x01e0, 0x0068, 0x2011, 0xb290, 0x2214,
+       0x2c08, 0x080c, 0xa940, 0x11a0, 0x2011, 0xb291, 0x2214, 0xa286,
+       0xffff, 0x01a0, 0x2160, 0x6007, 0x0026, 0x6013, 0x1700, 0x2011,
+       0xb289, 0x2214, 0xa296, 0xffff, 0x1160, 0x6007, 0x0025, 0x0048,
+       0x601c, 0xa086, 0x0007, 0x1d70, 0x080c, 0x8078, 0x2160, 0x6007,
+       0x0025, 0x6003, 0x0001, 0x080c, 0x67ee, 0x002e, 0x001e, 0x0005,
+       0x2001, 0x0001, 0x080c, 0x4c1e, 0x0156, 0x0016, 0x0026, 0x0036,
+       0x20a9, 0x0004, 0x2019, 0xad05, 0x2011, 0xb296, 0x080c, 0x8a7c,
+       0x003e, 0x002e, 0x001e, 0x015e, 0x0120, 0x6007, 0x0031, 0x0804,
+       0x9ca6, 0x080c, 0x87bd, 0x080c, 0x574f, 0x1158, 0x0006, 0x0026,
+       0x0036, 0x080c, 0x576b, 0x0110, 0x080c, 0x5726, 0x003e, 0x002e,
+       0x000e, 0x0005, 0x6106, 0x080c, 0x9eb4, 0x6007, 0x002b, 0x0804,
+       0x9ca6, 0x6007, 0x002c, 0x0804, 0x9ca6, 0x080c, 0xab4e, 0x1904,
+       0x9e76, 0x080c, 0x9e98, 0x1904, 0x9ba0, 0x6106, 0x080c, 0x9eb8,
+       0x1120, 0x6007, 0x002e, 0x0804, 0x9ca6, 0x6007, 0x002f, 0x0804,
+       0x9ca6, 0x00e6, 0x00d6, 0x00c6, 0x6018, 0xa080, 0x0001, 0x200c,
+       0xa184, 0x00ff, 0xa086, 0x0006, 0x0158, 0xa184, 0xff00, 0x8007,
+       0xa086, 0x0006, 0x0128, 0x00ce, 0x00de, 0x00ee, 0x0804, 0x9cab,
+       0x2001, 0xad71, 0x2004, 0xd0e4, 0x0904, 0x9dd2, 0x2071, 0xb28c,
+       0x7010, 0x6036, 0x7014, 0x603a, 0x7108, 0x720c, 0x2001, 0xad52,
+       0x2004, 0xd0a4, 0x0140, 0x6018, 0x2068, 0x6810, 0xa106, 0x1118,
+       0x6814, 0xa206, 0x01f8, 0x2001, 0xad52, 0x2004, 0xd0ac, 0x1580,
+       0x2069, 0xad00, 0x6870, 0xa206, 0x1558, 0x686c, 0xa106, 0x1540,
+       0x7210, 0x080c, 0x9586, 0x0548, 0x080c, 0xa9d4, 0x0530, 0x622a,
+       0x6007, 0x0036, 0x6003, 0x0001, 0x080c, 0x67a8, 0x00ce, 0x00de,
+       0x00ee, 0x0005, 0x7214, 0xa286, 0xffff, 0x0150, 0x080c, 0x9586,
+       0x01a0, 0xa280, 0x0002, 0x2004, 0x7110, 0xa106, 0x1170, 0x0c08,
+       0x7210, 0x2c08, 0x080c, 0xa940, 0x2c10, 0x2160, 0x0130, 0x08c8,
+       0x6007, 0x0037, 0x6013, 0x1500, 0x08e8, 0x6007, 0x0037, 0x6013,
+       0x1700, 0x08c0, 0x6007, 0x0012, 0x08a8, 0x6018, 0xa080, 0x0001,
+       0x2004, 0xa084, 0xff00, 0x8007, 0xa086, 0x0006, 0x1904, 0x9cab,
+       0x00e6, 0x00d6, 0x00c6, 0x2001, 0xad71, 0x2004, 0xd0e4, 0x0904,
+       0x9e38, 0x2069, 0xad00, 0x2071, 0xb28c, 0x7008, 0x6036, 0x720c,
+       0x623a, 0xa286, 0xffff, 0x1140, 0x7208, 0x00c6, 0x2c08, 0x080c,
+       0xa940, 0x2c10, 0x00ce, 0x0588, 0x080c, 0x9586, 0x0570, 0x00c6,
+       0x0026, 0x2260, 0x080c, 0x928f, 0x002e, 0x00ce, 0x7118, 0xa18c,
+       0xff00, 0x810f, 0xa186, 0x0001, 0x0158, 0xa186, 0x0005, 0x0118,
+       0xa186, 0x0007, 0x1178, 0xa280, 0x0004, 0x2004, 0xa005, 0x0150,
+       0x0056, 0x7510, 0x7614, 0x080c, 0xa9eb, 0x005e, 0x00ce, 0x00de,
+       0x00ee, 0x0005, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013, 0x2a00,
+       0x6003, 0x0001, 0x080c, 0x67a8, 0x0c88, 0x6007, 0x003b, 0x602b,
+       0x0009, 0x6013, 0x1700, 0x6003, 0x0001, 0x080c, 0x67a8, 0x0c30,
+       0x6007, 0x003b, 0x602b, 0x000b, 0x6013, 0x0000, 0x0804, 0x9daa,
+       0x00e6, 0x0026, 0x080c, 0x502d, 0x0558, 0x080c, 0x501d, 0x080c,
+       0xabc5, 0x1520, 0x2071, 0xad00, 0x70d0, 0xc085, 0x70d2, 0x00f6,
+       0x2079, 0x0100, 0x729c, 0xa284, 0x00ff, 0x706e, 0x78e6, 0xa284,
+       0xff00, 0x7270, 0xa205, 0x7072, 0x78ea, 0x00fe, 0x70db, 0x0000,
+       0x2001, 0xad52, 0x2004, 0xd0a4, 0x0120, 0x2011, 0xafe0, 0x2013,
+       0x07d0, 0xd0ac, 0x1128, 0x080c, 0x28fa, 0x0010, 0x080c, 0xabf1,
+       0x002e, 0x00ee, 0x080c, 0x8078, 0x0804, 0x9caa, 0x080c, 0x8078,
+       0x0005, 0x2600, 0x0002, 0x9e81, 0x9e81, 0x9e81, 0x9e81, 0x9e81,
+       0x9e83, 0x080c, 0x14f6, 0x080c, 0xab4e, 0x1d80, 0x0089, 0x1138,
+       0x6007, 0x0045, 0x6003, 0x0001, 0x080c, 0x67ee, 0x0005, 0x080c,
+       0x2ad9, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x67ee, 0x0005,
+       0x00d6, 0x0066, 0x6618, 0x2668, 0x6e04, 0xa6b4, 0xff00, 0x8637,
+       0xa686, 0x0006, 0x0170, 0xa686, 0x0004, 0x0158, 0x6e04, 0xa6b4,
+       0x00ff, 0xa686, 0x0006, 0x0128, 0xa686, 0x0004, 0x0110, 0xa085,
+       0x0001, 0x006e, 0x00de, 0x0005, 0x00d6, 0x0449, 0x00de, 0x0005,
+       0x00d6, 0x0491, 0x11f0, 0x680c, 0xa08c, 0xff00, 0x6820, 0xa084,
+       0x00ff, 0xa115, 0x6212, 0x6824, 0x602a, 0xd1e4, 0x0118, 0x2009,
+       0x0001, 0x0060, 0xd1ec, 0x0168, 0x6920, 0xa18c, 0x00ff, 0x6824,
+       0x080c, 0x2676, 0x1130, 0x2110, 0x2009, 0x0000, 0x080c, 0x2b1e,
+       0x0018, 0xa085, 0x0001, 0x0008, 0xa006, 0x00de, 0x0005, 0x2069,
+       0xb28d, 0x6800, 0xa082, 0x0010, 0x1228, 0x6013, 0x0000, 0xa085,
+       0x0001, 0x0008, 0xa006, 0x0005, 0x6013, 0x0000, 0x2069, 0xb28c,
+       0x6808, 0xa084, 0xff00, 0xa086, 0x0800, 0x1140, 0x6800, 0xa084,
+       0x00ff, 0xa08e, 0x0014, 0x0110, 0xa08e, 0x0010, 0x0005, 0x6004,
+       0xa0b2, 0x0080, 0x1a0c, 0x14f6, 0xa1b6, 0x0013, 0x1130, 0x2008,
+       0xa1b2, 0x0040, 0x1a04, 0x9ffb, 0x0092, 0xa1b6, 0x0027, 0x0120,
+       0xa1b6, 0x0014, 0x190c, 0x14f6, 0x2001, 0x0007, 0x080c, 0x4c5d,
+       0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005, 0x9f5f,
+       0x9f61, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f61, 0x9f6f, 0x9ff4, 0x9fbf,
+       0x9ff4, 0x9fd0, 0x9ff4, 0x9f6f, 0x9ff4, 0x9fec, 0x9ff4, 0x9fec,
+       0x9ff4, 0x9ff4, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f,
+       0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f61, 0x9f5f, 0x9ff4,
+       0x9f5f, 0x9f5f, 0x9ff4, 0x9f5f, 0x9ff1, 0x9ff4, 0x9f5f, 0x9f5f,
+       0x9f5f, 0x9f5f, 0x9ff4, 0x9ff4, 0x9f5f, 0x9ff4, 0x9ff4, 0x9f5f,
+       0x9f69, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9ff0, 0x9ff4, 0x9f5f,
+       0x9f5f, 0x9ff4, 0x9ff4, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x080c,
+       0x14f6, 0x080c, 0x6b73, 0x6003, 0x0002, 0x080c, 0x6c50, 0x0804,
+       0x9ffa, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x0804, 0x9ff4, 0x00f6,
+       0x2079, 0xad51, 0x7804, 0x00fe, 0xd0ac, 0x1904, 0x9ff4, 0x2001,
+       0x0000, 0x080c, 0x4c1e, 0x6018, 0xa080, 0x0004, 0x2004, 0xa086,
+       0x00ff, 0x1140, 0x00f6, 0x2079, 0xad00, 0x7894, 0x8000, 0x7896,
+       0x00fe, 0x00e0, 0x00c6, 0x6018, 0x2060, 0x6000, 0xd0f4, 0x1140,
+       0x6010, 0xa005, 0x0128, 0x00ce, 0x080c, 0x3cce, 0x0804, 0x9ff4,
+       0x00ce, 0x2001, 0xad00, 0x2004, 0xa086, 0x0002, 0x1138, 0x00f6,
+       0x2079, 0xad00, 0x7894, 0x8000, 0x7896, 0x00fe, 0x2001, 0x0002,
+       0x080c, 0x4c30, 0x080c, 0x6b73, 0x601f, 0x0001, 0x6003, 0x0001,
+       0x6007, 0x0002, 0x080c, 0x67ee, 0x080c, 0x6c50, 0x00c6, 0x6118,
+       0x2160, 0x2009, 0x0001, 0x080c, 0x6519, 0x00ce, 0x04d8, 0x6618,
+       0x00d6, 0x2668, 0x6e04, 0x00de, 0xa6b4, 0xff00, 0x8637, 0xa686,
+       0x0006, 0x0550, 0xa686, 0x0004, 0x0538, 0x2001, 0x0004, 0x0410,
+       0x2001, 0xad00, 0x2004, 0xa086, 0x0003, 0x1110, 0x080c, 0x3cce,
+       0x2001, 0x0006, 0x0489, 0x6618, 0x00d6, 0x2668, 0x6e04, 0x00de,
+       0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0170, 0x2001, 0x0006,
+       0x0048, 0x2001, 0x0004, 0x0030, 0x2001, 0x0006, 0x00e9, 0x0020,
+       0x0018, 0x0010, 0x080c, 0x4c5d, 0x080c, 0x6b73, 0x080c, 0x8078,
+       0x080c, 0x6c50, 0x0005, 0x2600, 0x0002, 0xa003, 0xa003, 0xa003,
+       0xa003, 0xa003, 0xa005, 0x080c, 0x14f6, 0x080c, 0x6b73, 0x080c,
+       0x8078, 0x080c, 0x6c50, 0x0005, 0x0016, 0x00d6, 0x6118, 0x2168,
+       0x6900, 0xd184, 0x0188, 0x6104, 0xa18e, 0x000a, 0x1128, 0x699c,
+       0xd1a4, 0x1110, 0x2001, 0x0007, 0x080c, 0x4c30, 0x2001, 0x0000,
+       0x080c, 0x4c1e, 0x080c, 0x2aff, 0x00de, 0x001e, 0x0005, 0x00d6,
+       0x6618, 0x2668, 0x6804, 0xa084, 0xff00, 0x8007, 0x00de, 0xa0b2,
+       0x000c, 0x1a0c, 0x14f6, 0xa1b6, 0x0015, 0x1110, 0x003b, 0x0028,
+       0xa1b6, 0x0016, 0x190c, 0x14f6, 0x006b, 0x0005, 0x86b9, 0x86b9,
+       0x86b9, 0x86b9, 0x86b9, 0x86b9, 0xa08f, 0xa056, 0x86b9, 0x86b9,
+       0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x86b9,
+       0xa08f, 0xa096, 0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x00f6, 0x2079,
+       0xad51, 0x7804, 0xd0ac, 0x11e0, 0x6018, 0xa07d, 0x01c8, 0x7800,
+       0xd0f4, 0x1118, 0x7810, 0xa005, 0x1198, 0x2001, 0x0000, 0x080c,
+       0x4c1e, 0x2001, 0x0002, 0x080c, 0x4c30, 0x601f, 0x0001, 0x6003,
+       0x0001, 0x6007, 0x0002, 0x080c, 0x67ee, 0x080c, 0x6c50, 0x00a8,
+       0x2011, 0xb283, 0x2204, 0x8211, 0x220c, 0x080c, 0x2676, 0x1168,
+       0x00c6, 0x080c, 0x4cdc, 0x0120, 0x00ce, 0x080c, 0x8078, 0x0028,
+       0x080c, 0x493a, 0x00ce, 0x080c, 0x8078, 0x00fe, 0x0005, 0x6604,
+       0xa6b6, 0x001e, 0x1110, 0x080c, 0x8078, 0x0005, 0x080c, 0x8940,
+       0x1138, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x67ee, 0x0010,
+       0x080c, 0x8078, 0x0005, 0x6004, 0xa08a, 0x0080, 0x1a0c, 0x14f6,
+       0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005, 0xa182,
+       0x0040, 0x0002, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c7, 0xa0c5,
+       0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5,
+       0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0x080c, 0x14f6, 0x00d6,
+       0x00e6, 0x00f6, 0x0156, 0x0046, 0x0026, 0x6218, 0xa280, 0x002b,
+       0x2004, 0xa005, 0x0120, 0x2021, 0x0000, 0x080c, 0xab96, 0x6106,
+       0x2071, 0xb280, 0x7444, 0xa4a4, 0xff00, 0x0904, 0xa129, 0xa486,
+       0x2000, 0x1130, 0x2009, 0x0001, 0x2011, 0x0200, 0x080c, 0x663f,
+       0x080c, 0x15d9, 0x090c, 0x14f6, 0x6003, 0x0007, 0x2d00, 0x6837,
+       0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x6c5a, 0x2c00, 0x685e,
+       0x6008, 0x68b2, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, 0x694a,
+       0x0016, 0xa084, 0xff00, 0x6846, 0x684f, 0x0000, 0x6857, 0x0036,
+       0x080c, 0x510c, 0x001e, 0xa486, 0x2000, 0x1130, 0x2019, 0x0017,
+       0x080c, 0xa8eb, 0x0804, 0xa186, 0xa486, 0x0400, 0x1130, 0x2019,
+       0x0002, 0x080c, 0xa89d, 0x0804, 0xa186, 0xa486, 0x0200, 0x1110,
+       0x080c, 0xa882, 0xa486, 0x1000, 0x1110, 0x080c, 0xa8d0, 0x0804,
+       0xa186, 0x2069, 0xb048, 0x6a00, 0xd284, 0x0904, 0xa1d5, 0xa284,
+       0x0300, 0x1904, 0xa1cf, 0x6804, 0xa005, 0x0904, 0xa1c0, 0x2d78,
+       0x6003, 0x0007, 0x080c, 0x15c0, 0x0904, 0xa18d, 0x7800, 0xd08c,
+       0x1118, 0x7804, 0x8001, 0x7806, 0x6013, 0x0000, 0x6803, 0x0000,
+       0x6837, 0x0116, 0x683b, 0x0000, 0x6008, 0x68b2, 0x2c00, 0x684a,
+       0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, 0x6986, 0x6846, 0x7928,
+       0x698a, 0x792c, 0x698e, 0x7930, 0x6992, 0x7934, 0x6996, 0x6853,
+       0x003d, 0x7244, 0xa294, 0x0003, 0xa286, 0x0002, 0x1118, 0x684f,
+       0x0040, 0x0040, 0xa286, 0x0001, 0x1118, 0x684f, 0x0080, 0x0010,
+       0x684f, 0x0000, 0x20a9, 0x000a, 0x2001, 0xb290, 0xad90, 0x0015,
+       0x200c, 0x810f, 0x2112, 0x8000, 0x8210, 0x1f04, 0xa178, 0x200c,
+       0x6982, 0x8000, 0x200c, 0x697e, 0x080c, 0x510c, 0x002e, 0x004e,
+       0x015e, 0x00fe, 0x00ee, 0x00de, 0x0005, 0x6013, 0x0100, 0x6003,
+       0x0001, 0x6007, 0x0041, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0c70,
+       0x2069, 0xb292, 0x2d04, 0xa084, 0xff00, 0xa086, 0x1200, 0x11a8,
+       0x2069, 0xb280, 0x686c, 0xa084, 0x00ff, 0x0016, 0x6110, 0xa18c,
+       0x0700, 0xa10d, 0x6112, 0x001e, 0x6003, 0x0001, 0x6007, 0x0043,
+       0x080c, 0x67a8, 0x080c, 0x6c50, 0x0888, 0x6013, 0x0200, 0x6003,
+       0x0001, 0x6007, 0x0041, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0830,
+       0x6013, 0x0300, 0x0010, 0x6013, 0x0100, 0x6003, 0x0001, 0x6007,
+       0x0041, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0804, 0xa186, 0x6013,
+       0x0500, 0x0c98, 0x6013, 0x0600, 0x0818, 0x6013, 0x0200, 0x0800,
+       0xa186, 0x0013, 0x1170, 0x6004, 0xa08a, 0x0040, 0x0a0c, 0x14f6,
+       0xa08a, 0x0053, 0x1a0c, 0x14f6, 0xa082, 0x0040, 0x2008, 0x0804,
+       0xa252, 0xa186, 0x0051, 0x0138, 0xa186, 0x0047, 0x11d8, 0x6004,
+       0xa086, 0x0041, 0x0518, 0x2001, 0x0109, 0x2004, 0xd084, 0x01f0,
+       0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x080c, 0x6699,
+       0x002e, 0x001e, 0x000e, 0x012e, 0x6000, 0xa086, 0x0002, 0x1170,
+       0x0804, 0xa295, 0xa186, 0x0027, 0x0120, 0xa186, 0x0014, 0x190c,
+       0x14f6, 0x6004, 0xa082, 0x0040, 0x2008, 0x001a, 0x080c, 0x80be,
+       0x0005, 0xa22c, 0xa22e, 0xa22e, 0xa22c, 0xa22c, 0xa22c, 0xa22c,
+       0xa22c, 0xa22c, 0xa22c, 0xa22c, 0xa22c, 0xa22c, 0xa22c, 0xa22c,
+       0xa22c, 0xa22c, 0xa22c, 0xa22c, 0x080c, 0x14f6, 0x080c, 0x6b73,
+       0x080c, 0x6c50, 0x0036, 0x00d6, 0x6010, 0xa06d, 0x01c0, 0xad84,
+       0xf000, 0x01a8, 0x6003, 0x0002, 0x6018, 0x2004, 0xd0bc, 0x1178,
+       0x2019, 0x0004, 0x080c, 0xa91f, 0x6013, 0x0000, 0x6014, 0xa005,
+       0x1120, 0x2001, 0xafa4, 0x2004, 0x6016, 0x6003, 0x0007, 0x00de,
+       0x003e, 0x0005, 0x0002, 0xa266, 0xa283, 0xa26f, 0xa28f, 0xa266,
+       0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0xa266,
+       0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0x080c, 0x14f6,
+       0x6010, 0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x080c,
+       0x6b73, 0x6010, 0xa080, 0x0013, 0x2004, 0xd0b4, 0x0138, 0x6003,
+       0x0007, 0x2009, 0x0043, 0x080c, 0x80a7, 0x0010, 0x6003, 0x0002,
+       0x080c, 0x6c50, 0x0005, 0x080c, 0x6b73, 0x080c, 0xab55, 0x1120,
+       0x080c, 0x6618, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005, 0x080c,
+       0x6b73, 0x2009, 0x0041, 0x0804, 0xa3de, 0xa182, 0x0040, 0x0002,
+       0xa2ab, 0xa2ad, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ae,
+       0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab,
+       0xa2ab, 0xa2b9, 0xa2ab, 0x080c, 0x14f6, 0x0005, 0x6003, 0x0004,
+       0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1824,
+       0x0005, 0x00d6, 0x080c, 0x6618, 0x00de, 0x080c, 0xabb4, 0x080c,
+       0x8078, 0x0005, 0xa182, 0x0040, 0x0002, 0xa2d8, 0xa2d8, 0xa2d8,
+       0xa2d8, 0xa2d8, 0xa2d8, 0xa2d8, 0xa2da, 0xa2d8, 0xa2dd, 0xa316,
+       0xa2d8, 0xa2d8, 0xa2d8, 0xa2d8, 0xa316, 0xa2d8, 0xa2d8, 0xa2d8,
+       0x080c, 0x14f6, 0x080c, 0x80be, 0x0005, 0x2001, 0xad71, 0x2004,
+       0xd0e4, 0x0158, 0x2001, 0x0100, 0x2004, 0xa082, 0x0005, 0x0228,
+       0x2001, 0x011f, 0x2004, 0x6036, 0x0010, 0x6037, 0x0000, 0x080c,
+       0x6c05, 0x080c, 0x6d0d, 0x6010, 0x00d6, 0x2068, 0x684c, 0xd0fc,
+       0x0150, 0xa08c, 0x0003, 0xa18e, 0x0002, 0x0168, 0x2009, 0x0041,
+       0x00de, 0x0804, 0xa3de, 0x6003, 0x0007, 0x6017, 0x0000, 0x080c,
+       0x6618, 0x00de, 0x0005, 0x080c, 0xab55, 0x0110, 0x00de, 0x0005,
+       0x080c, 0x6618, 0x080c, 0x8078, 0x00de, 0x0ca0, 0x0036, 0x080c,
+       0x6c05, 0x080c, 0x6d0d, 0x6010, 0x00d6, 0x2068, 0x6018, 0x2004,
+       0xd0bc, 0x0188, 0x684c, 0xa084, 0x0003, 0xa086, 0x0002, 0x0140,
+       0x687c, 0x632c, 0xa31a, 0x632e, 0x6880, 0x6328, 0xa31b, 0x632a,
+       0x6003, 0x0002, 0x0080, 0x2019, 0x0004, 0x080c, 0xa91f, 0x6014,
+       0xa005, 0x1128, 0x2001, 0xafa4, 0x2004, 0x8003, 0x6016, 0x6013,
+       0x0000, 0x6003, 0x0007, 0x00de, 0x003e, 0x0005, 0xa186, 0x0013,
+       0x1150, 0x6004, 0xa086, 0x0042, 0x190c, 0x14f6, 0x080c, 0x6b73,
+       0x080c, 0x6c50, 0x0005, 0xa186, 0x0027, 0x0118, 0xa186, 0x0014,
+       0x1180, 0x6004, 0xa086, 0x0042, 0x190c, 0x14f6, 0x2001, 0x0007,
+       0x080c, 0x4c5d, 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50,
+       0x0005, 0xa182, 0x0040, 0x0002, 0xa37f, 0xa37f, 0xa37f, 0xa37f,
+       0xa37f, 0xa37f, 0xa37f, 0xa381, 0xa38d, 0xa37f, 0xa37f, 0xa37f,
+       0xa37f, 0xa37f, 0xa37f, 0xa37f, 0xa37f, 0xa37f, 0xa37f, 0x080c,
+       0x14f6, 0x0036, 0x0046, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10,
+       0x080c, 0x1824, 0x004e, 0x003e, 0x0005, 0x6010, 0x00d6, 0x2068,
+       0x6810, 0x6a14, 0x0006, 0x0046, 0x0056, 0x6c7c, 0xa422, 0x6d80,
+       0x2200, 0xa52b, 0x602c, 0xa420, 0x642e, 0x6028, 0xa529, 0x652a,
+       0x005e, 0x004e, 0x000e, 0xa20d, 0x1178, 0x684c, 0xd0fc, 0x0120,
+       0x2009, 0x0041, 0x00de, 0x0490, 0x6003, 0x0007, 0x6017, 0x0000,
+       0x080c, 0x6618, 0x00de, 0x0005, 0x0006, 0x00f6, 0x2c78, 0x080c,
+       0x5029, 0x00fe, 0x000e, 0x0120, 0x6003, 0x0002, 0x00de, 0x0005,
+       0x2009, 0xad0d, 0x210c, 0xd19c, 0x0118, 0x6003, 0x0007, 0x0010,
+       0x6003, 0x0006, 0x0021, 0x080c, 0x661a, 0x00de, 0x0005, 0xd2fc,
+       0x0140, 0x8002, 0x8000, 0x8212, 0xa291, 0x0000, 0x2009, 0x0009,
+       0x0010, 0x2009, 0x0015, 0x6a6a, 0x6866, 0x0005, 0xa182, 0x0040,
+       0x0208, 0x0062, 0xa186, 0x0013, 0x0120, 0xa186, 0x0014, 0x190c,
+       0x14f6, 0x6020, 0xd0dc, 0x090c, 0x14f6, 0x0005, 0xa401, 0xa408,
+       0xa414, 0xa420, 0xa401, 0xa401, 0xa401, 0xa42f, 0xa401, 0xa403,
+       0xa403, 0xa401, 0xa401, 0xa401, 0xa401, 0xa403, 0xa401, 0xa403,
+       0xa401, 0x080c, 0x14f6, 0x6020, 0xd0dc, 0x090c, 0x14f6, 0x0005,
+       0x6003, 0x0001, 0x6106, 0x080c, 0x67a8, 0x0126, 0x2091, 0x8000,
+       0x080c, 0x6c50, 0x012e, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c,
+       0x67a8, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c50, 0x012e, 0x0005,
+       0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, 0x1e6e, 0x0126, 0x2091,
+       0x8000, 0x080c, 0x680b, 0x080c, 0x6d0d, 0x012e, 0x0005, 0xa016,
+       0x080c, 0x1824, 0x0005, 0x0126, 0x2091, 0x8000, 0x0036, 0x00d6,
+       0xa182, 0x0040, 0x0023, 0x00de, 0x003e, 0x012e, 0x0005, 0xa44f,
+       0xa451, 0xa463, 0xa47e, 0xa44f, 0xa44f, 0xa44f, 0xa493, 0xa44f,
+       0xa44f, 0xa44f, 0xa44f, 0xa44f, 0xa44f, 0xa44f, 0xa44f, 0x080c,
+       0x14f6, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x01f8, 0xa09c, 0x0003,
+       0xa39e, 0x0003, 0x01d0, 0x6003, 0x0001, 0x6106, 0x080c, 0x67a8,
+       0x080c, 0x6c50, 0x0498, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x0168,
+       0xa09c, 0x0003, 0xa39e, 0x0003, 0x0140, 0x6003, 0x0001, 0x6106,
+       0x080c, 0x67a8, 0x080c, 0x6c50, 0x0408, 0x6013, 0x0000, 0x6017,
+       0x0000, 0x2019, 0x0004, 0x080c, 0xa91f, 0x00c0, 0x6010, 0x2068,
+       0x684c, 0xd0fc, 0x0d90, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0d68,
+       0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, 0x1e6e, 0x080c, 0x680b,
+       0x080c, 0x6d0d, 0x0018, 0xa016, 0x080c, 0x1824, 0x0005, 0x080c,
+       0x6b73, 0x6110, 0x81ff, 0x0158, 0x00d6, 0x2168, 0x080c, 0xabfa,
+       0x0036, 0x2019, 0x0029, 0x080c, 0xa91f, 0x003e, 0x00de, 0x080c,
+       0x974e, 0x080c, 0x6c50, 0x0005, 0x080c, 0x6c05, 0x6110, 0x81ff,
+       0x0158, 0x00d6, 0x2168, 0x080c, 0xabfa, 0x0036, 0x2019, 0x0029,
+       0x080c, 0xa91f, 0x003e, 0x00de, 0x080c, 0x974e, 0x080c, 0x6d0d,
+       0x0005, 0xa182, 0x0085, 0x0002, 0xa4cd, 0xa4cb, 0xa4cb, 0xa4d9,
+       0xa4cb, 0xa4cb, 0xa4cb, 0x080c, 0x14f6, 0x6003, 0x000b, 0x6106,
+       0x080c, 0x67a8, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c50, 0x012e,
+       0x0005, 0x0026, 0x00e6, 0x080c, 0xab4e, 0x0118, 0x080c, 0x8078,
+       0x00c8, 0x2071, 0xb280, 0x7224, 0x6212, 0x7220, 0x080c, 0xa7ce,
+       0x0118, 0x6007, 0x0086, 0x0040, 0x6007, 0x0087, 0x7224, 0xa296,
+       0xffff, 0x1110, 0x6007, 0x0086, 0x6003, 0x0001, 0x080c, 0x67a8,
+       0x080c, 0x6c50, 0x00ee, 0x002e, 0x0005, 0xa186, 0x0013, 0x1160,
+       0x6004, 0xa08a, 0x0085, 0x0a0c, 0x14f6, 0xa08a, 0x008c, 0x1a0c,
+       0x14f6, 0xa082, 0x0085, 0x00a2, 0xa186, 0x0027, 0x0130, 0xa186,
+       0x0014, 0x0118, 0x080c, 0x80be, 0x0050, 0x2001, 0x0007, 0x080c,
+       0x4c5d, 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005,
+       0xa527, 0xa529, 0xa529, 0xa527, 0xa527, 0xa527, 0xa527, 0x080c,
+       0x14f6, 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005,
+       0xa182, 0x0085, 0x0a0c, 0x14f6, 0xa182, 0x008c, 0x1a0c, 0x14f6,
+       0xa182, 0x0085, 0x0002, 0xa542, 0xa542, 0xa542, 0xa544, 0xa542,
+       0xa542, 0xa542, 0x080c, 0x14f6, 0x0005, 0xa186, 0x0013, 0x0148,
+       0xa186, 0x0014, 0x0130, 0xa186, 0x0027, 0x0118, 0x080c, 0x80be,
+       0x0030, 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005,
+       0x0036, 0x080c, 0xabb4, 0x603f, 0x0000, 0x2019, 0x000b, 0x0031,
+       0x601f, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x0126, 0x0036,
+       0x2091, 0x8000, 0x0086, 0x2c40, 0x0096, 0x2049, 0x0000, 0x080c,
+       0x7b9a, 0x009e, 0x008e, 0x1578, 0x0076, 0x2c38, 0x080c, 0x7c34,
+       0x007e, 0x1548, 0x6000, 0xa086, 0x0000, 0x0528, 0x601c, 0xa086,
+       0x0007, 0x0508, 0x00d6, 0x6000, 0xa086, 0x0004, 0x1150, 0x080c,
+       0xabb4, 0x601f, 0x0007, 0x2001, 0xafa3, 0x2004, 0x6016, 0x080c,
+       0x190b, 0x6010, 0x2068, 0x080c, 0x9596, 0x0110, 0x080c, 0xa91f,
+       0x00de, 0x6013, 0x0000, 0x080c, 0xabb4, 0x601f, 0x0007, 0x2001,
+       0xafa3, 0x2004, 0x6016, 0x003e, 0x012e, 0x0005, 0x00f6, 0x00c6,
+       0x0036, 0x0156, 0x2079, 0xb280, 0x7938, 0x783c, 0x080c, 0x2676,
+       0x1904, 0xa5f1, 0x0016, 0x00c6, 0x080c, 0x4cdc, 0x15c0, 0x2011,
+       0xb290, 0xac98, 0x000a, 0x20a9, 0x0004, 0x080c, 0x8a7c, 0x1578,
+       0x001e, 0x002e, 0x0026, 0x0016, 0x2019, 0x0029, 0x080c, 0x7cf4,
+       0x080c, 0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x007e,
+       0x001e, 0x0076, 0x2039, 0x0000, 0x080c, 0xa712, 0x007e, 0x080c,
+       0x4ecf, 0x0026, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286, 0x0006,
+       0x0118, 0xa286, 0x0004, 0x1118, 0x62a0, 0x080c, 0x2b87, 0x002e,
+       0x001e, 0x080c, 0x493a, 0x6612, 0x6516, 0xa006, 0x0010, 0x00ce,
+       0x001e, 0x015e, 0x003e, 0x00ce, 0x00fe, 0x0005, 0x00c6, 0x00d6,
+       0x00e6, 0x0016, 0x2009, 0xad20, 0x2104, 0xa086, 0x0074, 0x1904,
+       0xa64b, 0x2069, 0xb28e, 0x690c, 0xa182, 0x0100, 0x06c0, 0x6908,
+       0xa184, 0x8000, 0x05e8, 0x2001, 0xaf9d, 0x2004, 0xa005, 0x1160,
+       0x6018, 0x2070, 0x7010, 0xa084, 0x00ff, 0x0118, 0x7000, 0xd0f4,
+       0x0118, 0xa184, 0x0800, 0x0560, 0x6910, 0xa18a, 0x0001, 0x0610,
+       0x6914, 0x2069, 0xb2ae, 0x6904, 0x81ff, 0x1198, 0x690c, 0xa182,
+       0x0100, 0x02a8, 0x6908, 0x81ff, 0x1178, 0x6910, 0xa18a, 0x0001,
+       0x0288, 0x6918, 0xa18a, 0x0001, 0x0298, 0x00d0, 0x6013, 0x0100,
+       0x00a0, 0x6013, 0x0300, 0x0088, 0x6013, 0x0500, 0x0070, 0x6013,
+       0x0700, 0x0058, 0x6013, 0x0900, 0x0040, 0x6013, 0x0b00, 0x0028,
+       0x6013, 0x0f00, 0x0010, 0x6013, 0x2d00, 0xa085, 0x0001, 0x0008,
+       0xa006, 0x001e, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6,
+       0x0026, 0x0036, 0x0156, 0x6218, 0x2268, 0x6b04, 0xa394, 0x00ff,
+       0xa286, 0x0006, 0x0190, 0xa286, 0x0004, 0x0178, 0xa394, 0xff00,
+       0x8217, 0xa286, 0x0006, 0x0148, 0xa286, 0x0004, 0x0130, 0x00c6,
+       0x2d60, 0x080c, 0x4ceb, 0x00ce, 0x04c0, 0x2011, 0xb296, 0xad98,
+       0x000a, 0x20a9, 0x0004, 0x080c, 0x8a7c, 0x1580, 0x2011, 0xb29a,
+       0xad98, 0x0006, 0x20a9, 0x0004, 0x080c, 0x8a7c, 0x1538, 0x0046,
+       0x0016, 0x6aa0, 0xa294, 0x00ff, 0x8227, 0xa006, 0x2009, 0xad52,
+       0x210c, 0xd1a4, 0x0138, 0x2009, 0x0029, 0x080c, 0xa96c, 0x6800,
+       0xc0e5, 0x6802, 0x2019, 0x0029, 0x080c, 0x68e7, 0x0076, 0x2039,
+       0x0000, 0x080c, 0x681d, 0x2c08, 0x080c, 0xa712, 0x007e, 0x2001,
+       0x0007, 0x080c, 0x4c5d, 0x001e, 0x004e, 0xa006, 0x015e, 0x003e,
+       0x002e, 0x00de, 0x00ce, 0x0005, 0x00d6, 0x2069, 0xb28e, 0x6800,
+       0xa086, 0x0800, 0x0118, 0x6013, 0x0000, 0x0008, 0xa006, 0x00de,
+       0x0005, 0x00c6, 0x00f6, 0x0016, 0x0026, 0x0036, 0x0156, 0x2079,
+       0xb28c, 0x7930, 0x7834, 0x080c, 0x2676, 0x11a0, 0x080c, 0x4cdc,
+       0x1188, 0x2011, 0xb290, 0xac98, 0x000a, 0x20a9, 0x0004, 0x080c,
+       0x8a7c, 0x1140, 0x2011, 0xb294, 0xac98, 0x0006, 0x20a9, 0x0004,
+       0x080c, 0x8a7c, 0x015e, 0x003e, 0x002e, 0x001e, 0x00fe, 0x00ce,
+       0x0005, 0x00c6, 0x0006, 0x0016, 0x0026, 0x0036, 0x0156, 0x2011,
+       0xb283, 0x2204, 0x8211, 0x220c, 0x080c, 0x2676, 0x11a0, 0x080c,
+       0x4cdc, 0x1188, 0x2011, 0xb296, 0xac98, 0x000a, 0x20a9, 0x0004,
+       0x080c, 0x8a7c, 0x1140, 0x2011, 0xb29a, 0xac98, 0x0006, 0x20a9,
+       0x0004, 0x080c, 0x8a7c, 0x015e, 0x003e, 0x002e, 0x001e, 0x000e,
+       0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0056,
+       0x0046, 0x0026, 0x0126, 0x2091, 0x8000, 0x2740, 0x2029, 0xafd0,
+       0x252c, 0x2021, 0xafd6, 0x2424, 0x2061, 0xb400, 0x2071, 0xad00,
+       0x7644, 0x7064, 0x81ff, 0x0128, 0x8001, 0xa602, 0x1a04, 0xa78e,
+       0x0018, 0xa606, 0x0904, 0xa78e, 0x2100, 0xac06, 0x0904, 0xa785,
+       0x080c, 0xa990, 0x0904, 0xa785, 0x671c, 0xa786, 0x0001, 0x0904,
+       0xa7a5, 0xa786, 0x0004, 0x0904, 0xa7a5, 0xa786, 0x0007, 0x05e8,
+       0x2500, 0xac06, 0x05d0, 0x2400, 0xac06, 0x05b8, 0x080c, 0xa9a0,
+       0x15a0, 0x88ff, 0x0118, 0x6050, 0xa906, 0x1578, 0x00d6, 0x6000,
+       0xa086, 0x0004, 0x1120, 0x0016, 0x080c, 0x190b, 0x001e, 0xa786,
+       0x0008, 0x1148, 0x080c, 0x9789, 0x1130, 0x080c, 0x85f3, 0x00de,
+       0x080c, 0x974e, 0x00d0, 0x6010, 0x2068, 0x080c, 0x9596, 0x0190,
+       0xa786, 0x0003, 0x1528, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
+       0x080c, 0xabfa, 0x0016, 0x080c, 0x97fd, 0x080c, 0x510c, 0x001e,
+       0x080c, 0x9742, 0x00de, 0x080c, 0x974e, 0xace0, 0x0018, 0x2001,
+       0xad16, 0x2004, 0xac02, 0x1210, 0x0804, 0xa726, 0x012e, 0x002e,
+       0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x0005,
+       0xa786, 0x0006, 0x19c0, 0xa386, 0x0005, 0x0128, 0x080c, 0xabfa,
+       0x080c, 0xa91f, 0x08f8, 0x00de, 0x0c00, 0x080c, 0xa9a0, 0x19e8,
+       0x81ff, 0x09d8, 0xa180, 0x0001, 0x2004, 0xa086, 0x0018, 0x0130,
+       0xa180, 0x0001, 0x2004, 0xa086, 0x002d, 0x1978, 0x6000, 0xa086,
+       0x0002, 0x1958, 0x080c, 0x9778, 0x0130, 0x080c, 0x9789, 0x1928,
+       0x080c, 0x85f3, 0x0038, 0x080c, 0x2aff, 0x080c, 0x9789, 0x1110,
+       0x080c, 0x85f3, 0x080c, 0x974e, 0x0804, 0xa785, 0x00c6, 0x00e6,
+       0x0016, 0x2c08, 0x2170, 0x080c, 0xa940, 0x001e, 0x0120, 0x601c,
+       0xa084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, 0xa7e6, 0xa7e6,
+       0xa7e6, 0xa7e6, 0xa7e6, 0xa7e6, 0xa7e8, 0xa7e6, 0xa006, 0x0005,
+       0x0046, 0x0016, 0x7018, 0xa080, 0x0028, 0x2024, 0xa4a4, 0x00ff,
+       0x8427, 0x2c00, 0x2009, 0x0020, 0x080c, 0xa96c, 0x001e, 0x004e,
+       0x0036, 0x2019, 0x0002, 0x080c, 0xa566, 0x003e, 0xa085, 0x0001,
+       0x0005, 0x2001, 0x0001, 0x080c, 0x4c1e, 0x0156, 0x0016, 0x0026,
+       0x0036, 0x20a9, 0x0004, 0x2019, 0xad05, 0x2011, 0xb296, 0x080c,
+       0x8a7c, 0x003e, 0x002e, 0x001e, 0x015e, 0xa005, 0x0005, 0x00f6,
+       0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0026, 0x0126, 0x2091,
+       0x8000, 0x2740, 0x2061, 0xb400, 0x2079, 0x0001, 0x8fff, 0x0904,
+       0xa875, 0x2071, 0xad00, 0x7644, 0x7064, 0x8001, 0xa602, 0x1a04,
+       0xa875, 0x88ff, 0x0128, 0x2800, 0xac06, 0x15b0, 0x2079, 0x0000,
+       0x080c, 0xa990, 0x0588, 0x2400, 0xac06, 0x0570, 0x671c, 0xa786,
+       0x0006, 0x1550, 0xa786, 0x0007, 0x0538, 0x88ff, 0x1140, 0x6018,
+       0xa206, 0x1510, 0x85ff, 0x0118, 0x6050, 0xa106, 0x11e8, 0x00d6,
+       0x6000, 0xa086, 0x0004, 0x1150, 0x080c, 0xabb4, 0x601f, 0x0007,
+       0x2001, 0xafa3, 0x2004, 0x6016, 0x080c, 0x190b, 0x6010, 0x2068,
+       0x080c, 0x9596, 0x0120, 0x0046, 0x080c, 0xa91f, 0x004e, 0x00de,
+       0x080c, 0x974e, 0x88ff, 0x1198, 0xace0, 0x0018, 0x2001, 0xad16,
+       0x2004, 0xac02, 0x1210, 0x0804, 0xa826, 0xa006, 0x012e, 0x002e,
+       0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0xa8c5,
+       0x0001, 0x0ca0, 0x0076, 0x0056, 0x0086, 0x2041, 0x0000, 0x2029,
+       0x0001, 0x2c20, 0x2019, 0x0002, 0x6218, 0x0096, 0x2049, 0x0000,
+       0x080c, 0x7b9a, 0x009e, 0x008e, 0x2039, 0x0000, 0x080c, 0x7c34,
+       0x080c, 0xa817, 0x005e, 0x007e, 0x0005, 0x0026, 0x0046, 0x0056,
+       0x0076, 0x00c6, 0x0156, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x2009,
+       0x0000, 0x0016, 0x0036, 0x080c, 0x4cdc, 0x11b0, 0x2c10, 0x0056,
+       0x0086, 0x2041, 0x0000, 0x2508, 0x2029, 0x0001, 0x0096, 0x2049,
+       0x0000, 0x080c, 0x7b9a, 0x009e, 0x008e, 0x2039, 0x0000, 0x080c,
+       0x7c34, 0x080c, 0xa817, 0x005e, 0x003e, 0x001e, 0x8108, 0x1f04,
+       0xa8a9, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x002e, 0x0005,
+       0x0076, 0x0056, 0x6218, 0x0086, 0x2041, 0x0000, 0x2029, 0x0001,
+       0x2019, 0x0048, 0x0096, 0x2049, 0x0000, 0x080c, 0x7b9a, 0x009e,
+       0x008e, 0x2039, 0x0000, 0x080c, 0x7c34, 0x2c20, 0x080c, 0xa817,
+       0x005e, 0x007e, 0x0005, 0x0026, 0x0046, 0x0056, 0x0076, 0x00c6,
+       0x0156, 0x2c20, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x0036,
+       0x080c, 0x4cdc, 0x11c0, 0x2c10, 0x0086, 0x2041, 0x0000, 0x2828,
+       0x0046, 0x2021, 0x0001, 0x080c, 0xab96, 0x004e, 0x0096, 0x2049,
+       0x0000, 0x080c, 0x7b9a, 0x009e, 0x008e, 0x2039, 0x0000, 0x080c,
+       0x7c34, 0x080c, 0xa817, 0x003e, 0x001e, 0x8108, 0x1f04, 0xa8f6,
+       0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x002e, 0x0005, 0x0016,
+       0x00f6, 0x3800, 0xd08c, 0x0130, 0xad82, 0x1000, 0x02b0, 0xad82,
+       0xad00, 0x0230, 0xad82, 0xe400, 0x0280, 0xad82, 0xffff, 0x1268,
+       0x6800, 0xa07d, 0x0138, 0x6803, 0x0000, 0x6b52, 0x080c, 0x510c,
+       0x2f68, 0x0cb0, 0x6b52, 0x080c, 0x510c, 0x00fe, 0x001e, 0x0005,
+       0x00e6, 0x0046, 0x0036, 0x2061, 0xb400, 0x2071, 0xad00, 0x7444,
+       0x7064, 0x8001, 0xa402, 0x12d8, 0x2100, 0xac06, 0x0168, 0x6000,
+       0xa086, 0x0000, 0x0148, 0x6008, 0xa206, 0x1130, 0x6018, 0xa1a0,
+       0x0006, 0x2424, 0xa406, 0x0140, 0xace0, 0x0018, 0x2001, 0xad16,
+       0x2004, 0xac02, 0x1220, 0x0c08, 0xa085, 0x0001, 0x0008, 0xa006,
+       0x003e, 0x004e, 0x00ee, 0x0005, 0x00d6, 0x0006, 0x080c, 0x15d9,
+       0x000e, 0x090c, 0x14f6, 0x6837, 0x010d, 0x685e, 0x0026, 0x2010,
+       0x080c, 0x9586, 0x2001, 0x0000, 0x0120, 0x2200, 0xa080, 0x0014,
+       0x2004, 0x002e, 0x684a, 0x6956, 0x6c46, 0x684f, 0x0000, 0xa006,
+       0x68b2, 0x6802, 0x683a, 0x685a, 0x080c, 0x510c, 0x00de, 0x0005,
+       0x6700, 0xa786, 0x0000, 0x0158, 0xa786, 0x0001, 0x0140, 0xa786,
+       0x000a, 0x0128, 0xa786, 0x0009, 0x0110, 0xa085, 0x0001, 0x0005,
+       0x00e6, 0x6018, 0x2070, 0x70a0, 0xa206, 0x00ee, 0x0005, 0x0016,
+       0x6004, 0xa08e, 0x001e, 0x11a0, 0x8007, 0x6130, 0xa18c, 0x00ff,
+       0xa105, 0x6032, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0005,
+       0x2001, 0xafa4, 0x2004, 0x6016, 0x080c, 0x67a8, 0x080c, 0x6c50,
+       0x001e, 0x0005, 0xe000, 0xe000, 0x0005, 0x6020, 0xd0e4, 0x0158,
+       0xd0cc, 0x0118, 0x080c, 0x9866, 0x0030, 0x080c, 0xabb4, 0x080c,
+       0x6618, 0x080c, 0x8078, 0x0005, 0xa280, 0x0007, 0x2004, 0xa084,
+       0x000f, 0x0002, 0xa9e3, 0xa9e3, 0xa9e3, 0xa9e8, 0xa9e3, 0xa9e5,
+       0xa9e5, 0xa9e3, 0xa9e5, 0xa006, 0x0005, 0x00c6, 0x2260, 0x00ce,
+       0xa085, 0x0001, 0x0005, 0xa280, 0x0007, 0x2004, 0xa084, 0x000f,
+       0x0002, 0xa9fa, 0xa9fa, 0xa9fa, 0xa9fa, 0xa9fa, 0xa9fa, 0xaa05,
+       0xa9fa, 0xa9fa, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013, 0x2a00,
+       0x6003, 0x0001, 0x080c, 0x67a8, 0x0005, 0x00c6, 0x2260, 0x080c,
+       0xabb4, 0x603f, 0x0000, 0x6020, 0xc0f4, 0xc0cc, 0x6022, 0x6037,
+       0x0000, 0x00ce, 0x00d6, 0x2268, 0xa186, 0x0007, 0x1904, 0xaa60,
+       0x6810, 0xa005, 0x0138, 0xa080, 0x0013, 0x2004, 0xd0fc, 0x1110,
+       0x00de, 0x08c0, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, 0x67a8,
+       0x080c, 0x6c50, 0x00c6, 0x2d60, 0x6100, 0xa186, 0x0002, 0x1904,
+       0xaae7, 0x6010, 0xa005, 0x1138, 0x6000, 0xa086, 0x0007, 0x190c,
+       0x14f6, 0x0804, 0xaae7, 0xa08c, 0xf000, 0x1130, 0x0028, 0x2068,
+       0x6800, 0xa005, 0x1de0, 0x2d00, 0xa080, 0x0013, 0x2004, 0xa084,
+       0x0003, 0xa086, 0x0002, 0x1180, 0x6010, 0x2068, 0x684c, 0xc0dc,
+       0xc0f4, 0x684e, 0x6850, 0xc0f4, 0xc0fc, 0x6852, 0x2009, 0x0043,
+       0x080c, 0xa3de, 0x0804, 0xaae7, 0x2009, 0x0041, 0x0804, 0xaae1,
+       0xa186, 0x0005, 0x15f0, 0x6810, 0xa080, 0x0013, 0x2004, 0xd0bc,
+       0x1118, 0x00de, 0x0804, 0xa9fa, 0xd0b4, 0x0128, 0xd0fc, 0x090c,
+       0x14f6, 0x0804, 0xaa18, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c,
+       0x67a8, 0x080c, 0x6c50, 0x00c6, 0x2d60, 0x6100, 0xa186, 0x0002,
+       0x0120, 0xa186, 0x0004, 0x1904, 0xaae7, 0x2071, 0xaffd, 0x7000,
+       0xa086, 0x0003, 0x1128, 0x7004, 0xac06, 0x1110, 0x7003, 0x0000,
+       0x6810, 0xa080, 0x0013, 0x200c, 0xc1f4, 0xc1dc, 0x2102, 0x8000,
+       0x200c, 0xc1f4, 0xc1fc, 0xc1bc, 0x2102, 0x2009, 0x0042, 0x0804,
+       0xaae1, 0x0036, 0x00d6, 0x00d6, 0x080c, 0x15d9, 0x003e, 0x090c,
+       0x14f6, 0x6837, 0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x685b,
+       0x0000, 0x6b5e, 0x6857, 0x0045, 0x2c00, 0x6862, 0x6034, 0x6872,
+       0x2360, 0x6020, 0xc0dd, 0x6022, 0x6018, 0xa080, 0x0028, 0x2004,
+       0xa084, 0x00ff, 0x8007, 0x6350, 0x6b4a, 0x6846, 0x684f, 0x0000,
+       0x6d6a, 0x6e66, 0x686f, 0x0001, 0x080c, 0x510c, 0x2019, 0x0045,
+       0x6008, 0x2068, 0x080c, 0xa566, 0x2d00, 0x600a, 0x601f, 0x0006,
+       0x6003, 0x0007, 0x6017, 0x0000, 0x603f, 0x0000, 0x00de, 0x003e,
+       0x0038, 0x603f, 0x0000, 0x6003, 0x0007, 0x080c, 0xa3de, 0x00ce,
+       0x00de, 0x0005, 0xa186, 0x0013, 0x1128, 0x6004, 0xa082, 0x0085,
+       0x2008, 0x00c2, 0xa186, 0x0027, 0x1178, 0x080c, 0x6b73, 0x0036,
+       0x00d6, 0x6010, 0x2068, 0x2019, 0x0004, 0x080c, 0xa91f, 0x00de,
+       0x003e, 0x080c, 0x6c50, 0x0005, 0xa186, 0x0014, 0x0d70, 0x080c,
+       0x80be, 0x0005, 0xab13, 0xab11, 0xab11, 0xab11, 0xab11, 0xab11,
+       0xab13, 0x080c, 0x14f6, 0x080c, 0x6b73, 0x6003, 0x000c, 0x080c,
+       0x6c50, 0x0005, 0xa182, 0x008c, 0x1220, 0xa182, 0x0085, 0x0208,
+       0x001a, 0x080c, 0x80be, 0x0005, 0xab2b, 0xab2b, 0xab2b, 0xab2b,
+       0xab2d, 0xab4b, 0xab2b, 0x080c, 0x14f6, 0x00d6, 0x2c68, 0x080c,
+       0x8022, 0x01a0, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0xb28e,
+       0x210c, 0x6136, 0x2009, 0xb28f, 0x210c, 0x613a, 0x600b, 0xffff,
+       0x6918, 0x611a, 0x601f, 0x0004, 0x080c, 0x67a8, 0x2d60, 0x080c,
+       0x8078, 0x00de, 0x0005, 0x080c, 0x8078, 0x0005, 0x00e6, 0x6018,
+       0x2070, 0x7000, 0xd0ec, 0x00ee, 0x0005, 0x6010, 0xa080, 0x0013,
+       0x200c, 0xd1ec, 0x05d0, 0x2001, 0xad71, 0x2004, 0xd0ec, 0x05a8,
+       0x6003, 0x0002, 0x6020, 0xc0e5, 0x6022, 0xd1ac, 0x0180, 0x00f6,
+       0x2c78, 0x080c, 0x5025, 0x00fe, 0x0150, 0x2001, 0xafa5, 0x2004,
+       0x603e, 0x2009, 0xad71, 0x210c, 0xd1f4, 0x11e8, 0x0080, 0x2009,
+       0xad71, 0x210c, 0xd1f4, 0x0128, 0x6020, 0xc0e4, 0x6022, 0xa006,
+       0x00a0, 0x2001, 0xafa5, 0x200c, 0x8103, 0xa100, 0x603e, 0x6018,
+       0xa088, 0x002b, 0x2104, 0xa005, 0x0118, 0xa088, 0x0003, 0x0cd0,
+       0x2c0a, 0x600f, 0x0000, 0xa085, 0x0001, 0x0005, 0x0016, 0x00c6,
+       0x00e6, 0x6150, 0xa2f0, 0x002b, 0x2e04, 0x2060, 0x8cff, 0x0180,
+       0x84ff, 0x1118, 0x6050, 0xa106, 0x1138, 0x600c, 0x2072, 0x080c,
+       0x6618, 0x080c, 0x8078, 0x0010, 0xacf0, 0x0003, 0x2e64, 0x0c70,
+       0x00ee, 0x00ce, 0x001e, 0x0005, 0x00d6, 0x6018, 0xa0e8, 0x002b,
+       0x2d04, 0xa005, 0x0140, 0xac06, 0x0120, 0x2d04, 0xa0e8, 0x0003,
+       0x0cb8, 0x600c, 0x206a, 0x00de, 0x0005, 0x0026, 0x0036, 0x0156,
+       0x2011, 0xad27, 0x2204, 0xa084, 0x00ff, 0x2019, 0xb28e, 0x2334,
+       0xa636, 0x11d8, 0x8318, 0x2334, 0x2204, 0xa084, 0xff00, 0xa636,
+       0x11a0, 0x2011, 0xb290, 0x6018, 0xa098, 0x000a, 0x20a9, 0x0004,
+       0x080c, 0x8a7c, 0x1150, 0x2011, 0xb294, 0x6018, 0xa098, 0x0006,
+       0x20a9, 0x0004, 0x080c, 0x8a7c, 0x1100, 0x015e, 0x003e, 0x002e,
+       0x0005, 0x00e6, 0x2071, 0xad00, 0x080c, 0x48f5, 0x080c, 0x28fa,
+       0x00ee, 0x0005, 0x00e6, 0x6018, 0x2070, 0x7000, 0xd0fc, 0x0108,
+       0x0011, 0x00ee, 0x0005, 0x6850, 0xc0e5, 0x6852, 0x0005, 0x00e6,
+       0x00c6, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0016, 0x0126,
+       0x2091, 0x8000, 0x2029, 0xafd0, 0x252c, 0x2021, 0xafd6, 0x2424,
+       0x2061, 0xb400, 0x2071, 0xad00, 0x7644, 0x7064, 0xa606, 0x0578,
+       0x671c, 0xa786, 0x0001, 0x0118, 0xa786, 0x0008, 0x1500, 0x2500,
+       0xac06, 0x01e8, 0x2400, 0xac06, 0x01d0, 0x080c, 0xa990, 0x01b8,
+       0x080c, 0xa9a0, 0x11a0, 0x6000, 0xa086, 0x0004, 0x1120, 0x0016,
+       0x080c, 0x190b, 0x001e, 0x080c, 0x9778, 0x1110, 0x080c, 0x2aff,
+       0x080c, 0x9789, 0x1110, 0x080c, 0x85f3, 0x080c, 0x974e, 0xace0,
+       0x0018, 0x2001, 0xad16, 0x2004, 0xac02, 0x1208, 0x0858, 0x012e,
+       0x001e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x00ce, 0x00ee,
+       0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0xad40,
+       0xd5a4, 0x0118, 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0118, 0x7030,
+       0x8000, 0x7032, 0xd5ac, 0x0118, 0x2071, 0xad4a, 0x0451, 0x00ee,
+       0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000,
+       0x2071, 0xad40, 0xd5a4, 0x0118, 0x7034, 0x8000, 0x7036, 0xd5b4,
+       0x0118, 0x7030, 0x8000, 0x7032, 0xd5ac, 0x0118, 0x2071, 0xad4a,
+       0x0081, 0x00ee, 0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6,
+       0x2091, 0x8000, 0x2071, 0xad42, 0x0021, 0x00ee, 0x000e, 0x012e,
+       0x0005, 0x2e04, 0x8000, 0x2072, 0x1220, 0x8e70, 0x2e04, 0x8000,
+       0x2072, 0x0005, 0x00e6, 0x2071, 0xad40, 0x0c99, 0x00ee, 0x0005,
+       0x00e6, 0x2071, 0xad44, 0x0c69, 0x00ee, 0x0005, 0x0001, 0x0002,
+       0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200,
+       0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x8529
+};
+
index 0e1e0ab1f8d633afe29c9293f270287957387e5d..35ca6dc3147de5b3d0a9949cdc67f0ae8521fd88 100644 (file)
@@ -1022,7 +1022,7 @@ static int sd_init_onedisk(int i)
                cmd[1] = (rscsi_disks[i].device->scsi_level <= SCSI_2) ?
                         ((rscsi_disks[i].device->lun << 5) & 0xe0) : 0;
                cmd[2] = 0x3f;  /* Get all pages */
-               cmd[4] = 8;     /* But we only want the 8 byte header */
+               cmd[4] = 255;     /* But we only want the 8 byte header */
                SRpnt->sr_cmd_len = 0;
                SRpnt->sr_sense_buffer[0] = 0;
                SRpnt->sr_sense_buffer[2] = 0;
index ebd5eff75101b0b2af30d5d2e27a21d5b44dcd39..5d6a3cd2c0a1c65c67cf2c178bf63f59126192ac 100644 (file)
 #define FAST
 #endif
 
-#undef LINKED          /* Linked commands are currently broken! */
+#undef LINKED                  /* Linked commands are currently broken! */
 
 #if defined(OVERRIDE) && !defined(CONTROLLER)
 #error Please use -DCONTROLLER=SEAGATE or -DCONTROLLER=FD to override controller type
        STATUS
 */
 #ifdef SWAPSTAT
-       #define STAT_MSG                0x08
-       #define STAT_CD                 0x02
+#define STAT_MSG               0x08
+#define STAT_CD                        0x02
 #else
-       #define STAT_MSG                0x02
-       #define STAT_CD                 0x08
+#define STAT_MSG               0x02
+#define STAT_CD                        0x08
 #endif
 
 #define STAT_BSY               0x01
 extern volatile int seagate_st0x_timeout;
 
 #ifdef PARITY
-       #define BASE_CMD CMD_EN_PARITY
+#define BASE_CMD CMD_EN_PARITY
 #else
-       #define BASE_CMD  0
+#define BASE_CMD  0
 #endif
 
 /*
@@ -193,7 +193,7 @@ extern volatile int seagate_st0x_timeout;
 #define PHASE_BUS_FREE 1
 #define PHASE_ARBITRATION 2
 #define PHASE_SELECTION 4
-#define PHASE_DATAIN 8 
+#define PHASE_DATAIN 8
 #define PHASE_DATAOUT 0x10
 #define PHASE_CMDOUT 0x20
 #define PHASE_MSGIN 0x40
@@ -216,44 +216,43 @@ extern volatile int seagate_st0x_timeout;
 #define ST0X_BUS_FREE_DELAY 25
 #define ST0X_SELECTION_DELAY 25
 
-#define SEAGATE 1      /* these determine the type of the controller */
+#define SEAGATE 1              /* these determine the type of the controller */
 #define FD     2
 
 #define ST0X_ID_STR    "Seagate ST-01/ST-02"
 #define FD_ID_STR      "TMC-8XX/TMC-950"
 
-
 static int internal_command (unsigned char target, unsigned char lun,
-                             const void *cmnd,
-                             void *buff, int bufflen, int reselect);
+                            const void *cmnd,
+                            void *buff, int bufflen, int reselect);
 
-static int incommand;                   /* set if arbitration has finished
-                                           and we are in some command phase. */
+static int incommand;          /* set if arbitration has finished
+                                  and we are in some command phase. */
 
-static unsigned int base_address = 0;   /* Where the card ROM starts, used to 
-                                           calculate memory mapped register
-                                           location.  */
+static unsigned int base_address = 0;  /* Where the card ROM starts, used to 
+                                          calculate memory mapped register
+                                          location.  */
 
-static unsigned long st0x_cr_sr;        /* control register write, status
-                                           register read.  256 bytes in
-                                           length.
-                                           Read is status of SCSI BUS, as per 
-                                           STAT masks.  */
+static unsigned long st0x_cr_sr;       /* control register write, status
+                                          register read.  256 bytes in
+                                          length.
+                                          Read is status of SCSI BUS, as per 
+                                          STAT masks.  */
 
-static unsigned long st0x_dr;           /* data register, read write 256
-                                           bytes in length.  */
+static unsigned long st0x_dr;  /* data register, read write 256
+                                  bytes in length.  */
 
-static volatile int st0x_aborted = 0;   /* set when we are aborted, ie by a
-                                           time out, etc.  */
+static volatile int st0x_aborted = 0;  /* set when we are aborted, ie by a
+                                          time out, etc.  */
 
-static unsigned char controller_type = 0;       /* set to SEAGATE for ST0x
-                                                   boards or FD for TMC-8xx
-                                                   boards */
+static unsigned char controller_type = 0;      /* set to SEAGATE for ST0x
+                                                  boards or FD for TMC-8xx
+                                                  boards */
 static int irq = IRQ;
 
-MODULE_PARM(base_address, "i");
-MODULE_PARM(controller_type, "b");
-MODULE_PARM(irq, "i");
+MODULE_PARM (base_address, "i");
+MODULE_PARM (controller_type, "b");
+MODULE_PARM (irq, "i");
 
 #define retcode(result) (((result) << 16) | (message << 8) | status)
 #define STATUS ((u8) isa_readb(st0x_cr_sr))
@@ -261,40 +260,38 @@ MODULE_PARM(irq, "i");
 #define WRITE_CONTROL(d) { isa_writeb((d), st0x_cr_sr); }
 #define WRITE_DATA(d) { isa_writeb((d), st0x_dr); }
 
-void st0x_setup (char *str, int *ints)
+void
+st0x_setup (char *str, int *ints)
 {
-  controller_type = SEAGATE;
-  base_address = ints[1];
-  irq = ints[2];
+       controller_type = SEAGATE;
+       base_address = ints[1];
+       irq = ints[2];
 }
 
-void tmc8xx_setup (char *str, int *ints)
+void
+tmc8xx_setup (char *str, int *ints)
 {
-  controller_type = FD;
-  base_address = ints[1];
-  irq = ints[2];
+       controller_type = FD;
+       base_address = ints[1];
+       irq = ints[2];
 }
 
 #ifndef OVERRIDE
-static unsigned int seagate_bases[] =
-{
-  0xc8000, 0xca000, 0xcc000,
-  0xce000, 0xdc000, 0xde000
+static unsigned int seagate_bases[] = {
+       0xc8000, 0xca000, 0xcc000,
+       0xce000, 0xdc000, 0xde000
 };
 
-typedef struct
-{
-  const unsigned char *signature;
-  unsigned offset;
-  unsigned length;
-  unsigned char type;
-}
-Signature;
+typedef struct {
+       const unsigned char *signature;
+       unsigned offset;
+       unsigned length;
+       unsigned char type;
+} Signature;
 
-static const Signature __initdata signatures[] =
-{
-  {"ST01 v1.7  (C) Copyright 1987 Seagate", 15, 37, SEAGATE},
-  {"SCSI BIOS 2.00  (C) Copyright 1987 Seagate", 15, 40, SEAGATE},
+static Signature __initdata signatures[] = {
+       {"ST01 v1.7  (C) Copyright 1987 Seagate", 15, 37, SEAGATE},
+       {"SCSI BIOS 2.00  (C) Copyright 1987 Seagate", 15, 40, SEAGATE},
 
 /*
  * The following two lines are NOT mistakes.  One detects ROM revision
@@ -303,28 +300,28 @@ static const Signature __initdata signatures[] =
  * are probably "good enough"
  */
 
-  {"SEAGATE SCSI BIOS ", 16, 17, SEAGATE},
-  {"SEAGATE SCSI BIOS ", 17, 17, SEAGATE},
+       {"SEAGATE SCSI BIOS ", 16, 17, SEAGATE},
+       {"SEAGATE SCSI BIOS ", 17, 17, SEAGATE},
 
 /*
  * However, future domain makes several incompatible SCSI boards, so specific
  * signatures must be used.
  */
 
-  {"FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89", 5, 46, FD},
-  {"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89", 5, 46, FD},
-  {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90", 5, 47, FD},
-  {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90", 5, 47, FD},
-  {"FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90", 5, 46, FD},
-  {"FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92", 5, 44, FD},
-  {"IBM F1 BIOS V1.1004/30/92", 5, 25, FD},
-  {"FUTURE DOMAIN TMC-950", 5, 21, FD},
-  /* Added for 2.2.16 by Matthias_Heidbrink@b.maus.de */
-  {"IBM F1 V1.2009/22/93", 5, 25, FD},
+       {"FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89", 5, 46, FD},
+       {"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89", 5, 46, FD},
+       {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90", 5, 47, FD},
+       {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90", 5, 47, FD},
+       {"FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90", 5, 46, FD},
+       {"FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92", 5, 44, FD},
+       {"IBM F1 BIOS V1.1004/30/92", 5, 25, FD},
+       {"FUTURE DOMAIN TMC-950", 5, 21, FD},
+       /* Added for 2.2.16 by Matthias_Heidbrink@b.maus.de */
+       {"IBM F1 V1.2009/22/93", 5, 25, FD},
 };
 
 #define NUM_SIGNATURES (sizeof(signatures) / sizeof(Signature))
-#endif /* n OVERRIDE */
+#endif                         /* n OVERRIDE */
 
 /*
  * hostno stores the hostnumber, as told to us by the init routine.
@@ -382,35 +379,37 @@ static int fast = 1;
  */
 
 static int borken_calibration = 0;
+
 static void __init borken_init (void)
 {
-  register int count = 0, start = jiffies + 1, stop = start + 25;
+       register int count = 0, start = jiffies + 1, stop = start + 25;
 
-  while (time_before(jiffies, start)) ;
-  for (; time_before(jiffies, stop); ++count) ;
+       while (time_before (jiffies, start)) ;
+       for (; time_before (jiffies, stop); ++count) ;
 
 /*
  * Ok, we now have a count for .25 seconds.  Convert to a
  * count per second and divide by transfer rate in K.  */
 
-  borken_calibration = (count * 4) / (SLOW_RATE * 1024);
+       borken_calibration = (count * 4) / (SLOW_RATE * 1024);
 
-  if (borken_calibration < 1)
-    borken_calibration = 1;
+       if (borken_calibration < 1)
+               borken_calibration = 1;
 }
 
 static inline void borken_wait (void)
 {
-  register int count;
+       register int count;
 
-  for (count = borken_calibration; count && (STATUS & STAT_REQ); --count) ;
+       for (count = borken_calibration; count && (STATUS & STAT_REQ);
+            --count) ;
 #if (DEBUG & DEBUG_BORKEN)
-  if (count)
-    printk ("scsi%d : borken timeout\n", hostno);
+       if (count)
+               printk ("scsi%d : borken timeout\n", hostno);
 #endif
 }
 
-#endif /* def SLOW_RATE */
+#endif                         /* def SLOW_RATE */
 
 /* These beasts only live on ISA, and ISA means 8MHz. Each ULOOP()
  * contains at least one ISA access, which takes more than 0.125
@@ -422,33 +421,34 @@ static inline void borken_wait (void)
 
 int __init seagate_st0x_detect (Scsi_Host_Template * tpnt)
 {
-  struct Scsi_Host *instance;
-  int i, j;
+       struct Scsi_Host *instance;
+       int i, j;
 
-  tpnt->proc_name = "seagate";
+       tpnt->proc_name = "seagate";
 /*
- *    First, we try for the manual override.  */
-  DANY ("Autodetecting ST0x / TMC-8xx\n");
+ *    First, we try for the manual override.
+ */
+       DANY ("Autodetecting ST0x / TMC-8xx\n");
 
-  if (hostno != -1) {
-    printk (KERN_ERR "seagate_st0x_detect() called twice?!\n");
-    return 0;
-  }
+       if (hostno != -1) {
+               printk (KERN_ERR "seagate_st0x_detect() called twice?!\n");
+               return 0;
+       }
 
 /* If the user specified the controller type from the command line,
    controller_type will be non-zero, so don't try to detect one */
 
-  if (!controller_type)
-  {
+       if (!controller_type) {
 #ifdef OVERRIDE
-    base_address = OVERRIDE;
-    controller_type = CONTROLLER;
+               base_address = OVERRIDE;
+               controller_type = CONTROLLER;
 
-    DANY("Base address overridden to %x, controller type is %s\n",
-            base_address, controller_type == SEAGATE ? "SEAGATE" : "FD");
-#else /* OVERRIDE */
+               DANY ("Base address overridden to %x, controller type is %s\n",
+                     base_address,
+                     controller_type == SEAGATE ? "SEAGATE" : "FD");
+#else                          /* OVERRIDE */
 /*
- *    To detect this card, we simply look for the signature
+ *     To detect this card, we simply look for the signature
  *      from the BIOS version notice in all the possible locations
  *      of the ROM's.  This has a nice side effect of not trashing
  *      any register locations that might be used by something else.
@@ -457,106 +457,112 @@ int __init seagate_st0x_detect (Scsi_Host_Template * tpnt)
  * space for the on-board RAM instead.
  */
 
-    for (i = 0; i < (sizeof (seagate_bases) / sizeof (unsigned int)); ++i)
-
-      for (j = 0; !base_address && j < NUM_SIGNATURES; ++j)
-        if (isa_check_signature (seagate_bases[i] + signatures[j].offset,
-                             signatures[j].signature, signatures[j].length))
-        {
-          base_address = seagate_bases[i];
-          controller_type = signatures[j].type;
-        }
-#endif /* OVERRIDE */
-  }    /* (! controller_type) */
-
-  tpnt->this_id = (controller_type == SEAGATE) ? 7 : 6;
-  tpnt->name = (controller_type == SEAGATE) ? ST0X_ID_STR : FD_ID_STR;
+               for (i = 0;
+                    i < (sizeof (seagate_bases) / sizeof (unsigned int)); ++i)
+
+                       for (j = 0; !base_address && j < NUM_SIGNATURES; ++j)
+                               if (isa_check_signature
+                                   (seagate_bases[i] + signatures[j].offset,
+                                    signatures[j].signature,
+                                    signatures[j].length)) {
+                                       base_address = seagate_bases[i];
+                                       controller_type = signatures[j].type;
+                               }
+#endif                         /* OVERRIDE */
+       }
+       /* (! controller_type) */
+       tpnt->this_id = (controller_type == SEAGATE) ? 7 : 6;
+       tpnt->name = (controller_type == SEAGATE) ? ST0X_ID_STR : FD_ID_STR;
 
-  if (!base_address) {
-    DANY ("ST0x / TMC-8xx not detected.\n");
-    return 0;
-  }
+       if (!base_address) {
+               DANY ("ST0x / TMC-8xx not detected.\n");
+               return 0;
+       }
 
-  st0x_cr_sr = base_address + (controller_type == SEAGATE ? 0x1a00 : 0x1c00);
-  st0x_dr = st0x_cr_sr + 0x200;
+       st0x_cr_sr =
+           base_address + (controller_type == SEAGATE ? 0x1a00 : 0x1c00);
+       st0x_dr = st0x_cr_sr + 0x200;
 
-  DANY ("%s detected. Base address = %x, cr = %x, dr = %x\n",
-       tpnt->name, base_address, st0x_cr_sr, st0x_dr);
+       DANY ("%s detected. Base address = %x, cr = %x, dr = %x\n",
+             tpnt->name, base_address, st0x_cr_sr, st0x_dr);
 
 /*
- *    At all times, we will use IRQ 5.  Should also check for IRQ3 if we
+ *     At all times, we will use IRQ 5.  Should also check for IRQ3 if we
  *      loose our first interrupt.
  */
-  instance = scsi_register (tpnt, 0);
-  if(instance == NULL)
-       return 0;
-       
-  hostno = instance->host_no;
-  if (request_irq (irq, do_seagate_reconnect_intr, SA_INTERRUPT,
-                  (controller_type == SEAGATE) ? "seagate" : "tmc-8xx", NULL)) {
-    printk ("scsi%d : unable to allocate IRQ%d\n", hostno, irq);
-    return 0;
-  }
-  instance->irq = irq;
-  instance->io_port = base_address;
+       instance = scsi_register (tpnt, 0);
+       if (instance == NULL)
+               return 0;
+
+       hostno = instance->host_no;
+       if (request_irq (irq, do_seagate_reconnect_intr, SA_INTERRUPT,
+                        (controller_type == SEAGATE) ? "seagate" : "tmc-8xx",
+                        NULL)) {
+               printk ("scsi%d : unable to allocate IRQ%d\n", hostno, irq);
+               return 0;
+       }
+       instance->irq = irq;
+       instance->io_port = base_address;
 #ifdef SLOW_RATE
-  printk( "Calibrating borken timer... " );
-  borken_init ();
-  printk( " %d cycles per transfer\n", borken_calibration );
+       printk (KERN_INFO "Calibrating borken timer... ");
+       borken_init ();
+       printk (" %d cycles per transfer\n", borken_calibration);
 #endif
 
-  printk( "This is one second... " );
-  {
-    int clock;
-    ULOOP( 1*1000*1000 ) {
-      STATUS;
-      if (TIMEOUT) break;
-    }
-  }
+       printk (KERN_INFO "This is one second... ");
+       {
+               int clock;
+               ULOOP (1 * 1000 * 1000) {
+                       STATUS;
+                       if (TIMEOUT)
+                               break;
+               }
+       }
 
-  printk ("done, %s options:"
+       printk ("done, %s options:"
 #ifdef ARBITRATE
-            " ARBITRATE"
+               " ARBITRATE"
 #endif
 #ifdef DEBUG
-            " DEBUG"
+               " DEBUG"
 #endif
 #ifdef FAST
-            " FAST"
+               " FAST"
 #ifdef FAST32
-            "32"
+               "32"
 #endif
 #endif
 #ifdef LINKED
-            " LINKED"
+               " LINKED"
 #endif
 #ifdef PARITY
-            " PARITY"
+               " PARITY"
 #endif
 #ifdef SEAGATE_USE_ASM
-            " SEAGATE_USE_ASM"
+               " SEAGATE_USE_ASM"
 #endif
 #ifdef SLOW_RATE
-            " SLOW_RATE"
+               " SLOW_RATE"
 #endif
 #ifdef SWAPSTAT
-            " SWAPSTAT"
+               " SWAPSTAT"
 #endif
 #ifdef SWAPCNTDATA
-            " SWAPCNTDATA"
+               " SWAPCNTDATA"
 #endif
-         "\n", tpnt->name);
-  return 1;
+               "\n", tpnt->name);
+       return 1;
 }
 
-const char *seagate_st0x_info (struct Scsi_Host *shpnt)
+const char *
+seagate_st0x_info (struct Scsi_Host *shpnt)
 {
-  static char buffer[64];
+       static char buffer[64];
 
-  sprintf (buffer, "%s at irq %d, address 0x%05X",
-           (controller_type == SEAGATE) ? ST0X_ID_STR : FD_ID_STR,
-           irq, base_address);
-  return buffer;
+       sprintf (buffer, "%s at irq %d, address 0x%05X",
+                (controller_type == SEAGATE) ? ST0X_ID_STR : FD_ID_STR,
+                irq, base_address);
+       return buffer;
 }
 
 /*
@@ -616,50 +622,50 @@ static int should_reconnect = 0;
 
 static void do_seagate_reconnect_intr (int irq, void *dev_id, struct pt_regs *regs)
 {
-  unsigned long flags;
+       unsigned long flags;
 
-  spin_lock_irqsave(&io_request_lock, flags);
-  seagate_reconnect_intr(irq, dev_id, regs);
-  spin_unlock_irqrestore(&io_request_lock, flags);
+       spin_lock_irqsave (&io_request_lock, flags);
+       seagate_reconnect_intr (irq, dev_id, regs);
+       spin_unlock_irqrestore (&io_request_lock, flags);
 }
 
 static void seagate_reconnect_intr (int irq, void *dev_id, struct pt_regs *regs)
 {
-  int temp;
-  Scsi_Cmnd *SCtmp;
-
-  DPRINTK (PHASE_RESELECT, "scsi%d : seagate_reconnect_intr() called\n", hostno);
-
-  if (!should_reconnect)
-    printk ("scsi%d: unexpected interrupt.\n", hostno);
-  else
-  {
-    should_reconnect = 0;
-
-    DPRINTK (PHASE_RESELECT, "scsi%d : internal_command("
-            "%d, %08x, %08x, RECONNECT_NOW\n", hostno,
-            current_target, current_data, current_bufflen);
-
-    temp = internal_command (current_target, current_lun, current_cmnd,
-                             current_data, current_bufflen, RECONNECT_NOW);
-
-    if (msg_byte (temp) != DISCONNECT)
-    {
-      if (done_fn)
-      {
-        DPRINTK (PHASE_RESELECT, "scsi%d : done_fn(%d,%08x)", hostno,
-                hostno, temp);
-        if (!SCint)
-          panic ("SCint == NULL in seagate");
-        SCtmp = SCint;
-        SCint = NULL;
-        SCtmp->result = temp;
-        done_fn (SCtmp);
-      }
-      else
-        printk ("done_fn() not defined.\n");
-    }
-  }
+       int temp;
+       Scsi_Cmnd *SCtmp;
+
+       DPRINTK (PHASE_RESELECT, "scsi%d : seagate_reconnect_intr() called\n",
+                hostno);
+
+       if (!should_reconnect)
+               printk ("scsi%d: unexpected interrupt.\n", hostno);
+       else {
+               should_reconnect = 0;
+
+               DPRINTK (PHASE_RESELECT, "scsi%d : internal_command("
+                        "%d, %08x, %08x, RECONNECT_NOW\n", hostno,
+                        current_target, current_data, current_bufflen);
+
+               temp =
+                   internal_command (current_target, current_lun, current_cmnd,
+                                     current_data, current_bufflen,
+                                     RECONNECT_NOW);
+
+               if (msg_byte (temp) != DISCONNECT) {
+                       if (done_fn) {
+                               DPRINTK (PHASE_RESELECT,
+                                        "scsi%d : done_fn(%d,%08x)", hostno,
+                                        hostno, temp);
+                               if (!SCint)
+                                       panic ("SCint == NULL in seagate");
+                               SCtmp = SCint;
+                               SCint = NULL;
+                               SCtmp->result = temp;
+                               done_fn (SCtmp);
+                       } else
+                               printk ("done_fn() not defined.\n");
+               }
+       }
 }
 
 /*
@@ -677,212 +683,215 @@ static int recursion_depth = 0;
 
 int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 {
-  int result, reconnect;
-  Scsi_Cmnd *SCtmp;
-
-  DANY( "seagate: que_command" );
-  done_fn = done;
-  current_target = SCpnt->target;
-  current_lun = SCpnt->lun;
-  (const void *) current_cmnd = SCpnt->cmnd;
-  current_data = (unsigned char *) SCpnt->request_buffer;
-  current_bufflen = SCpnt->request_bufflen;
-  SCint = SCpnt;
-  if (recursion_depth) return 0;
-  recursion_depth++;
-  do
-  {
+       int result, reconnect;
+       Scsi_Cmnd *SCtmp;
+
+       DANY ("seagate: que_command");
+       done_fn = done;
+       current_target = SCpnt->target;
+       current_lun = SCpnt->lun;
+       (const void *) current_cmnd = SCpnt->cmnd;
+       current_data = (unsigned char *) SCpnt->request_buffer;
+       current_bufflen = SCpnt->request_bufflen;
+       SCint = SCpnt;
+       if (recursion_depth)
+               return 0;
+       recursion_depth++;
+       do {
 #ifdef LINKED
 /*
  * Set linked command bit in control field of SCSI command.
  */
 
-    current_cmnd[SCpnt->cmd_len] |= 0x01;
-    if (linked_connected)
-    {
-      DPRINTK (DEBUG_LINKED, 
-              "scsi%d : using linked commands, current I_T_L nexus is ", hostno);
-      if ((linked_target == current_target) && (linked_lun == current_lun))
-      {
-        DPRINTK (DEBUG_LINKED, "correct\n");
-        reconnect = LINKED_RIGHT;
-      }
-      else
-      {
-        DPRINTK (DEBUG_LINKED, "incorrect\n");
-        reconnect = LINKED_WRONG;
-      }
-    }
-    else
-#endif /* LINKED */
-      reconnect = CAN_RECONNECT;
-
-    result = internal_command (SCint->target, SCint->lun, SCint->cmnd,
-                               SCint->request_buffer, SCint->request_bufflen, reconnect);
-    if (msg_byte (result) == DISCONNECT) break;
-    SCtmp = SCint;
-    SCint = NULL;
-    SCtmp->result = result;
-    done_fn (SCtmp);
-  }
-  while (SCint);
-  recursion_depth--;
-  return 0;
+               current_cmnd[SCpnt->cmd_len] |= 0x01;
+               if (linked_connected) {
+                       DPRINTK (DEBUG_LINKED,
+                                "scsi%d : using linked commands, current I_T_L nexus is ",
+                                hostno);
+                       if ((linked_target == current_target)
+                           && (linked_lun == current_lun)) {
+                               DPRINTK (DEBUG_LINKED, "correct\n");
+                               reconnect = LINKED_RIGHT;
+                       } else {
+                               DPRINTK (DEBUG_LINKED, "incorrect\n");
+                               reconnect = LINKED_WRONG;
+                       }
+               } else
+#endif                         /* LINKED */
+                       reconnect = CAN_RECONNECT;
+
+               result =
+                   internal_command (SCint->target, SCint->lun, SCint->cmnd,
+                                     SCint->request_buffer,
+                                     SCint->request_bufflen, reconnect);
+               if (msg_byte (result) == DISCONNECT)
+                       break;
+               SCtmp = SCint;
+               SCint = NULL;
+               SCtmp->result = result;
+               done_fn (SCtmp);
+       }
+       while (SCint);
+       recursion_depth--;
+       return 0;
 }
 
 int seagate_st0x_command (Scsi_Cmnd * SCpnt)
 {
-  return internal_command (SCpnt->target, SCpnt->lun, SCpnt->cmnd,
-                           SCpnt->request_buffer, SCpnt->request_bufflen,
-                           (int) NO_RECONNECT);
+       return internal_command (SCpnt->target, SCpnt->lun, SCpnt->cmnd,
+                                SCpnt->request_buffer, SCpnt->request_bufflen,
+                                (int) NO_RECONNECT);
 }
 
-static int internal_command (unsigned char target, unsigned char lun, 
-                             const void *cmnd, void *buff, int bufflen, int reselect)
+static int internal_command (unsigned char target, unsigned char lun,
+                 const void *cmnd, void *buff, int bufflen, int reselect)
 {
-  unsigned char *data = NULL;
-  struct scatterlist *buffer = NULL;
-  int clock, temp, nobuffs = 0, done = 0, len = 0;
-  unsigned long flags;
+       unsigned char *data = NULL;
+       struct scatterlist *buffer = NULL;
+       int clock, temp, nobuffs = 0, done = 0, len = 0;
+       unsigned long flags;
 
 #ifdef DEBUG
-  int transfered = 0, phase = 0, newphase;
+       int transfered = 0, phase = 0, newphase;
 #endif
 
-  register unsigned char status_read;
-  unsigned char tmp_data, tmp_control, status = 0, message = 0;
+       register unsigned char status_read;
+       unsigned char tmp_data, tmp_control, status = 0, message = 0;
 
-  unsigned transfersize = 0, underflow = 0;
+       unsigned transfersize = 0, underflow = 0;
 
 #ifdef SLOW_RATE
-  int borken = (int) SCint->device->borken; /* Does the current target require
-                                              Very Slow I/O ?  */
+       int borken = (int) SCint->device->borken;       /* Does the current target require
+                                                          Very Slow I/O ?  */
 #endif
 
-  incommand = 0;
-  st0x_aborted = 0;
+       incommand = 0;
+       st0x_aborted = 0;
 
 #if (DEBUG & PRINT_COMMAND)
-  printk ("scsi%d : target = %d, command = ", hostno, target);
-  print_command ((unsigned char *) cmnd);
+       printk ("scsi%d : target = %d, command = ", hostno, target);
+       print_command ((unsigned char *) cmnd);
 #endif
 
 #if (DEBUG & PHASE_RESELECT)
-  switch (reselect)
-  {
-    case RECONNECT_NOW:
-      printk ("scsi%d : reconnecting\n", hostno);
-      break;
+       switch (reselect) {
+       case RECONNECT_NOW:
+               printk ("scsi%d : reconnecting\n", hostno);
+               break;
 #ifdef LINKED
-    case LINKED_RIGHT:
-      printk ("scsi%d : connected, can reconnect\n", hostno);
-      break;
-    case LINKED_WRONG:
-      printk ("scsi%d : connected to wrong target, can reconnect\n", hostno);
-      break;
+       case LINKED_RIGHT:
+               printk ("scsi%d : connected, can reconnect\n", hostno);
+               break;
+       case LINKED_WRONG:
+               printk ("scsi%d : connected to wrong target, can reconnect\n",
+                       hostno);
+               break;
 #endif
-    case CAN_RECONNECT:
-      printk ("scsi%d : allowed to reconnect\n", hostno);
-      break;
-    default:
-      printk ("scsi%d : not allowed to reconnect\n", hostno);
-  }
+       case CAN_RECONNECT:
+               printk ("scsi%d : allowed to reconnect\n", hostno);
+               break;
+       default:
+               printk ("scsi%d : not allowed to reconnect\n", hostno);
+       }
 #endif
 
-  if (target == (controller_type == SEAGATE ? 7 : 6))
-    return DID_BAD_TARGET;
+       if (target == (controller_type == SEAGATE ? 7 : 6))
+               return DID_BAD_TARGET;
 
 /*
- *    We work it differently depending on if this is is "the first time,"
+ *     We work it differently depending on if this is is "the first time,"
  *      or a reconnect.  If this is a reselect phase, then SEL will
  *      be asserted, and we must skip selection / arbitration phases.
  */
 
-  switch (reselect)
-  {
-    case RECONNECT_NOW:
-      DPRINTK ( PHASE_RESELECT, "scsi%d : phase RESELECT \n", hostno);
+       switch (reselect) {
+       case RECONNECT_NOW:
+               DPRINTK (PHASE_RESELECT, "scsi%d : phase RESELECT \n", hostno);
 
 /*
- *    At this point, we should find the logical or of our ID and the original
+ *     At this point, we should find the logical or of our ID and the original
  *      target's ID on the BUS, with BSY, SEL, and I/O signals asserted.
  *
  *      After ARBITRATION phase is completed, only SEL, BSY, and the
  *      target ID are asserted.  A valid initiator ID is not on the bus
  *      until IO is asserted, so we must wait for that.
  */
-      ULOOP( 100*1000 ) {
-        temp = STATUS;
-        if ((temp & STAT_IO) && !(temp & STAT_BSY))
-          break;
-
-        if (TIMEOUT) {
-          DPRINTK (PHASE_RESELECT, 
-                  "scsi%d : RESELECT timed out while waiting for IO .\n", hostno);
-          return (DID_BAD_INTR << 16);
-        }
-      }
+               ULOOP (100 * 1000) {
+                       temp = STATUS;
+                       if ((temp & STAT_IO) && !(temp & STAT_BSY))
+                               break;
+
+                       if (TIMEOUT) {
+                               DPRINTK (PHASE_RESELECT,
+                                        "scsi%d : RESELECT timed out while waiting for IO .\n",
+                                        hostno);
+                               return (DID_BAD_INTR << 16);
+                       }
+               }
 
 /*
- *    After I/O is asserted by the target, we can read our ID and its
+ *     After I/O is asserted by the target, we can read our ID and its
  *      ID off of the BUS.
  */
 
-      if (!((temp = DATA) & (controller_type == SEAGATE ? 0x80 : 0x40)))
-      {
-        DPRINTK (PHASE_RESELECT,
-                "scsi%d : detected reconnect request to different target.\n"
-                "\tData bus = %d\n", hostno, temp);
-        return (DID_BAD_INTR << 16);
-      }
-
-      if (!(temp & (1 << current_target)))
-      {
-        printk ("scsi%d : Unexpected reselect interrupt.  Data bus = %d\n",
-                hostno, temp);
-        return (DID_BAD_INTR << 16);
-      }
-
-      buffer = current_buffer;
-      cmnd = current_cmnd;              /* WDE add */
-      data = current_data;              /* WDE add */
-      len = current_bufflen;            /* WDE add */
-      nobuffs = current_nobuffs;
+               if (!
+                   ((temp =
+                     DATA) & (controller_type == SEAGATE ? 0x80 : 0x40))) {
+                       DPRINTK (PHASE_RESELECT,
+                                "scsi%d : detected reconnect request to different target.\n"
+                                "\tData bus = %d\n", hostno, temp);
+                       return (DID_BAD_INTR << 16);
+               }
+
+               if (!(temp & (1 << current_target))) {
+                       printk
+                           ("scsi%d : Unexpected reselect interrupt.  Data bus = %d\n",
+                            hostno, temp);
+                       return (DID_BAD_INTR << 16);
+               }
+
+               buffer = current_buffer;
+               cmnd = current_cmnd;    /* WDE add */
+               data = current_data;    /* WDE add */
+               len = current_bufflen;  /* WDE add */
+               nobuffs = current_nobuffs;
 
 /*
- *    We have determined that we have been selected.  At this point,
+ *     We have determined that we have been selected.  At this point,
  *      we must respond to the reselection by asserting BSY ourselves
  */
 
 #if 1
-      WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE | CMD_BSY);
+               WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE | CMD_BSY);
 #else
-      WRITE_CONTROL (BASE_CMD | CMD_BSY);
+               WRITE_CONTROL (BASE_CMD | CMD_BSY);
 #endif
 
 /*
- *    The target will drop SEL, and raise BSY, at which time we must drop
+ *     The target will drop SEL, and raise BSY, at which time we must drop
  *      BSY.
  */
 
-      ULOOP( 100*1000 ) {
-       if (!(STATUS & STAT_SEL)) break;
-       if (TIMEOUT) {
-         WRITE_CONTROL (BASE_CMD | CMD_INTR);
-         DPRINTK (PHASE_RESELECT,
-                  "scsi%d : RESELECT timed out while waiting for SEL.\n", hostno);
-         return (DID_BAD_INTR << 16);
-       }
-      }
+               ULOOP (100 * 1000) {
+                       if (!(STATUS & STAT_SEL))
+                               break;
+                       if (TIMEOUT) {
+                               WRITE_CONTROL (BASE_CMD | CMD_INTR);
+                               DPRINTK (PHASE_RESELECT,
+                                        "scsi%d : RESELECT timed out while waiting for SEL.\n",
+                                        hostno);
+                               return (DID_BAD_INTR << 16);
+                       }
+               }
 
-      WRITE_CONTROL (BASE_CMD);
+               WRITE_CONTROL (BASE_CMD);
 
 /*
- *    At this point, we have connected with the target and can get
+ *     At this point, we have connected with the target and can get
  *      on with our lives.
  */
-      break;
-    case CAN_RECONNECT:
+               break;
+       case CAN_RECONNECT:
 
 #ifdef LINKED
 /*
@@ -892,11 +901,12 @@ static int internal_command (unsigned char target, unsigned char lun,
  * message on MESSAGE OUT phase, and then loop back to here.
  */
 
-    connect_loop:
+             connect_loop:
 
 #endif
 
-      DPRINTK (PHASE_BUS_FREE, "scsi%d : phase = BUS FREE \n", hostno);
+               DPRINTK (PHASE_BUS_FREE, "scsi%d : phase = BUS FREE \n",
+                        hostno);
 
 /*
  *    BUS FREE PHASE
@@ -909,21 +919,22 @@ static int internal_command (unsigned char target, unsigned char lun,
 
 #ifndef ARBITRATE
 #error FIXME: this is broken: we may not use jiffies here - we are under cli(). It will hardlock.
-      clock = jiffies + ST0X_BUS_FREE_DELAY;
+               clock = jiffies + ST0X_BUS_FREE_DELAY;
 
-      while (((STATUS | STATUS | STATUS) &
-              (STAT_BSY | STAT_SEL)) &&
-             (!st0x_aborted) && time_before(jiffies, clock));
+               while (((STATUS | STATUS | STATUS) &
+                       (STAT_BSY | STAT_SEL)) &&
+                      (!st0x_aborted) && time_before (jiffies, clock)) ;
 
-      if (time_after(jiffies, clock))
-        return retcode (DID_BUS_BUSY);
-      else if (st0x_aborted)
-        return retcode (st0x_aborted);
+               if (time_after (jiffies, clock))
+                       return retcode (DID_BUS_BUSY);
+               else if (st0x_aborted)
+                       return retcode (st0x_aborted);
 #endif
 
-      DPRINTK (PHASE_SELECTION, "scsi%d : phase = SELECTION\n", hostno);
+               DPRINTK (PHASE_SELECTION, "scsi%d : phase = SELECTION\n",
+                        hostno);
 
-      clock = jiffies + ST0X_SELECTION_DELAY;
+               clock = jiffies + ST0X_SELECTION_DELAY;
 
 /*
  * Arbitration/selection procedure :
@@ -937,26 +948,30 @@ static int internal_command (unsigned char target, unsigned char lun,
  */
 
 #ifdef ARBITRATE
-      save_flags (flags);
-      cli ();
-      WRITE_CONTROL (0);
-      WRITE_DATA ((controller_type == SEAGATE) ? 0x80 : 0x40);
-      WRITE_CONTROL (CMD_START_ARB);
-      restore_flags (flags);
-
-      ULOOP( ST0X_SELECTION_DELAY * 10000 ) {
-       status_read = STATUS;
-       if (status_read & STAT_ARB_CMPL) break;
-       if (st0x_aborted)       /* FIXME: What? We are going to do something even after abort? */
-          break;
-       if (TIMEOUT || (status_read & STAT_SEL)) {
-         printk( "scsi%d : arbitration lost or timeout.\n", hostno );
-         WRITE_CONTROL (BASE_CMD);
-         return retcode (DID_NO_CONNECT);
-       }
-      }
-
-      DPRINTK (PHASE_SELECTION, "scsi%d : arbitration complete\n", hostno);
+               save_flags (flags);
+               cli ();
+               WRITE_CONTROL (0);
+               WRITE_DATA ((controller_type == SEAGATE) ? 0x80 : 0x40);
+               WRITE_CONTROL (CMD_START_ARB);
+               restore_flags (flags);
+
+               ULOOP (ST0X_SELECTION_DELAY * 10000) {
+                       status_read = STATUS;
+                       if (status_read & STAT_ARB_CMPL)
+                               break;
+                       if (st0x_aborted)       /* FIXME: What? We are going to do something even after abort? */
+                               break;
+                       if (TIMEOUT || (status_read & STAT_SEL)) {
+                               printk
+                                   ("scsi%d : arbitration lost or timeout.\n",
+                                    hostno);
+                               WRITE_CONTROL (BASE_CMD);
+                               return retcode (DID_NO_CONNECT);
+                       }
+               }
+
+               DPRINTK (PHASE_SELECTION, "scsi%d : arbitration complete\n",
+                        hostno);
 #endif
 
 /*
@@ -971,92 +986,103 @@ static int internal_command (unsigned char target, unsigned char lun,
  *    try this with a SCSI protocol or logic analyzer to see what is
  *    going on.
  */
-       tmp_data = (unsigned char) ((1 << target) | (controller_type == SEAGATE ? 0x80 : 0x40));
-       tmp_control = BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL | (reselect ? CMD_ATTN : 0);
-
-       save_flags(flags);
-       cli();
+               tmp_data =
+                   (unsigned char) ((1 << target) |
+                                    (controller_type ==
+                                     SEAGATE ? 0x80 : 0x40));
+               tmp_control =
+                   BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL | (reselect ? CMD_ATTN
+                                                           : 0);
+
+               save_flags (flags);
+               cli ();
 #ifdef OLDCNTDATASCEME
 #ifdef SWAPCNTDATA
-       WRITE_CONTROL (tmp_control);
-       WRITE_DATA (tmp_data);
+               WRITE_CONTROL (tmp_control);
+               WRITE_DATA (tmp_data);
 #else
-       WRITE_DATA (tmp_data);
-       WRITE_CONTROL (tmp_control);
+               WRITE_DATA (tmp_data);
+               WRITE_CONTROL (tmp_control);
 #endif
 #else
-       tmp_control ^= CMD_BSY;         /* This is guesswork. What used to be in driver    */
-       WRITE_CONTROL (tmp_control);    /* could never work: it sent data into control     */
-       WRITE_DATA (tmp_data);          /* register and control info into data. Hopefully  */
-       tmp_control ^= CMD_BSY;         /* fixed, but order of first two may be wrong.     */
-       WRITE_CONTROL (tmp_control);                                  /* -- pavel@ucw.cz   */
-#endif       
-
+               tmp_control ^= CMD_BSY; /* This is guesswork. What used to be in driver    */
+               WRITE_CONTROL (tmp_control);    /* could never work: it sent data into control     */
+               WRITE_DATA (tmp_data);  /* register and control info into data. Hopefully  */
+               tmp_control ^= CMD_BSY; /* fixed, but order of first two may be wrong.     */
+               WRITE_CONTROL (tmp_control);    /* -- pavel@ucw.cz   */
+#endif
 
-       restore_flags (flags);
+               restore_flags (flags);
 
-       ULOOP( 250*1000 ) {
-        if (st0x_aborted) {
+               ULOOP (250 * 1000) {
+                       if (st0x_aborted) {
 /*
- *    If we have been aborted, and we have a command in progress, IE the
+ *     If we have been aborted, and we have a command in progress, IE the
  *      target still has BSY asserted, then we will reset the bus, and
  *      notify the midlevel driver to expect sense.
  */
 
-          WRITE_CONTROL (BASE_CMD);
-          if (STATUS & STAT_BSY) {
-            printk ("scsi%d : BST asserted after we've been aborted.\n", hostno);
-            seagate_st0x_reset (NULL, 0);
-            return retcode (DID_RESET);
-          }
-          return retcode (st0x_aborted);
-        }
-        if (STATUS & STAT_BSY) break;
-        if (TIMEOUT) {
-          DPRINTK (PHASE_SELECTION, "scsi%d : NO CONNECT with target %d, stat = %x \n",
-                   hostno, target, STATUS);
-          return retcode (DID_NO_CONNECT);
-        }
-       }
+                               WRITE_CONTROL (BASE_CMD);
+                               if (STATUS & STAT_BSY) {
+                                       printk
+                                           ("scsi%d : BST asserted after we've been aborted.\n",
+                                            hostno);
+                                       seagate_st0x_reset (NULL, 0);
+                                       return retcode (DID_RESET);
+                               }
+                               return retcode (st0x_aborted);
+                       }
+                       if (STATUS & STAT_BSY)
+                               break;
+                       if (TIMEOUT) {
+                               DPRINTK (PHASE_SELECTION,
+                                        "scsi%d : NO CONNECT with target %d, stat = %x \n",
+                                        hostno, target, STATUS);
+                               return retcode (DID_NO_CONNECT);
+                       }
+               }
 
 /* Establish current pointers.  Take into account scatter / gather */
 
-      if ((nobuffs = SCint->use_sg))
-      {
+               if ((nobuffs = SCint->use_sg)) {
 #if (DEBUG & DEBUG_SG)
-        {
-          int i;
-
-          printk ("scsi%d : scatter gather requested, using %d buffers.\n",
-                  hostno, nobuffs);
-          for (i = 0; i < nobuffs; ++i)
-            printk ("scsi%d : buffer %d address = %08x length = %d\n",
-                    hostno, i, buffer[i].address, buffer[i].length);
-        }
+                       {
+                               int i;
+
+                               printk
+                                   ("scsi%d : scatter gather requested, using %d buffers.\n",
+                                    hostno, nobuffs);
+                               for (i = 0; i < nobuffs; ++i)
+                                       printk
+                                           ("scsi%d : buffer %d address = %08x length = %d\n",
+                                            hostno, i, buffer[i].address,
+                                            buffer[i].length);
+                       }
 #endif
 
-        buffer = (struct scatterlist *) SCint->buffer;
-        len = buffer->length;
-        data = (unsigned char *) buffer->address;
-      }
-      else
-      {
-        DPRINTK (DEBUG_SG, "scsi%d : scatter gather not requested.\n", hostno);
-        buffer = NULL;
-        len = SCint->request_bufflen;
-        data = (unsigned char *) SCint->request_buffer;
-      }
-
-      DPRINTK (PHASE_DATAIN | PHASE_DATAOUT, "scsi%d : len = %d\n", hostno, len);
-
-      break;
+                       buffer = (struct scatterlist *) SCint->buffer;
+                       len = buffer->length;
+                       data = (unsigned char *) buffer->address;
+               } else {
+                       DPRINTK (DEBUG_SG,
+                                "scsi%d : scatter gather not requested.\n",
+                                hostno);
+                       buffer = NULL;
+                       len = SCint->request_bufflen;
+                       data = (unsigned char *) SCint->request_buffer;
+               }
+
+               DPRINTK (PHASE_DATAIN | PHASE_DATAOUT, "scsi%d : len = %d\n",
+                        hostno, len);
+
+               break;
 #ifdef LINKED
-    case LINKED_RIGHT:
-      break;
-    case LINKED_WRONG:
-      break;
+       case LINKED_RIGHT:
+               break;
+       case LINKED_WRONG:
+               break;
 #endif
-  }                                     /* end of switch(reselect) */
+       }                       /* end of switch(reselect) */
 
 /*
  *    There are several conditions under which we wish to send a message :
@@ -1069,14 +1095,14 @@ static int internal_command (unsigned char target, unsigned char lun,
 
 /* GCC does not like an ifdef inside a macro, so do it the hard way. */
 #ifdef LINKED
-  WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE |
-                 (((reselect == CAN_RECONNECT)
-                   || (reselect == LINKED_WRONG)
-                  )? CMD_ATTN : 0));
+       WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE |
+                      (((reselect == CAN_RECONNECT)
+                        || (reselect == LINKED_WRONG)
+                       )? CMD_ATTN : 0));
 #else
-  WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE |
-                 (((reselect == CAN_RECONNECT)
-                  )? CMD_ATTN : 0));
+       WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE |
+                      (((reselect == CAN_RECONNECT)
+                       )? CMD_ATTN : 0));
 #endif
 
 /*
@@ -1091,134 +1117,145 @@ static int internal_command (unsigned char target, unsigned char lun,
  *
  */
 
-  DPRINTK (PHASE_ETC, "scsi%d : phase = INFORMATION TRANSFER\n", hostno);
+       DPRINTK (PHASE_ETC, "scsi%d : phase = INFORMATION TRANSFER\n", hostno);
 
-  incommand = 1;
-  transfersize = SCint->transfersize;
-  underflow = SCint->underflow;
+       incommand = 1;
+       transfersize = SCint->transfersize;
+       underflow = SCint->underflow;
 
 /*
- *    Now, we poll the device for status information,
+ *     Now, we poll the device for status information,
  *      and handle any requests it makes.  Note that since we are unsure of
  *      how much data will be flowing across the system, etc and cannot
  *      make reasonable timeouts, that we will instead have the midlevel
  *      driver handle any timeouts that occur in this phase.
  */
 
-  while (((status_read = STATUS) & STAT_BSY) && !st0x_aborted && !done)
-  {
+       while (((status_read = STATUS) & STAT_BSY) && !st0x_aborted && !done) {
 #ifdef PARITY
-    if (status_read & STAT_PARITY)
-    {
-      printk ("scsi%d : got parity error\n", hostno);
-      st0x_aborted = DID_PARITY;
-    }
+               if (status_read & STAT_PARITY) {
+                       printk ("scsi%d : got parity error\n", hostno);
+                       st0x_aborted = DID_PARITY;
+               }
 #endif
 
-    if (status_read & STAT_REQ)
-    {
+               if (status_read & STAT_REQ) {
 #if ((DEBUG & PHASE_ETC) == PHASE_ETC)
-      if ((newphase = (status_read & REQ_MASK)) != phase)
-      {
-        phase = newphase;
-        switch (phase)
-        {
-          case REQ_DATAOUT:
-            printk ("scsi%d : phase = DATA OUT\n", hostno);
-            break;
-          case REQ_DATAIN:
-            printk ("scsi%d : phase = DATA IN\n", hostno);
-            break;
-          case REQ_CMDOUT:
-            printk ("scsi%d : phase = COMMAND OUT\n", hostno);
-            break;
-          case REQ_STATIN:
-            printk ("scsi%d : phase = STATUS IN\n", hostno);
-            break;
-          case REQ_MSGOUT:
-            printk ("scsi%d : phase = MESSAGE OUT\n", hostno);
-            break;
-          case REQ_MSGIN:
-            printk ("scsi%d : phase = MESSAGE IN\n", hostno);
-            break;
-          default:
-            printk ("scsi%d : phase = UNKNOWN\n", hostno);
-            st0x_aborted = DID_ERROR;
-        }
-      }
+                       if ((newphase = (status_read & REQ_MASK)) != phase) {
+                               phase = newphase;
+                               switch (phase) {
+                               case REQ_DATAOUT:
+                                       printk ("scsi%d : phase = DATA OUT\n",
+                                               hostno);
+                                       break;
+                               case REQ_DATAIN:
+                                       printk ("scsi%d : phase = DATA IN\n",
+                                               hostno);
+                                       break;
+                               case REQ_CMDOUT:
+                                       printk
+                                           ("scsi%d : phase = COMMAND OUT\n",
+                                            hostno);
+                                       break;
+                               case REQ_STATIN:
+                                       printk ("scsi%d : phase = STATUS IN\n",
+                                               hostno);
+                                       break;
+                               case REQ_MSGOUT:
+                                       printk
+                                           ("scsi%d : phase = MESSAGE OUT\n",
+                                            hostno);
+                                       break;
+                               case REQ_MSGIN:
+                                       printk ("scsi%d : phase = MESSAGE IN\n",
+                                               hostno);
+                                       break;
+                               default:
+                                       printk ("scsi%d : phase = UNKNOWN\n",
+                                               hostno);
+                                       st0x_aborted = DID_ERROR;
+                               }
+                       }
 #endif
-      switch (status_read & REQ_MASK)
-      {
-        case REQ_DATAOUT:
+                       switch (status_read & REQ_MASK) {
+                       case REQ_DATAOUT:
 /*
  * If we are in fast mode, then we simply splat the data out
  * in word-sized chunks as fast as we can.
  */
 
-          if (!len)
-          {
+                               if (!len) {
 #if 0
-            printk ("scsi%d: underflow to target %d lun %d \n", hostno, target, lun);
-            st0x_aborted = DID_ERROR;
-            fast = 0;
+                                       printk
+                                           ("scsi%d: underflow to target %d lun %d \n",
+                                            hostno, target, lun);
+                                       st0x_aborted = DID_ERROR;
+                                       fast = 0;
 #endif
-            break;
-          }
+                                       break;
+                               }
 
-          if (fast && transfersize && !(len % transfersize)
-              && (len >= transfersize)
+                               if (fast && transfersize
+                                   && !(len % transfersize)
+                                   && (len >= transfersize)
 #ifdef FAST32
-              && !(transfersize % 4)
+                                   && !(transfersize % 4)
 #endif
-            )
-          {
-            DPRINTK (DEBUG_FAST,
-                    "scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
-                    "         len = %d, data = %08x\n",
-                  hostno, SCint->underflow, SCint->transfersize, len, data);
+                                   ) {
+                                       DPRINTK (DEBUG_FAST,
+                                                "scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
+                                                "         len = %d, data = %08x\n",
+                                                hostno, SCint->underflow,
+                                                SCint->transfersize, len,
+                                                data);
 
 /* SJT: Start. Fast Write */
 #ifdef SEAGATE_USE_ASM
-            __asm__(
-                "cld\n\t"
+                                       __asm__ ("cld\n\t"
 #ifdef FAST32
-                "shr $2, %%ecx\n\t"
-                "1:\t"
-                "lodsl\n\t"
-                "movl %%eax, (%%edi)\n\t"
+                                                "shr $2, %%ecx\n\t"
+                                                "1:\t"
+                                                "lodsl\n\t"
+                                                "movl %%eax, (%%edi)\n\t"
 #else
-                "1:\t"
-                "lodsb\n\t"
-                "movb %%al, (%%edi)\n\t"
+                                                "1:\t"
+                                                "lodsb\n\t"
+                                                "movb %%al, (%%edi)\n\t"
 #endif
-                "loop 1b;"
-/* output */    :
-/* input */     : "D" (phys_to_virt(st0x_dr)), "S" (data), "c" (SCint->transfersize) 
-/* clobbered */ : "eax", "ecx", "esi" );
-#else /* SEAGATE_USE_ASM */
-            {
+                                                "loop 1b;"
+                                     /* output */ :
+                                     /* input */ :"D" (phys_to_virt (st0x_dr)),
+                                                "S"
+                                                (data),
+                                                "c" (SCint->transfersize)
+/* clobbered */
+                                     :  "eax", "ecx",
+                                                "esi");
+#else                          /* SEAGATE_USE_ASM */
+                                       {
 #ifdef FAST32
-              unsigned int *iop = phys_to_virt (st0x_dr);
-              const unsigned int *dp = (unsigned int *) data;
-              int xferlen = transfersize >> 2;
+                                               unsigned int *iop =
+                                                   phys_to_virt (st0x_dr);
+                                               const unsigned int *dp =
+                                                   (unsigned int *) data;
+                                               int xferlen = transfersize >> 2;
 #else
-              unsigned char *iop = phys_to_virt (st0x_dr);
-              const unsigned char *dp = data;
-              int xferlen = transfersize;
+                                               unsigned char *iop =
+                                                   phys_to_virt (st0x_dr);
+                                               const unsigned char *dp = data;
+                                               int xferlen = transfersize;
 #endif
-              for (; xferlen; --xferlen)
-                *iop = *dp++;
-            }
-#endif /* SEAGATE_USE_ASM */
+                                               for (; xferlen; --xferlen)
+                                                       *iop = *dp++;
+                                       }
+#endif                         /* SEAGATE_USE_ASM */
 /* SJT: End */
-            len -= transfersize;
-            data += transfersize;
-            DPRINTK (DEBUG_FAST,
-                    "scsi%d : FAST transfer complete len = %d data = %08x\n",
-                    hostno, len, data);
-          }
-          else
-          {
+                                       len -= transfersize;
+                                       data += transfersize;
+                                       DPRINTK (DEBUG_FAST,
+                                                "scsi%d : FAST transfer complete len = %d data = %08x\n",
+                                                hostno, len, data);
+                               } else {
 /*
  *    We loop as long as we are in a data out phase, there is data to send,
  *      and BSY is still active.
@@ -1227,7 +1264,7 @@ static int internal_command (unsigned char target, unsigned char lun,
 /* SJT: Start. Slow Write. */
 #ifdef SEAGATE_USE_ASM
 
-int __dummy_1,__dummy_2;
+                                       int __dummy_1, __dummy_2;
 
 /*
  *      We loop as long as we are in a data out phase, there is data to send, 
@@ -1236,159 +1273,173 @@ int __dummy_1,__dummy_2;
 /* Local variables : len = ecx , data = esi, 
                      st0x_cr_sr = ebx, st0x_dr =  edi
 */
-            __asm__ (
-            /* Test for any data here at all. */
-                    "orl %%ecx, %%ecx\n\t"
-                    "jz 2f\n\t"
-                    "cld\n\t"
+                                       __asm__ (
+                                                       /* Test for any data here at all. */
+                                                       "orl %%ecx, %%ecx\n\t"
+                                                       "jz 2f\n\t" "cld\n\t"
 /*                    "movl " SYMBOL_NAME_STR(st0x_cr_sr) ", %%ebx\n\t"  */
 /*                    "movl " SYMBOL_NAME_STR(st0x_dr) ", %%edi\n\t"  */
-                "1:\t"
-                    "movb (%%ebx), %%al\n\t"
-            /* Test for BSY */
-                    "test $1, %%al\n\t"
-                    "jz 2f\n\t"
-            /* Test for data out phase - STATUS & REQ_MASK should be 
-               REQ_DATAOUT, which is 0. */
-                    "test $0xe, %%al\n\t"
-                    "jnz 2f\n\t"
-            /* Test for REQ */      
-                    "test $0x10, %%al\n\t"
-                    "jz 1b\n\t"
-                    "lodsb\n\t"
-                    "movb %%al, (%%edi)\n\t"
-                    "loop 1b\n\t"
-                "2:\n"
-/* output */    : "=S" (data), "=c" (len)  ,"=b" (__dummy_1) ,"=D" (__dummy_2)
-/* input */     : "0" (data), "1" (len), "2" (phys_to_virt(st0x_cr_sr)), "3" (phys_to_virt(st0x_dr)) 
-/* clobbered */ : "eax"); 
-#else /* SEAGATE_USE_ASM */
-            while (len)
-            {
-              unsigned char stat;
-
-              stat = STATUS;
-              if (!(stat & STAT_BSY) || ((stat & REQ_MASK) != REQ_DATAOUT))
-                break;
-              if (stat & STAT_REQ)
-              {
-                WRITE_DATA (*data++);
-                --len;
-              }
-            }
-#endif /* SEAGATE_USE_ASM */
+                                                       "1:\t"
+                                                       "movb (%%ebx), %%al\n\t"
+                                                       /* Test for BSY */
+                                                       "test $1, %%al\n\t"
+                                                       "jz 2f\n\t"
+                                                       /* Test for data out phase - STATUS & REQ_MASK should be 
+                                                          REQ_DATAOUT, which is 0. */
+                                                       "test $0xe, %%al\n\t"
+                                                       "jnz 2f\n\t"
+                                                       /* Test for REQ */
+                                                       "test $0x10, %%al\n\t"
+                                                       "jz 1b\n\t"
+                                                       "lodsb\n\t"
+                                                       "movb %%al, (%%edi)\n\t"
+                                                       "loop 1b\n\t" "2:\n"
+                                     /* output */ :"=S" (data), "=c" (len),
+                                                       "=b"
+                                                       (__dummy_1),
+                                                       "=D" (__dummy_2)
+/* input */
+                                     :         "0" (data), "1" (len),
+                                                       "2" (phys_to_virt
+                                                            (st0x_cr_sr)),
+                                                       "3" (phys_to_virt
+                                                            (st0x_dr))
+/* clobbered */
+                                     :         "eax");
+#else                          /* SEAGATE_USE_ASM */
+                                       while (len) {
+                                               unsigned char stat;
+
+                                               stat = STATUS;
+                                               if (!(stat & STAT_BSY)
+                                                   || ((stat & REQ_MASK) !=
+                                                       REQ_DATAOUT))
+                                                       break;
+                                               if (stat & STAT_REQ) {
+                                                       WRITE_DATA (*data++);
+                                                       --len;
+                                               }
+                                       }
+#endif                         /* SEAGATE_USE_ASM */
 /* SJT: End. */
-          }
-
-          if (!len && nobuffs)
-          {
-            --nobuffs;
-            ++buffer;
-            len = buffer->length;
-            data = (unsigned char *) buffer->address;
-            DPRINTK (DEBUG_SG,
-                   "scsi%d : next scatter-gather buffer len = %d address = %08x\n",
-                    hostno, len, data);
-          }
-          break;
-
-        case REQ_DATAIN:
+                               }
+
+                               if (!len && nobuffs) {
+                                       --nobuffs;
+                                       ++buffer;
+                                       len = buffer->length;
+                                       data =
+                                           (unsigned char *) buffer->address;
+                                       DPRINTK (DEBUG_SG,
+                                                "scsi%d : next scatter-gather buffer len = %d address = %08x\n",
+                                                hostno, len, data);
+                               }
+                               break;
+
+                       case REQ_DATAIN:
 #ifdef SLOW_RATE
-          if (borken)
-          {
+                               if (borken) {
 #if (DEBUG & (PHASE_DATAIN))
-            transfered += len;
+                                       transfered += len;
 #endif
-            for (;
-                 len && (STATUS & (REQ_MASK | STAT_REQ)) == (REQ_DATAIN |
-                                                             STAT_REQ)
-                 ; --len)
-            {
-              *data++ = DATA;
-              borken_wait ();
-            }
+                                       for (;
+                                            len
+                                            && (STATUS & (REQ_MASK | STAT_REQ))
+                                            == (REQ_DATAIN | STAT_REQ);
+                                            --len) {
+                                               *data++ = DATA;
+                                               borken_wait ();
+                                       }
 #if (DEBUG & (PHASE_DATAIN))
-            transfered -= len;
+                                       transfered -= len;
 #endif
-          }
-          else
+                               } else
 #endif
 
-            if (fast && transfersize && !(len % transfersize) &&
-                (len >= transfersize)
+                                       if (fast && transfersize
+                                           && !(len % transfersize)
+                                           && (len >= transfersize)
 #ifdef FAST32
-                && !(transfersize % 4)
+                                           && !(transfersize % 4)
 #endif
-            )
-          {
-            DPRINTK (DEBUG_FAST,
-                    "scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
-                    "         len = %d, data = %08x\n",
-                  hostno, SCint->underflow, SCint->transfersize, len, data);
+                                   ) {
+                                       DPRINTK (DEBUG_FAST,
+                                                "scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
+                                                "         len = %d, data = %08x\n",
+                                                hostno, SCint->underflow,
+                                                SCint->transfersize, len,
+                                                data);
 
 /* SJT: Start. Fast Read */
 #ifdef SEAGATE_USE_ASM
-            __asm__(
-                    "cld\n\t"
+                                       __asm__ ("cld\n\t"
 #ifdef FAST32
-                    "shr $2, %%ecx\n\t"
-                "1:\t"
-                    "movl (%%esi), %%eax\n\t"
-                    "stosl\n\t"
+                                                "shr $2, %%ecx\n\t"
+                                                "1:\t"
+                                                "movl (%%esi), %%eax\n\t"
+                                                "stosl\n\t"
 #else
-                "1:\t"
-                    "movb (%%esi), %%al\n\t"
-                    "stosb\n\t"
+                                                "1:\t"
+                                                "movb (%%esi), %%al\n\t"
+                                                "stosb\n\t"
 #endif
-                    "loop 1b\n\t"
-/* output */        : 
-/* input */         : "S" (phys_to_virt(st0x_dr)), "D" (data), "c" (SCint->transfersize) 
-/* clobbered */     : "eax", "ecx", "edi");
-#else /* SEAGATE_USE_ASM */
-            {
+                                                "loop 1b\n\t"
+                                     /* output */ :
+                                     /* input */ :"S" (phys_to_virt (st0x_dr)),
+                                                "D"
+                                                (data),
+                                                "c" (SCint->transfersize)
+/* clobbered */
+                                     :  "eax", "ecx",
+                                                "edi");
+#else                          /* SEAGATE_USE_ASM */
+                                       {
 #ifdef FAST32
-              const unsigned int *iop = phys_to_virt (st0x_dr);
-              unsigned int *dp = (unsigned int *) data;
-              int xferlen = len >> 2;
+                                               const unsigned int *iop =
+                                                   phys_to_virt (st0x_dr);
+                                               unsigned int *dp =
+                                                   (unsigned int *) data;
+                                               int xferlen = len >> 2;
 #else
-              const unsigned char *iop = phys_to_virt (st0x_dr);
-              unsigned char *dp = data;
-              int xferlen = len;
+                                               const unsigned char *iop =
+                                                   phys_to_virt (st0x_dr);
+                                               unsigned char *dp = data;
+                                               int xferlen = len;
 #endif
-              for (; xferlen; --xferlen)
-                *dp++ = *iop;
-            }
-#endif /* SEAGATE_USE_ASM */
+                                               for (; xferlen; --xferlen)
+                                                       *dp++ = *iop;
+                                       }
+#endif                         /* SEAGATE_USE_ASM */
 /* SJT: End */
-            len -= transfersize;
-            data += transfersize;
+                                       len -= transfersize;
+                                       data += transfersize;
 #if (DEBUG & PHASE_DATAIN)
-            printk ("scsi%d: transfered += %d\n", hostno, transfersize);
-            transfered += transfersize;
+                                       printk ("scsi%d: transfered += %d\n",
+                                               hostno, transfersize);
+                                       transfered += transfersize;
 #endif
 
-            DPRINTK (DEBUG_FAST,
-                    "scsi%d : FAST transfer complete len = %d data = %08x\n",
-                    hostno, len, data);
-          }
-          else
-          {
+                                       DPRINTK (DEBUG_FAST,
+                                                "scsi%d : FAST transfer complete len = %d data = %08x\n",
+                                                hostno, len, data);
+                               } else {
 
 #if (DEBUG & PHASE_DATAIN)
-            printk ("scsi%d: transfered += %d\n", hostno, len);
-            transfered += len;          /* Assume we'll transfer it all, then
-                                           subtract what we *didn't* transfer */
+                                       printk ("scsi%d: transfered += %d\n",
+                                               hostno, len);
+                                       transfered += len;      /* Assume we'll transfer it all, then
+                                                                  subtract what we *didn't* transfer */
 #endif
 
 /*
- *    We loop as long as we are in a data in phase, there is room to read,
+ *     We loop as long as we are in a data in phase, there is room to read,
  *      and BSY is still active
  */
 
 /* SJT: Start. */
 #ifdef SEAGATE_USE_ASM
 
-int __dummy_3,__dummy_4;
+                                       int __dummy_3, __dummy_4;
 
 /* Dummy clobbering variables for the new gcc-2.95 */
 
@@ -1396,175 +1447,200 @@ int __dummy_3,__dummy_4;
  *      We loop as long as we are in a data in phase, there is room to read, 
  *      and BSY is still active
  */
-            /* Local variables : ecx = len, edi = data
-                                 esi = st0x_cr_sr, ebx = st0x_dr */
-            __asm__ (
-            /* Test for room to read */
-                "orl %%ecx, %%ecx\n\t"
-                "jz 2f\n\t"
-                "cld\n\t"
+                                       /* Local variables : ecx = len, edi = data
+                                          esi = st0x_cr_sr, ebx = st0x_dr */
+                                       __asm__ (
+                                                       /* Test for room to read */
+                                                       "orl %%ecx, %%ecx\n\t"
+                                                       "jz 2f\n\t" "cld\n\t"
 /*                "movl " SYMBOL_NAME_STR(st0x_cr_sr) ", %%esi\n\t"  */
 /*                "movl " SYMBOL_NAME_STR(st0x_dr) ", %%ebx\n\t"  */
-            "1:\t"
-                "movb (%%esi), %%al\n\t"
-            /* Test for BSY */
-                "test $1, %%al\n\t"
-                "jz 2f\n\t"
-            /* Test for data in phase - STATUS & REQ_MASK should be REQ_DATAIN, 
-               = STAT_IO, which is 4. */
-                "movb $0xe, %%ah\n\t"      
-                "andb %%al, %%ah\n\t"
-                "cmpb $0x04, %%ah\n\t"
-                "jne 2f\n\t"
-            /* Test for REQ */      
-                "test $0x10, %%al\n\t"
-                "jz 1b\n\t"
-                "movb (%%ebx), %%al\n\t"      
-                "stosb\n\t"   
-                "loop 1b\n\t"
-            "2:\n"
-/* output */    : "=D" (data), "=c" (len) ,"=S" (__dummy_3) ,"=b" (__dummy_4)
-/* input */     : "0" (data), "1" (len), "2" (phys_to_virt(st0x_cr_sr)), "3" (phys_to_virt(st0x_dr)) 
-/* clobbered */ : "eax" ); 
-#else /* SEAGATE_USE_ASM */
-            while (len)
-            {
-              unsigned char stat;
-
-              stat = STATUS;
-              if (!(stat & STAT_BSY) || ((stat & REQ_MASK) != REQ_DATAIN))
-                break;
-              if (stat & STAT_REQ)
-              {
-                *data++ = DATA;
-                --len;
-              }
-            }
-#endif /* SEAGATE_USE_ASM */
+                                                       "1:\t"
+                                                       "movb (%%esi), %%al\n\t"
+                                                       /* Test for BSY */
+                                                       "test $1, %%al\n\t"
+                                                       "jz 2f\n\t"
+                                                       /* Test for data in phase - STATUS & REQ_MASK should be REQ_DATAIN, 
+                                                          = STAT_IO, which is 4. */
+                                                       "movb $0xe, %%ah\n\t"
+                                                       "andb %%al, %%ah\n\t"
+                                                       "cmpb $0x04, %%ah\n\t"
+                                                       "jne 2f\n\t"
+                                                       /* Test for REQ */
+                                                       "test $0x10, %%al\n\t"
+                                                       "jz 1b\n\t"
+                                                       "movb (%%ebx), %%al\n\t"
+                                                       "stosb\n\t"
+                                                       "loop 1b\n\t" "2:\n"
+                                     /* output */ :"=D" (data), "=c" (len),
+                                                       "=S"
+                                                       (__dummy_3),
+                                                       "=b" (__dummy_4)
+/* input */
+                                     :         "0" (data), "1" (len),
+                                                       "2" (phys_to_virt
+                                                            (st0x_cr_sr)),
+                                                       "3" (phys_to_virt
+                                                            (st0x_dr))
+/* clobbered */
+                                     :         "eax");
+#else                          /* SEAGATE_USE_ASM */
+                                       while (len) {
+                                               unsigned char stat;
+
+                                               stat = STATUS;
+                                               if (!(stat & STAT_BSY)
+                                                   || ((stat & REQ_MASK) !=
+                                                       REQ_DATAIN))
+                                                       break;
+                                               if (stat & STAT_REQ) {
+                                                       *data++ = DATA;
+                                                       --len;
+                                               }
+                                       }
+#endif                         /* SEAGATE_USE_ASM */
 /* SJT: End. */
 #if (DEBUG & PHASE_DATAIN)
-            printk ("scsi%d: transfered -= %d\n", hostno, len);
-            transfered -= len;          /* Since we assumed all of Len got  *
-                                           transfered, correct our mistake */
+                                       printk ("scsi%d: transfered -= %d\n",
+                                               hostno, len);
+                                       transfered -= len;      /* Since we assumed all of Len got  *
+                                                                  transfered, correct our mistake */
 #endif
-          }
-
-          if (!len && nobuffs)
-          {
-            --nobuffs;
-            ++buffer;
-            len = buffer->length;
-            data = (unsigned char *) buffer->address;
-            DPRINTK (DEBUG_SG, 
-                    "scsi%d : next scatter-gather buffer len = %d address = %08x\n",
-                    hostno, len, data);
-          }
-
-          break;
-
-        case REQ_CMDOUT:
-          while (((status_read = STATUS) & STAT_BSY) &&
-                 ((status_read & REQ_MASK) == REQ_CMDOUT))
-            if (status_read & STAT_REQ)
-            {
-              WRITE_DATA (*(const unsigned char *) cmnd);
-              cmnd = 1 + (const unsigned char *) cmnd;
+                               }
+
+                               if (!len && nobuffs) {
+                                       --nobuffs;
+                                       ++buffer;
+                                       len = buffer->length;
+                                       data =
+                                           (unsigned char *) buffer->address;
+                                       DPRINTK (DEBUG_SG,
+                                                "scsi%d : next scatter-gather buffer len = %d address = %08x\n",
+                                                hostno, len, data);
+                               }
+
+                               break;
+
+                       case REQ_CMDOUT:
+                               while (((status_read = STATUS) & STAT_BSY) &&
+                                      ((status_read & REQ_MASK) == REQ_CMDOUT))
+                                       if (status_read & STAT_REQ) {
+                                               WRITE_DATA (*
+                                                           (const unsigned char
+                                                            *) cmnd);
+                                               cmnd =
+                                                   1 +
+                                                   (const unsigned char *)
+                                                   cmnd;
 #ifdef SLOW_RATE
-              if (borken)
-                borken_wait ();
+                                               if (borken)
+                                                       borken_wait ();
 #endif
-            }
-          break;
+                                       }
+                               break;
 
-        case REQ_STATIN:
-          status = DATA;
-          break;
+                       case REQ_STATIN:
+                               status = DATA;
+                               break;
 
-        case REQ_MSGOUT:
+                       case REQ_MSGOUT:
 /*
- *    We can only have sent a MSG OUT if we requested to do this
+ *     We can only have sent a MSG OUT if we requested to do this
  *      by raising ATTN.  So, we must drop ATTN.
  */
 
-          WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE);
+                               WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE);
 /*
- *    If we are reconnecting, then we must send an IDENTIFY message in
- *       response  to MSGOUT.
+ *     If we are reconnecting, then we must send an IDENTIFY message in
+ *      response  to MSGOUT.
  */
-          switch (reselect)
-          {
-            case CAN_RECONNECT:
-              WRITE_DATA (IDENTIFY (1, lun));
-
-              DPRINTK (PHASE_RESELECT | PHASE_MSGOUT, "scsi%d : sent IDENTIFY message.\n", hostno);
-              break;
+                               switch (reselect) {
+                               case CAN_RECONNECT:
+                                       WRITE_DATA (IDENTIFY (1, lun));
+
+                                       DPRINTK (PHASE_RESELECT | PHASE_MSGOUT,
+                                                "scsi%d : sent IDENTIFY message.\n",
+                                                hostno);
+                                       break;
 #ifdef LINKED
-            case LINKED_WRONG:
-              WRITE_DATA (ABORT);
-              linked_connected = 0;
-              reselect = CAN_RECONNECT;
-              goto connect_loop;
-              DPRINTK (PHASE_MSGOUT | DEBUG_LINKED, 
-                      "scsi%d : sent ABORT message to cancel incorrect I_T_L nexus.\n", hostno);
-#endif /* LINKED */
-              DPRINTK (DEBUG_LINKED, "correct\n");
-            default:
-              WRITE_DATA (NOP);
-              printk ("scsi%d : target %d requested MSGOUT, sent NOP message.\n", hostno, target);
-          }
-          break;
-
-        case REQ_MSGIN:
-          switch (message = DATA)
-          {
-            case DISCONNECT:
-             DANY ("seagate: deciding to disconnect\n");
-              should_reconnect = 1;
-              current_data = data;      /* WDE add */
-              current_buffer = buffer;
-              current_bufflen = len;    /* WDE add */
-              current_nobuffs = nobuffs;
+                               case LINKED_WRONG:
+                                       WRITE_DATA (ABORT);
+                                       linked_connected = 0;
+                                       reselect = CAN_RECONNECT;
+                                       goto connect_loop;
+                                       DPRINTK (PHASE_MSGOUT | DEBUG_LINKED,
+                                                "scsi%d : sent ABORT message to cancel incorrect I_T_L nexus.\n",
+                                                hostno);
+#endif                         /* LINKED */
+                                       DPRINTK (DEBUG_LINKED, "correct\n");
+                               default:
+                                       WRITE_DATA (NOP);
+                                       printk
+                                           ("scsi%d : target %d requested MSGOUT, sent NOP message.\n",
+                                            hostno, target);
+                               }
+                               break;
+
+                       case REQ_MSGIN:
+                               switch (message = DATA) {
+                               case DISCONNECT:
+                                       DANY ("seagate: deciding to disconnect\n");
+                                       should_reconnect = 1;
+                                       current_data = data;    /* WDE add */
+                                       current_buffer = buffer;
+                                       current_bufflen = len;  /* WDE add */
+                                       current_nobuffs = nobuffs;
 #ifdef LINKED
-              linked_connected = 0;
+                                       linked_connected = 0;
 #endif
-              done = 1;
-              DPRINTK ((PHASE_RESELECT | PHASE_MSGIN), "scsi%d : disconnected.\n", hostno);
-              break;
+                                       done = 1;
+                                       DPRINTK ((PHASE_RESELECT | PHASE_MSGIN),
+                                                "scsi%d : disconnected.\n",
+                                                hostno);
+                                       break;
 
 #ifdef LINKED
-            case LINKED_CMD_COMPLETE:
-            case LINKED_FLG_CMD_COMPLETE:
+                               case LINKED_CMD_COMPLETE:
+                               case LINKED_FLG_CMD_COMPLETE:
 #endif
-            case COMMAND_COMPLETE:
+                               case COMMAND_COMPLETE:
 /*
  * Note : we should check for underflow here.
  */
-              DPRINTK (PHASE_MSGIN, "scsi%d : command complete.\n", hostno);
-              done = 1;
-              break;
-            case ABORT:
-              DPRINTK (PHASE_MSGIN, "scsi%d : abort message.\n", hostno);
-              done = 1;
-              break;
-            case SAVE_POINTERS:
-              current_buffer = buffer;
-              current_bufflen = len;    /* WDE add */
-              current_data = data;      /* WDE mod */
-              current_nobuffs = nobuffs;
-              DPRINTK (PHASE_MSGIN, "scsi%d : pointers saved.\n", hostno);
-              break;
-            case RESTORE_POINTERS:
-              buffer = current_buffer;
-              cmnd = current_cmnd;
-              data = current_data;      /* WDE mod */
-              len = current_bufflen;
-              nobuffs = current_nobuffs;
-              DPRINTK (PHASE_MSGIN, "scsi%d : pointers restored.\n", hostno);
-              break;
-            default:
+                                       DPRINTK (PHASE_MSGIN,
+                                                "scsi%d : command complete.\n",
+                                                hostno);
+                                       done = 1;
+                                       break;
+                               case ABORT:
+                                       DPRINTK (PHASE_MSGIN,
+                                                "scsi%d : abort message.\n",
+                                                hostno);
+                                       done = 1;
+                                       break;
+                               case SAVE_POINTERS:
+                                       current_buffer = buffer;
+                                       current_bufflen = len;  /* WDE add */
+                                       current_data = data;    /* WDE mod */
+                                       current_nobuffs = nobuffs;
+                                       DPRINTK (PHASE_MSGIN,
+                                                "scsi%d : pointers saved.\n",
+                                                hostno);
+                                       break;
+                               case RESTORE_POINTERS:
+                                       buffer = current_buffer;
+                                       cmnd = current_cmnd;
+                                       data = current_data;    /* WDE mod */
+                                       len = current_bufflen;
+                                       nobuffs = current_nobuffs;
+                                       DPRINTK (PHASE_MSGIN,
+                                                "scsi%d : pointers restored.\n",
+                                                hostno);
+                                       break;
+                               default:
 
 /*
- *    IDENTIFY distinguishes itself from the other messages by setting the
+ *     IDENTIFY distinguishes itself from the other messages by setting the
  *      high byte. [FIXME: should not this read "the high bit"? - pavel@ucw.cz]
  *
  *      Note : we need to handle at least one outstanding command per LUN,
@@ -1572,13 +1648,12 @@ int __dummy_3,__dummy_4;
  *      known ID (at this point) and LUN.
  */
 
-              if (message & 0x80)
-              {
-                DPRINTK (PHASE_MSGIN, "scsi%d : IDENTIFY message received from id %d, lun %d.\n",
-                        hostno, target, message & 7);
-              }
-              else
-              {
+                                       if (message & 0x80) {
+                                               DPRINTK (PHASE_MSGIN,
+                                                        "scsi%d : IDENTIFY message received from id %d, lun %d.\n",
+                                                        hostno, target,
+                                                        message & 7);
+                                       } else {
 
 /*
  *      We should go into a MESSAGE OUT phase, and send  a MESSAGE_REJECT
@@ -1586,17 +1661,19 @@ int __dummy_3,__dummy_4;
  *      needs some serious restructuring first though.
  */
 
-                DPRINTK (PHASE_MSGIN, 
-                        "scsi%d : unknown message %d from target %d.\n", hostno, message, target);
-              }
-          }
-          break;
+                                               DPRINTK (PHASE_MSGIN,
+                                                        "scsi%d : unknown message %d from target %d.\n",
+                                                        hostno, message,
+                                                        target);
+                                       }
+                               }
+                               break;
 
-        default:
-          printk ("scsi%d : unknown phase.\n", hostno);
-          st0x_aborted = DID_ERROR;
-      }                                 /* end of switch (status_read &
-                                           REQ_MASK) */
+                       default:
+                               printk ("scsi%d : unknown phase.\n", hostno);
+                               st0x_aborted = DID_ERROR;
+                       }       /* end of switch (status_read &
+                                  REQ_MASK) */
 
 #ifdef SLOW_RATE
 /*
@@ -1604,34 +1681,34 @@ int __dummy_3,__dummy_4;
  * byte transfer case (ie, message in, message out, status), so
  * I'll do the wait here if necessary.
  */
-      if (borken)
-        borken_wait ();
+                       if (borken)
+                               borken_wait ();
 #endif
 
-    }                                   /* if(status_read & STAT_REQ) ends */
-  }                                     /* while(((status_read = STATUS)...)
-                                           ends */
+               }               /* if(status_read & STAT_REQ) ends */
+       }                       /* while(((status_read = STATUS)...)
+                                  ends */
 
-  DPRINTK (PHASE_DATAIN | PHASE_DATAOUT | PHASE_EXIT, 
-          "scsi%d : Transfered %d bytes\n", hostno, transfered);
+       DPRINTK (PHASE_DATAIN | PHASE_DATAOUT | PHASE_EXIT,
+                "scsi%d : Transfered %d bytes\n", hostno, transfered);
 
 #if (DEBUG & PHASE_EXIT)
-#if 0                                   /* Doesn't work for scatter/gather */
-  printk ("Buffer : \n");
-  for (i = 0; i < 20; ++i)
-    printk ("%02x  ", ((unsigned char *) data)[i]);     /* WDE mod */
-  printk ("\n");
+#if 0                          /* Doesn't work for scatter/gather */
+       printk ("Buffer : \n");
+       for (i = 0; i < 20; ++i)
+               printk ("%02x  ", ((unsigned char *) data)[i]); /* WDE mod */
+       printk ("\n");
 #endif
-  printk ("scsi%d : status = ", hostno);
-  print_status (status);
-  printk ("message = %02x\n", message);
+       printk ("scsi%d : status = ", hostno);
+       print_status (status);
+       printk ("message = %02x\n", message);
 #endif
 
 /* We shouldn't reach this until *after* BSY has been deasserted */
 
 #ifdef LINKED
-  else
-  {
+       else
+       {
 /*
  * Fix the message byte so that unsuspecting high level drivers don't
  * puke when they see a LINKED COMMAND message in place of the COMMAND
@@ -1642,52 +1719,53 @@ int __dummy_3,__dummy_4;
  * and we are now disconnected.
  */
 
-    switch (message)
-    {
-      case LINKED_CMD_COMPLETE:
-      case LINKED_FLG_CMD_COMPLETE:
-        message = COMMAND_COMPLETE;
-        linked_target = current_target;
-        linked_lun = current_lun;
-        linked_connected = 1;
-       DPRINTK (DEBUG_LINKED, "scsi%d : keeping I_T_L nexus established"
-                "for linked command.\n", hostno);
-    /* We also will need to adjust status to accommodate intermediate
-       conditions. */
-        if ((status == INTERMEDIATE_GOOD) ||
-            (status == INTERMEDIATE_C_GOOD))
-          status = GOOD;
-
-        break;
+               switch (message) {
+               case LINKED_CMD_COMPLETE:
+               case LINKED_FLG_CMD_COMPLETE:
+                       message = COMMAND_COMPLETE;
+                       linked_target = current_target;
+                       linked_lun = current_lun;
+                       linked_connected = 1;
+                       DPRINTK (DEBUG_LINKED,
+                                "scsi%d : keeping I_T_L nexus established"
+                                "for linked command.\n", hostno);
+                       /* We also will need to adjust status to accommodate intermediate
+                          conditions. */
+                       if ((status == INTERMEDIATE_GOOD) ||
+                           (status == INTERMEDIATE_C_GOOD))
+                               status = GOOD;
+
+                       break;
 /*
  * We should also handle what are "normal" termination messages
  * here (ABORT, BUS_DEVICE_RESET?, and COMMAND_COMPLETE individually,
  * and flake if things aren't right.
  */
-      default:
-        DPRINTK (DEBUG_LINKED, "scsi%d : closing I_T_L nexus.\n", hostno);
-        linked_connected = 0;
-    }
-  }
-#endif /* LINKED */
-
-  if (should_reconnect)
-  {
-    DPRINTK (PHASE_RESELECT, "scsi%d : exiting seagate_st0x_queue_command()"
-            "with reconnect enabled.\n", hostno);
-    WRITE_CONTROL (BASE_CMD | CMD_INTR);
-  }
-  else
-    WRITE_CONTROL (BASE_CMD);
-
-  return retcode (st0x_aborted);
-}                                       /* end of internal_command */
-
-int seagate_st0x_abort (Scsi_Cmnd * SCpnt)
+               default:
+                       DPRINTK (DEBUG_LINKED,
+                                "scsi%d : closing I_T_L nexus.\n", hostno);
+                       linked_connected = 0;
+               }
+       }
+#endif                         /* LINKED */
+
+       if (should_reconnect) {
+               DPRINTK (PHASE_RESELECT,
+                        "scsi%d : exiting seagate_st0x_queue_command()"
+                        "with reconnect enabled.\n", hostno);
+               WRITE_CONTROL (BASE_CMD | CMD_INTR);
+       } else
+               WRITE_CONTROL (BASE_CMD);
+
+       return retcode (st0x_aborted);
+}                              /* end of internal_command */
+
+static int seagate_st0x_abort (Scsi_Cmnd * SCpnt)
 {
-  st0x_aborted = DID_ABORT;
-  return SCSI_ABORT_PENDING;
+       st0x_aborted = DID_ABORT;
+       return SCSI_ABORT_PENDING;
 }
+
 #undef ULOOP
 #undef TIMEOUT
 
@@ -1695,24 +1773,23 @@ int seagate_st0x_abort (Scsi_Cmnd * SCpnt)
  * the seagate_st0x_reset function resets the SCSI bus 
  */
 
-int seagate_st0x_reset (Scsi_Cmnd * SCpnt, unsigned int reset_flags)
+static int seagate_st0x_reset (Scsi_Cmnd * SCpnt, unsigned int reset_flags)
 {
 /* No timeouts - this command is going to fail because it was reset. */
-  DANY ("scsi%d: Reseting bus... ", hostno );
+       DANY ("scsi%d: Reseting bus... ", hostno);
 
 /* assert  RESET signal on SCSI bus.  */
-  WRITE_CONTROL (BASE_CMD | CMD_RST);
+       WRITE_CONTROL (BASE_CMD | CMD_RST);
 
-  udelay( 20*1000 );
+       udelay (20 * 1000);
 
-  WRITE_CONTROL (BASE_CMD);
-  st0x_aborted = DID_RESET;
+       WRITE_CONTROL (BASE_CMD);
+       st0x_aborted = DID_RESET;
 
-  DANY ("done.\n");
-  return SCSI_RESET_WAKEUP;
+       DANY ("done.\n");
+       return SCSI_RESET_WAKEUP;
 }
 
-
 /* Eventually this will go into an include file, but this will be later */
 static Scsi_Host_Template driver_template = SEAGATE_ST0X;
 
index 3aedafd573fd592ccf226c0119ec12dcaefe67c8..37180f9c8c9a27ace424ae030abf340311abd99b 100644 (file)
@@ -16,9 +16,9 @@ int seagate_st0x_detect(Scsi_Host_Template *);
 int seagate_st0x_command(Scsi_Cmnd *);
 int seagate_st0x_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
 
-int seagate_st0x_abort(Scsi_Cmnd *);
+static int seagate_st0x_abort(Scsi_Cmnd *);
 const char *seagate_st0x_info(struct Scsi_Host *);
-int seagate_st0x_reset(Scsi_Cmnd *, unsigned int); 
+static int seagate_st0x_reset(Scsi_Cmnd *, unsigned int); 
 
 #define SEAGATE_ST0X  {  detect:         seagate_st0x_detect,          \
                         info:           seagate_st0x_info,             \
index f08b680f69ee13831cfe55f9dc253353e0e21162..1b7305fa8b4712f9c07c3999dff9f24aeec485b3 100644 (file)
@@ -19,9 +19,9 @@
  */
 #include <linux/config.h>
 #ifdef CONFIG_PROC_FS
- static char sg_version_str[] = "Version: 3.1.19 (20010623)";
+ static char sg_version_str[] = "Version: 3.1.20 (20010814)";
 #endif
- static int sg_version_num = 30119; /* 2 digits for each component */
+ static int sg_version_num = 30120; /* 2 digits for each component */
 /*
  *  D. P. Gilbert (dgilbert@interlog.com, dougg@triode.net.au), notes:
  *      - scsi logging is available via SCSI_LOG_TIMEOUT macros. First
@@ -271,6 +271,7 @@ static int sg_open(struct inode * inode, struct file * filp)
      /* Prevent the device driver from vanishing while we sleep */
      if (sdp->device->host->hostt->module)
         __MOD_INC_USE_COUNT(sdp->device->host->hostt->module);
+    sdp->device->access_count++;
 
     if (! ((flags & O_NONBLOCK) ||
           scsi_block_when_processing_errors(sdp->device))) {
@@ -323,6 +324,7 @@ static int sg_open(struct inode * inode, struct file * filp)
     return 0;
 
 error_out:
+    sdp->device->access_count--;
     if ((! sdp->detached) && sdp->device->host->hostt->module)
         __MOD_DEC_USE_COUNT(sdp->device->host->hostt->module);
     return retval;
@@ -342,8 +344,11 @@ static int sg_release(struct inode * inode, struct file * filp)
     SCSI_LOG_TIMEOUT(3, printk("sg_release: dev=%d\n", MINOR(sdp->i_rdev)));
     sg_fasync(-1, filp, 0);   /* remove filp from async notification list */
     if (0 == sg_remove_sfp(sdp, sfp)) { /* Returns 1 when sdp gone */
-       if ((! sdp->detached) && sdp->device->host->hostt->module)
-           __MOD_DEC_USE_COUNT(sdp->device->host->hostt->module);
+        if (! sdp->detached) {
+            sdp->device->access_count--;
+            if (sdp->device->host->hostt->module)
+                __MOD_DEC_USE_COUNT(sdp->device->host->hostt->module);
+        }
        sdp->exclude = 0;
        wake_up_interruptible(&sdp->o_excl_wait);
     }
@@ -874,6 +879,9 @@ static int sg_ioctl(struct inode * inode, struct file * filp,
         return 0;
     case SG_GET_VERSION_NUM:
         return put_user(sg_version_num, (int *)arg);
+    case SG_GET_ACCESS_COUNT:
+       val = (sdp->device ? sdp->device->access_count : 0);
+       return put_user(val, (int *)arg);
     case SG_GET_REQUEST_TABLE:
        result = verify_area(VERIFY_WRITE, (void *) arg,
                             SZ_SG_REQ_INFO * SG_MAX_QUEUE);
@@ -1116,6 +1124,7 @@ static void sg_cmd_done_bh(Scsi_Cmnd * SCpnt)
             sg_remove_sfp(sdp, sfp);
            sfp = NULL;
         }
+       sdp->device->access_count--;
        if (sg_template.module)
                __MOD_DEC_USE_COUNT(sg_template.module);
        if (sdp->device->host->hostt->module)
@@ -1241,6 +1250,15 @@ static int sg_attach(Scsi_Device * scsidp)
 
     for(k = 0; k < sg_template.dev_max; k++)
         if(! sg_dev_arr[k]) break;
+    if (k > MINORMASK) {
+       scsidp->attached--;
+       write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
+       printk("Unable to attach sg device <%d, %d, %d, %d>"
+              " type=%d, minor number exceed %d\n", scsidp->host->host_no, 
+              scsidp->channel, scsidp->id, scsidp->lun, scsidp->type,
+              MINORMASK);
+       return 1;
+    }
     if(k < sg_template.dev_max)
        sdp = (Sg_device *)kmalloc(sizeof(Sg_device), GFP_ATOMIC);
     else
@@ -1264,7 +1282,7 @@ static int sg_attach(Scsi_Device * scsidp)
     sdp->de = devfs_register (scsidp->de, "generic", DEVFS_FL_DEFAULT,
                              SCSI_GENERIC_MAJOR, k,
                              S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
-                             &sg_fops, NULL);
+                             &sg_fops, sdp);
     sg_template.nr_dev++;
     sg_dev_arr[k] = sdp;
     write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
@@ -1314,6 +1332,7 @@ static void sg_detach(Scsi_Device * scsidp)
                        sg_finish_rem_req(srp);
                }
                if (sfp->closed) {
+                   sdp->device->access_count--;
                    if (sg_template.module)
                        __MOD_DEC_USE_COUNT(sg_template.module);
                    if (sdp->device->host->hostt->module)
@@ -2210,6 +2229,7 @@ static int sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp)
     }
     else {
         sfp->closed = 1; /* flag dirty state on this fd */
+       sdp->device->access_count++;
        /* MOD_INC's to inhibit unloading sg and associated adapter driver */
        if (sg_template.module)
            __MOD_INC_USE_COUNT(sg_template.module);
@@ -2753,7 +2773,7 @@ static int sg_proc_devhdr_read(char * buffer, char ** start, off_t offset,
 static int sg_proc_devhdr_info(char * buffer, int * len, off_t * begin,
                               off_t offset, int size)
 {
-    PRINT_PROC("host\tchan\tid\tlun\ttype\tbopens\tqdepth\tbusy\tonline\n");
+    PRINT_PROC("host\tchan\tid\tlun\ttype\topens\tqdepth\tbusy\tonline\n");
     return 1;
 }
 
index c0d638004518394838cbc913639f1e17a772f5e8..ce064c67df8c3e4a407933f2f5944ecc4e049782 100644 (file)
@@ -45,6 +45,9 @@ dep_tristate '  S3 SonicVibes' CONFIG_SOUND_SONICVIBES $CONFIG_SOUND
 if [ "$CONFIG_VISWS" = "y" ]; then
     dep_tristate '  SGI Visual Workstation Sound' CONFIG_SOUND_VWSND $CONFIG_SOUND
 fi
+if [ "$CONFIG_DDB5477" = "y" ]; then
+    dep_tristate '  NEC Vrc5477 AC97 sound' CONFIG_SOUND_VRC5477 $CONFIG_SOUND
+fi
 dep_tristate '  Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core' CONFIG_SOUND_TRIDENT $CONFIG_SOUND
 
 dep_tristate '  Support for Turtle Beach MultiSound Classic, Tahiti, Monterey' CONFIG_SOUND_MSNDCLAS $CONFIG_SOUND
index 294000f6dce9f45802bf80360e3f2e28ae1d0ba8..6353b79b6c94a7eb4625d8848e420ba0af850662 100644 (file)
@@ -39,7 +39,7 @@
 #define AC97_PCM_FRONT_DAC_RATE 0x002C  /* PCM Front DAC Rate */
 #define AC97_PCM_SURR_DAC_RATE  0x002E  /* PCM Surround DAC Rate */
 #define AC97_PCM_LFE_DAC_RATE   0x0030  /* PCM LFE DAC Rate */
-#define AC97_PCM_LR_DAC_RATE   0x0032  /* PCM LR DAC Rate */
+#define AC97_PCM_LR_ADC_RATE   0x0032  /* PCM LR DAC Rate */
 #define AC97_PCM_MIC_ADC_RATE   0x0034  /* PCM MIC ADC Rate */
 #define AC97_CENTER_LFE_MASTER  0x0036  /* Center + LFE Master Volume */
 #define AC97_SURROUND_MASTER    0x0038  /* Surround (Rear) Master Volume */
index ce0355e5bbff77fc652ada225a47cbe82a9cb434..3d5882c85d6a667ff6eb7ebb119ed4edc73a084c 100644 (file)
@@ -104,6 +104,7 @@ static const struct {
        {0x41445303, "Analog Devices AD1819",   &null_ops},
        {0x41445340, "Analog Devices AD1881",   &null_ops},
        {0x41445348, "Analog Devices AD1881A",  &null_ops},
+       {0x41445360, "Analog Devices AD1885",   &default_ops},
        {0x41445460, "Analog Devices AD1885",   &default_ops},
        {0x414B4D00, "Asahi Kasei AK4540",      &null_ops},
        {0x414B4D01, "Asahi Kasei AK4542",      &null_ops},
@@ -937,3 +938,85 @@ static int pt101_init(struct ac97_codec * codec)
 
 EXPORT_SYMBOL(ac97_read_proc);
 EXPORT_SYMBOL(ac97_probe_codec);
+
+/*
+ *     AC97 library support routines
+ */    
+/**
+ *     ac97_set_dac_rate       -       set codec rate adaption
+ *     @codec: ac97 code
+ *     @rate: rate in hertz
+ *
+ *     Set the DAC rate. Assumes the codec supports VRA. The caller is
+ *     expected to have checked this little detail.
+ */
+unsigned int ac97_set_dac_rate(struct ac97_codec *codec, unsigned int rate)
+{
+       unsigned int new_rate = rate;
+       u32 dacp;
+       u32 mast_vol, phone_vol, mono_vol, pcm_vol;
+       u32 mute_vol = 0x8000;  /* The mute volume? */
+
+       if(rate != codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE))
+       {
+               /* Mute several registers */
+               mast_vol = codec->codec_read(codec, AC97_MASTER_VOL_STEREO);
+               mono_vol = codec->codec_read(codec, AC97_MASTER_VOL_MONO);
+               phone_vol = codec->codec_read(codec, AC97_HEADPHONE_VOL);
+               pcm_vol = codec->codec_read(codec, AC97_PCMOUT_VOL);
+               codec->codec_write(codec, AC97_MASTER_VOL_STEREO, mute_vol);
+               codec->codec_write(codec, AC97_MASTER_VOL_MONO, mute_vol);
+               codec->codec_write(codec, AC97_HEADPHONE_VOL, mute_vol);
+               codec->codec_write(codec, AC97_PCMOUT_VOL, mute_vol);
+               
+               /* Power down the DAC */
+               dacp=codec->codec_read(codec, AC97_POWER_CONTROL);
+               codec->codec_write(codec, AC97_POWER_CONTROL, dacp|0x0200);
+               /* Load the rate and read the effective rate */
+               codec->codec_write(codec, AC97_PCM_FRONT_DAC_RATE, rate);
+               new_rate=codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE);
+               /* Power it back up */
+               codec->codec_write(codec, AC97_POWER_CONTROL, dacp);
+
+               /* Restore volumes */
+               codec->codec_write(codec, AC97_MASTER_VOL_STEREO, mast_vol);
+               codec->codec_write(codec, AC97_MASTER_VOL_MONO, mono_vol);
+               codec->codec_write(codec, AC97_HEADPHONE_VOL, phone_vol);
+               codec->codec_write(codec, AC97_PCMOUT_VOL, pcm_vol);
+       }
+       return new_rate;
+}
+
+EXPORT_SYMBOL(ac97_set_dac_rate);
+
+/**
+ *     ac97_set_adc_rate       -       set codec rate adaption
+ *     @codec: ac97 code
+ *     @rate: rate in hertz
+ *
+ *     Set the ADC rate. Assumes the codec supports VRA. The caller is
+ *     expected to have checked this little detail.
+ */
+
+unsigned int ac97_set_adc_rate(struct ac97_codec *codec, unsigned int rate)
+{
+       unsigned int new_rate = rate;
+       u32 dacp;
+
+       if(rate != codec->codec_read(codec, AC97_PCM_LR_ADC_RATE))
+       {
+               /* Power down the ADC */
+               dacp=codec->codec_read(codec, AC97_POWER_CONTROL);
+               codec->codec_write(codec, AC97_POWER_CONTROL, dacp|0x0100);
+               /* Load the rate and read the effective rate */
+               codec->codec_write(codec, AC97_PCM_LR_ADC_RATE, rate);
+               new_rate=codec->codec_read(codec, AC97_PCM_LR_ADC_RATE);
+               /* Power it back up */
+               codec->codec_write(codec, AC97_POWER_CONTROL, dacp);
+       }
+       return new_rate;
+}
+
+EXPORT_SYMBOL(ac97_set_adc_rate);
index edd08a05c573d1ae30c26f7038829491b8945931..684c95b35f5da6a8b1f032e2010c8f37ec05c9bd 100644 (file)
@@ -29,6 +29,7 @@
  * Christoph Hellwig   : adapted to module_init/module_exit
  * Aki Laukkanen       : added power management support
  * Arnaldo C. de Melo  : added missing restore_flags in ad1848_resume
+ * Miguel Freitas       : added ISA PnP support
  *
  * Status:
  *             Tested. Believed fully functional.
@@ -39,6 +40,7 @@
 #include <linux/module.h>
 #include <linux/stddef.h>
 #include <linux/pm.h>
+#include <linux/isapnp.h>
 
 #define DEB(x)
 #define DEB1(x)
@@ -160,6 +162,18 @@ static struct {
     ,{CAP_F_TIMER} /* MD_1845_SSCAPE */
 };
 
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+static int isapnp      = 1;
+static int isapnpjump  = 0;
+static int reverse     = 0;
+
+static int audio_activated = 0;
+#else
+static int isapnp      = 0;
+#endif
+
+
+
 static int      ad1848_open(int dev, int mode);
 static void     ad1848_close(int dev);
 static void     ad1848_output_block(int dev, unsigned long buf, int count, int intrflag);
@@ -2812,34 +2826,207 @@ MODULE_PARM(irq, "i");                  /* IRQ to use */
 MODULE_PARM(dma, "i");                  /* First DMA channel */
 MODULE_PARM(dma2, "i");                 /* Second DMA channel */
 MODULE_PARM(type, "i");                 /* Card type */
-MODULE_PARM(deskpro_xl, "i");           /* Special magic for Deskpro XL boxen
-*/
+MODULE_PARM(deskpro_xl, "i");           /* Special magic for Deskpro XL boxen */
 MODULE_PARM(deskpro_m, "i");            /* Special magic for Deskpro M box */
-MODULE_PARM(soundpro, "i");             /* More special magic for SoundPro
-chips */
+MODULE_PARM(soundpro, "i");             /* More special magic for SoundPro chips */
+
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+MODULE_PARM(isapnp,    "i");
+MODULE_PARM(isapnpjump,        "i");
+MODULE_PARM(reverse,   "i");
+MODULE_PARM_DESC(isapnp,       "When set to 0, Plug & Play support will be disabled");
+MODULE_PARM_DESC(isapnpjump,   "Jumps to a specific slot in the driver's PnP table. Use the source, Luke.");
+MODULE_PARM_DESC(reverse,      "When set to 1, will reverse ISAPnP search order");
+
+struct pci_dev *ad1848_dev  = NULL;
+
+/* Please add new entries at the end of the table */
+static struct {
+       char *name;
+       unsigned short  card_vendor, card_device,
+                       vendor, function;
+       short mss_io, irq, dma, dma2;   /* index into isapnp table */
+        int type;
+} ad1848_isapnp_list[] __initdata = {
+       {"CMI 8330 SoundPRO",
+               ISAPNP_VENDOR('C','M','I'), ISAPNP_DEVICE(0x0001),
+               ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001),
+               0, 0, 0,-1, 0},
+        {"CS4232 based card",
+                ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+               ISAPNP_VENDOR('C','S','C'), ISAPNP_FUNCTION(0x0000),
+               0, 0, 0, 1, 0},
+        {"CS4232 based card",
+                ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+               ISAPNP_VENDOR('C','S','C'), ISAPNP_FUNCTION(0x0100),
+               0, 0, 0, 1, 0},
+        {"OPL3-SA2 WSS mode",
+               ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+               ISAPNP_VENDOR('Y','M','H'), ISAPNP_FUNCTION(0x0021),
+                1, 0, 0, 1, 1},
+       {0}
+};
+
+static struct isapnp_device_id id_table[] __devinitdata = {
+       {       ISAPNP_VENDOR('C','M','I'), ISAPNP_DEVICE(0x0001),
+               ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001), 0 },
+        {       ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+               ISAPNP_VENDOR('C','S','C'), ISAPNP_FUNCTION(0x0000), 0 },
+        {       ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+               ISAPNP_VENDOR('C','S','C'), ISAPNP_FUNCTION(0x0100), 0 },
+        {       ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+               ISAPNP_VENDOR('Y','M','H'), ISAPNP_FUNCTION(0x0021), 0 },
+       {0}
+};
+
+MODULE_DEVICE_TABLE(isapnp, id_table);
+
+static struct pci_dev *activate_dev(char *devname, char *resname, struct pci_dev *dev)
+{
+       int err;
+
+       /* Device already active? Let's use it */
+       if(dev->active)
+               return(dev);
+
+       if((err = dev->activate(dev)) < 0) {
+               printk(KERN_ERR "ad1848: %s %s config failed (out of resources?)[%d]\n", devname, resname, err);
+
+               dev->deactivate(dev);
+
+               return(NULL);
+       }
+       return(dev);
+}
+
+static struct pci_dev *ad1848_init_generic(struct pci_bus *bus, struct address_info *hw_config, int slot)
+{
+
+       /* Configure Audio device */
+       if((ad1848_dev = isapnp_find_dev(bus, ad1848_isapnp_list[slot].vendor, ad1848_isapnp_list[slot].function, NULL)))
+       {
+               int ret;
+               ret = ad1848_dev->prepare(ad1848_dev);
+               /* If device is active, assume configured with /proc/isapnp
+                * and use anyway. Some other way to check this? */
+               if(ret && ret != -EBUSY) {
+                       printk(KERN_ERR "ad1848: ISAPnP found device that could not be autoconfigured.\n");
+                       return(NULL);
+               }
+               if(ret == -EBUSY)
+                       audio_activated = 1;
+
+               if((ad1848_dev = activate_dev(ad1848_isapnp_list[slot].name, "ad1848", ad1848_dev)))
+               {
+                       hw_config->io_base      = ad1848_dev->resource[ad1848_isapnp_list[slot].mss_io].start;
+                       hw_config->irq          = ad1848_dev->irq_resource[ad1848_isapnp_list[slot].irq].start;
+                       hw_config->dma          = ad1848_dev->dma_resource[ad1848_isapnp_list[slot].dma].start;
+                       if(ad1848_isapnp_list[slot].dma2 != -1)
+                               hw_config->dma2 = ad1848_dev->dma_resource[ad1848_isapnp_list[slot].dma2].start;
+                       else
+                               hw_config->dma2 = -1;
+                        hw_config->card_subtype = ad1848_isapnp_list[slot].type;
+               } else
+                       return(NULL);
+       } else
+               return(NULL);
+
+       return(ad1848_dev);
+}
+
+static int __init ad1848_isapnp_init(struct address_info *hw_config, struct pci_bus *bus, int slot)
+{
+       char *busname = bus->name[0] ? bus->name : ad1848_isapnp_list[slot].name;
+
+       printk(KERN_INFO "ad1848: %s detected\n", busname);
+
+       /* Initialize this baby. */
+
+       if(ad1848_init_generic(bus, hw_config, slot)) {
+               /* We got it. */
+
+               printk(KERN_NOTICE "ad1848: ISAPnP reports '%s' at i/o %#x, irq %d, dma %d, %d\n",
+                      busname,
+                      hw_config->io_base, hw_config->irq, hw_config->dma,
+                      hw_config->dma2);
+               return 1;
+       }
+       else
+               printk(KERN_INFO "ad1848: Failed to initialize %s\n", busname);
+
+       return 0;
+}
+
+static int __init ad1848_isapnp_probe(struct address_info *hw_config)
+{
+       static int first = 1;
+       int i;
+
+       /* Count entries in sb_isapnp_list */
+       for (i = 0; ad1848_isapnp_list[i].card_vendor != 0; i++);
+       i--;
+
+       /* Check and adjust isapnpjump */
+       if( isapnpjump < 0 || isapnpjump > i) {
+               isapnpjump = reverse ? i : 0;
+               printk(KERN_ERR "ad1848: Valid range for isapnpjump is 0-%d. Adjusted to %d.\n", i, isapnpjump);
+       }
+
+       if(!first || !reverse)
+               i = isapnpjump;
+       first = 0;
+       while(ad1848_isapnp_list[i].card_vendor != 0) {
+               static struct pci_bus *bus = NULL;
+
+               while ((bus = isapnp_find_card(
+                               ad1848_isapnp_list[i].card_vendor,
+                               ad1848_isapnp_list[i].card_device,
+                               bus))) {
+
+                       if(ad1848_isapnp_init(hw_config, bus, i)) {
+                               isapnpjump = i; /* start next search from here */
+                               return 0;
+                       }
+               }
+               i += reverse ? -1 : 1;
+       }
+
+       return -ENODEV;
+}
+#endif
+
 
 static int __init init_ad1848(void)
 {
        printk(KERN_INFO "ad1848/cs4248 codec driver Copyright (C) by Hannu Savolainen 1993-1996\n");
 
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+       if(isapnp && (ad1848_isapnp_probe(&cfg) < 0) ) {
+               printk(KERN_NOTICE "ad1848: No ISAPnP cards found, trying standard ones...\n");
+               isapnp = 0;
+       }
+#endif
+
        if(io != -1) {
-               if(irq == -1 || dma == -1) {
-                       printk(KERN_WARNING "ad1848: must give I/O , IRQ and DMA.\n");
-                       return -EINVAL;
-               }
+               if( isapnp == 0 )
+               {
+                       if(irq == -1 || dma == -1) {
+                               printk(KERN_WARNING "ad1848: must give I/O , IRQ and DMA.\n");
+                               return -EINVAL;
+                       }
 
-               cfg.irq = irq;
-               cfg.io_base = io;
-               cfg.dma = dma;
-               cfg.dma2 = dma2;
-               cfg.card_subtype = type;
+                       cfg.irq = irq;
+                       cfg.io_base = io;
+                       cfg.dma = dma;
+                       cfg.dma2 = dma2;
+                       cfg.card_subtype = type;
+               }
 
                if(!probe_ms_sound(&cfg))
                        return -ENODEV;
                attach_ms_sound(&cfg, THIS_MODULE);
                loaded = 1;
        }
-       
        return 0;
 }
 
@@ -2847,6 +3034,12 @@ static void __exit cleanup_ad1848(void)
 {
        if(loaded)
                unload_ms_sound(&cfg);
+
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+       if(audio_activated)
+               if(ad1848_dev)
+                       ad1848_dev->deactivate(ad1848_dev);
+#endif
 }
 
 module_init(init_ad1848);
index de74ac98357bcc2c96331883cb91c737965b9b37..87180a2779c5922aa136e2bd4805cb8c36e86173 100644 (file)
  *                was calling prog_dmabuf with s->lock held, call missing
  *                unlock_kernel in cm_midi_release
  *
- *    Fri May 25 2001 - Carlos Eduardo Gorges <carlos@techlinux.com.br>
- *    - some driver cleanups
- *    - spin[un]lock* revision ( fix SMP support )
- *    - cosmetic code changes
+ *     Carlos Eduardo Gorges <carlos@techlinux.com.br>
+ *     Fri May 25 2001 
+ *     - SMP support ( spin[un]lock* revision )
+ *     - speaker mixer support 
+ *     Mon Aug 13 2001
+ *     - optimizations and cleanups
  *
  */
-
 /*****************************************************************************/
       
 #include <linux/version.h>
 #include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #include <asm/hardirq.h>
+#include <linux/bitops.h>
 
 #include "dm.h"
 
 /* --------------------------------------------------------------------- */
-
 #undef OSS_DOCUMENTED_MIXER_SEMANTICS
-
+#undef DMABYTEIO
 /* --------------------------------------------------------------------- */
 
-#ifndef PCI_VENDOR_ID_CMEDIA
-#define PCI_VENDOR_ID_CMEDIA         0x13F6
-#endif
-#ifndef PCI_DEVICE_ID_CMEDIA_CM8338A
-#define PCI_DEVICE_ID_CMEDIA_CM8338A 0x0100
-#endif
-#ifndef PCI_DEVICE_ID_CMEDIA_CM8338B
-#define PCI_DEVICE_ID_CMEDIA_CM8338B 0x0101
-#endif
-#ifndef PCI_DEVICE_ID_CMEDIA_CM8738
-#define PCI_DEVICE_ID_CMEDIA_CM8738  0x0111
-#endif
-#ifndef PCI_DEVICE_ID_CMEDIA_CM8738B
-#define PCI_DEVICE_ID_CMEDIA_CM8738B 0x0112
-#endif
-
 #define CM_MAGIC  ((PCI_VENDOR_ID_CMEDIA<<16)|PCI_DEVICE_ID_CMEDIA_CM8338A)
 
-/*
- * CM8338 registers definition
- */
-
-#define CODEC_CMI_FUNCTRL0      (0x00)
-#define CODEC_CMI_FUNCTRL1      (0x04)
-#define CODEC_CMI_CHFORMAT      (0x08)
-#define CODEC_CMI_INT_HLDCLR    (0x0C)
-#define CODEC_CMI_INT_STATUS    (0x10)
-#define CODEC_CMI_LEGACY_CTRL   (0x14)
-#define CODEC_CMI_MISC_CTRL     (0x18)
-#define CODEC_CMI_TDMA_POS      (0x1C)
-#define CODEC_CMI_MIXER         (0x20)
-#define CODEC_SB16_DATA         (0x22)
-#define CODEC_SB16_ADDR         (0x23)
-#define CODEC_CMI_MIXER1        (0x24)
-#define CODEC_CMI_MIXER2        (0x25)
-#define CODEC_CMI_AUX_VOL       (0x26)
-#define CODEC_CMI_MISC          (0x27)
-#define CODEC_CMI_AC97          (0x28)
-
-#define CODEC_CMI_CH0_FRAME1    (0x80)
-#define CODEC_CMI_CH0_FRAME2    (0x84)
-#define CODEC_CMI_CH1_FRAME1    (0x88)
-#define CODEC_CMI_CH1_FRAME2    (0x8C)
-
-#define CODEC_CMI_EXT_REG       (0xF0)
-#define UCHAR  unsigned char
-/*
-**  Mixer registers for SB16
-*/
-
-#define DSP_MIX_DATARESETIDX    ((UCHAR)(0x00))
-
-#define DSP_MIX_MASTERVOLIDX_L  ((UCHAR)(0x30))
-#define DSP_MIX_MASTERVOLIDX_R  ((UCHAR)(0x31))
-#define DSP_MIX_VOICEVOLIDX_L   ((UCHAR)(0x32))
-#define DSP_MIX_VOICEVOLIDX_R   ((UCHAR)(0x33))
-#define DSP_MIX_FMVOLIDX_L      ((UCHAR)(0x34))
-#define DSP_MIX_FMVOLIDX_R      ((UCHAR)(0x35))
-#define DSP_MIX_CDVOLIDX_L      ((UCHAR)(0x36))
-#define DSP_MIX_CDVOLIDX_R      ((UCHAR)(0x37))
-#define DSP_MIX_LINEVOLIDX_L    ((UCHAR)(0x38))
-#define DSP_MIX_LINEVOLIDX_R    ((UCHAR)(0x39))
-
-#define DSP_MIX_MICVOLIDX       ((UCHAR)(0x3A))
-#define DSP_MIX_SPKRVOLIDX      ((UCHAR)(0x3B))
-
-#define DSP_MIX_OUTMIXIDX       ((UCHAR)(0x3C))
-
-#define DSP_MIX_ADCMIXIDX_L     ((UCHAR)(0x3D))
-#define DSP_MIX_ADCMIXIDX_R     ((UCHAR)(0x3E))
-
-#define DSP_MIX_INGAINIDX_L     ((UCHAR)(0x3F))
-#define DSP_MIX_INGAINIDX_R     ((UCHAR)(0x40))
-#define DSP_MIX_OUTGAINIDX_L    ((UCHAR)(0x41))
-#define DSP_MIX_OUTGAINIDX_R    ((UCHAR)(0x42))
-
-#define DSP_MIX_AGCIDX          ((UCHAR)(0x43))
-
-#define DSP_MIX_TREBLEIDX_L     ((UCHAR)(0x44))
-#define DSP_MIX_TREBLEIDX_R     ((UCHAR)(0x45))
-#define DSP_MIX_BASSIDX_L       ((UCHAR)(0x46))
-#define DSP_MIX_BASSIDX_R       ((UCHAR)(0x47))
-#define CM_CH0_RESET     0x04
-#define CM_CH1_RESET     0x08
-#define CM_EXTENT_CODEC          0x100
-#define CM_EXTENT_MIDI   0x2
-#define CM_EXTENT_SYNTH          0x4
-#define CM_INT_CH0       1
-#define CM_INT_CH1       2
-
-#define CM_CFMT_STEREO     0x01
-#define CM_CFMT_16BIT      0x02
-#define CM_CFMT_MASK       0x03
-#define CM_CFMT_DACSHIFT   2
-#define CM_CFMT_ADCSHIFT   0
-
-static const unsigned sample_size[] = { 1, 2, 2, 4 };
-static const unsigned sample_shift[] = { 0, 1, 1, 2 };
+/* CM8338 registers definition ****************/
+
+#define CODEC_CMI_FUNCTRL0             (0x00)
+#define CODEC_CMI_FUNCTRL1             (0x04)
+#define CODEC_CMI_CHFORMAT             (0x08)
+#define CODEC_CMI_INT_HLDCLR           (0x0C)
+#define CODEC_CMI_INT_STATUS           (0x10)
+#define CODEC_CMI_LEGACY_CTRL          (0x14)
+#define CODEC_CMI_MISC_CTRL            (0x18)
+#define CODEC_CMI_TDMA_POS             (0x1C)
+#define CODEC_CMI_MIXER                        (0x20)
+#define CODEC_SB16_DATA                        (0x22)
+#define CODEC_SB16_ADDR                        (0x23)
+#define CODEC_CMI_MIXER1               (0x24)
+#define CODEC_CMI_MIXER2               (0x25)
+#define CODEC_CMI_AUX_VOL              (0x26)
+#define CODEC_CMI_MISC                 (0x27)
+#define CODEC_CMI_AC97                 (0x28)
+
+#define CODEC_CMI_CH0_FRAME1           (0x80)
+#define CODEC_CMI_CH0_FRAME2           (0x84)
+#define CODEC_CMI_CH1_FRAME1           (0x88)
+#define CODEC_CMI_CH1_FRAME2           (0x8C)
+
+#define CODEC_CMI_EXT_REG              (0xF0)
+
+/*  Mixer registers for SB16 ******************/
+
+#define DSP_MIX_DATARESETIDX           ((unsigned char)(0x00))
+
+#define DSP_MIX_MASTERVOLIDX_L         ((unsigned char)(0x30))
+#define DSP_MIX_MASTERVOLIDX_R         ((unsigned char)(0x31))
+#define DSP_MIX_VOICEVOLIDX_L          ((unsigned char)(0x32))
+#define DSP_MIX_VOICEVOLIDX_R          ((unsigned char)(0x33))
+#define DSP_MIX_FMVOLIDX_L             ((unsigned char)(0x34))
+#define DSP_MIX_FMVOLIDX_R             ((unsigned char)(0x35))
+#define DSP_MIX_CDVOLIDX_L             ((unsigned char)(0x36))
+#define DSP_MIX_CDVOLIDX_R             ((unsigned char)(0x37))
+#define DSP_MIX_LINEVOLIDX_L           ((unsigned char)(0x38))
+#define DSP_MIX_LINEVOLIDX_R           ((unsigned char)(0x39))
+
+#define DSP_MIX_MICVOLIDX              ((unsigned char)(0x3A))
+#define DSP_MIX_SPKRVOLIDX             ((unsigned char)(0x3B))
+
+#define DSP_MIX_OUTMIXIDX              ((unsigned char)(0x3C))
+
+#define DSP_MIX_ADCMIXIDX_L            ((unsigned char)(0x3D))
+#define DSP_MIX_ADCMIXIDX_R            ((unsigned char)(0x3E))
+
+#define DSP_MIX_INGAINIDX_L            ((unsigned char)(0x3F))
+#define DSP_MIX_INGAINIDX_R            ((unsigned char)(0x40))
+#define DSP_MIX_OUTGAINIDX_L           ((unsigned char)(0x41))
+#define DSP_MIX_OUTGAINIDX_R           ((unsigned char)(0x42))
+
+#define DSP_MIX_AGCIDX                 ((unsigned char)(0x43))
+
+#define DSP_MIX_TREBLEIDX_L            ((unsigned char)(0x44))
+#define DSP_MIX_TREBLEIDX_R            ((unsigned char)(0x45))
+#define DSP_MIX_BASSIDX_L              ((unsigned char)(0x46))
+#define DSP_MIX_BASSIDX_R              ((unsigned char)(0x47))
+
+#define CM_CH0_RESET                   0x04
+#define CM_CH1_RESET                   0x08
+#define CM_EXTENT_CODEC                        0x100
+#define CM_EXTENT_MIDI                 0x2
+#define CM_EXTENT_SYNTH                        0x4
+#define CM_INT_CH0                     1
+#define CM_INT_CH1                     2
+
+#define CM_CFMT_STEREO                 0x01
+#define CM_CFMT_16BIT                  0x02
+#define CM_CFMT_MASK                   0x03
+#define CM_CFMT_DACSHIFT               2
+#define CM_CFMT_ADCSHIFT               0
+
+static const unsigned sample_shift[]   = { 0, 1, 1, 2 };
 
 #define CM_ENABLE_CH1      0x2
 #define CM_ENABLE_CH0      0x1
 
-
-/* MIDI buffer sizes */
+/* MIDI buffer sizes **************************/
 
 #define MIDIINBUF  256
 #define MIDIOUTBUF 256
@@ -229,35 +209,29 @@ static const unsigned sample_shift[] = { 0, 1, 1, 2 };
 
 #define SND_DEV_DSP16   5 
 
-/* --------------------------------------------------------------------- */
+#define NR_DEVICE 3            /* maximum number of devices */
 
-struct cm_state {
-       /* magic */
-       unsigned int magic;
+/*********************************************/
 
-       /* we keep cm cards in a linked list */
-       struct cm_state *next;
+struct cm_state {
+       unsigned int magic;             /* magic */
+       struct cm_state *next;          /* we keep cm cards in a linked list */
 
-       /* soundcore stuff */
-       int dev_audio;
+       int dev_audio;                  /* soundcore stuff */
        int dev_mixer;
        int dev_midi;
        int dev_dmfm;
 
-       /* hardware resources */
-       unsigned int iosb, iobase, iosynth, iomidi, iogame, irq;
-       unsigned short deviceid;
+       unsigned int iosb, iobase, iosynth,
+                        iomidi, iogame, irq;   /* hardware resources */
+       unsigned short deviceid;                /* pci_id */
 
-        /* mixer stuff */
-        struct {
+        struct {                               /* mixer stuff */
                 unsigned int modcnt;
-#ifndef OSS_DOCUMENTED_MIXER_SEMANTICS
                unsigned short vol[13];
-#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
         } mix;
 
-       /* wave stuff */
-       unsigned int rateadc, ratedac;
+       unsigned int rateadc, ratedac;          /* wave stuff */
        unsigned char fmt, enable;
 
        spinlock_t lock;
@@ -274,15 +248,15 @@ struct cm_state {
                unsigned hwptr, swptr;
                unsigned total_bytes;
                int count;
-               unsigned error; /* over/underrun */
+               unsigned error;         /* over/underrun */
                wait_queue_head_t wait;
-               /* redundant, but makes calculations easier */
-               unsigned fragsize;
+               
+               unsigned fragsize;      /* redundant, but makes calculations easier */
                unsigned dmasize;
                unsigned fragsamples;
                unsigned dmasamples;
-               /* OSS stuff */
-               unsigned mapped:1;
+               
+               unsigned mapped:1;      /* OSS stuff */
                unsigned ready:1;
                unsigned endcleared:1;
                unsigned ossfragshift;
@@ -290,8 +264,7 @@ struct cm_state {
                unsigned subdivision;
        } dma_dac, dma_adc;
 
-       /* midi stuff */
-       struct {
+       struct {                        /* midi stuff */
                unsigned ird, iwr, icnt;
                unsigned ord, owr, ocnt;
                wait_queue_head_t iwait;
@@ -301,44 +274,41 @@ struct cm_state {
                unsigned char obuf[MIDIOUTBUF];
        } midi;
        
-       /* misc stuff */
-       int     chip_version;
+       int     chip_version;           
        int     max_channels;
-       int     curr_channels;
-       int     speakers;       // number of speakers
-       int     capability;     // HW capability, various for chip versions
-       int     status;         // HW or SW state
+       int     curr_channels;          
+       int     speakers;               /* number of speakers */
+       int     capability;             /* HW capability, various for chip versions */
+
+       int     status;                 /* HW or SW state */
        
-       /* spdif frame counter */
-       int     spdif_counter;
+       int     spdif_counter;          /* spdif frame counter */
 };
 
 /* flags used for capability */
-#define        CAN_AC3_HW      0x00000001      // 037 or later
-#define        CAN_AC3_SW      0x00000002      // 033 or later
-#define        CAN_AC3         (CAN_AC3_HW | CAN_AC3_SW)
-#define CAN_DUAL_DAC   0x00000004      // 033 or later
-#define        CAN_MULTI_CH_HW 0x00000008      // 039 or later
-#define        CAN_MULTI_CH    (CAN_MULTI_CH_HW | CAN_DUAL_DAC)
-#define        CAN_LINE_AS_REAR        0x00000010      // 033 or later
-#define        CAN_LINE_AS_BASS        0x00000020      // 039 or later
-#define        CAN_MIC_AS_BASS         0x00000040      // 039 or later
+#define        CAN_AC3_HW              0x00000001              /* 037 or later */
+#define        CAN_AC3_SW              0x00000002              /* 033 or later */
+#define        CAN_AC3                 (CAN_AC3_HW | CAN_AC3_SW)
+#define CAN_DUAL_DAC           0x00000004              /* 033 or later */
+#define        CAN_MULTI_CH_HW         0x00000008              /* 039 or later */
+#define        CAN_MULTI_CH            (CAN_MULTI_CH_HW | CAN_DUAL_DAC)
+#define        CAN_LINE_AS_REAR        0x00000010              /* 033 or later */
+#define        CAN_LINE_AS_BASS        0x00000020              /* 039 or later */
+#define        CAN_MIC_AS_BASS         0x00000040              /* 039 or later */
 
 /* flags used for status */
-#define        DO_AC3_HW       0x00000001
-#define        DO_AC3_SW       0x00000002
-#define        DO_AC3          (DO_AC3_HW | DO_AC3_SW)
-#define        DO_DUAL_DAC     0x00000004
-#define        DO_MULTI_CH_HW  0x00000008
-#define        DO_MULTI_CH     (DO_MULTI_CH_HW | DO_DUAL_DAC)
-#define        DO_LINE_AS_REAR 0x00000010      // 033 or later
-#define        DO_LINE_AS_BASS 0x00000020      // 039 or later
-#define        DO_MIC_AS_BASS  0x00000040      // 039 or later
-#define        DO_SPDIF_OUT    0x00000100
-#define        DO_SPDIF_IN     0x00000200
-#define        DO_SPDIF_LOOP   0x00000400
-
-/* --------------------------------------------------------------------- */
+#define        DO_AC3_HW               0x00000001
+#define        DO_AC3_SW               0x00000002
+#define        DO_AC3                  (DO_AC3_HW | DO_AC3_SW)
+#define        DO_DUAL_DAC             0x00000004
+#define        DO_MULTI_CH_HW          0x00000008
+#define        DO_MULTI_CH             (DO_MULTI_CH_HW | DO_DUAL_DAC)
+#define        DO_LINE_AS_REAR         0x00000010              /* 033 or later */
+#define        DO_LINE_AS_BASS         0x00000020              /* 039 or later */
+#define        DO_MIC_AS_BASS          0x00000040              /* 039 or later */
+#define        DO_SPDIF_OUT            0x00000100
+#define        DO_SPDIF_IN             0x00000200
+#define        DO_SPDIF_LOOP           0x00000400
 
 static struct cm_state *devs;
 static unsigned long wavetable_mem;
@@ -347,55 +317,25 @@ static unsigned long wavetable_mem;
 
 static inline unsigned ld2(unsigned int x)
 {
-       unsigned r = 0;
+       unsigned exp=16,l=5,r=0;
+       static const unsigned num[]={0x2,0x4,0x10,0x100,0x10000};
+
+       /* num: 2, 4, 16, 256, 65536 */
+       /* exp: 1, 2,  4,   8,    16 */
        
-       if (x >= 0x10000) {
-               x >>= 16;
-               r += 16;
-       }
-       if (x >= 0x100) {
-               x >>= 8;
-               r += 8;
-       }
-       if (x >= 0x10) {
-               x >>= 4;
-               r += 4;
-       }
-       if (x >= 4) {
-               x >>= 2;
-               r += 2;
+       while(l--) {
+               if( x >= num[l] ) {
+                       if(num[l]>2) x >>= exp;
+                       r+=exp;
+               }
+               exp>>=1;
        }
-       if (x >= 2)
-               r++;
-       return r;
-}
 
-/*
- * hweightN: returns the hamming weight (i.e. the number
- * of bits set) of a N-bit word
- */
-
-#ifdef hweight32
-#undef hweight32
-#endif
-
-static inline unsigned int hweight32(unsigned int w)
-{
-        unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
-        res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
-        res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
-        res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
-        return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
+       return r;
 }
 
 /* --------------------------------------------------------------------- */
 
-/*
- * Why use byte IO? Nobody knows, but S3 does it also in their Windows driver.
- */
-
-#undef DMABYTEIO
-
 static void maskb(unsigned int addr, unsigned int mask, unsigned int value)
 {
        outb((inb(addr) & mask) | value, addr);
@@ -451,15 +391,10 @@ static inline unsigned get_dmadac(struct cm_state *s)
 {
        unsigned int curr_addr;
 
-#if 1
        curr_addr = inw(s->iobase + CODEC_CMI_CH1_FRAME2) + 1;
        curr_addr <<= sample_shift[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK];
        curr_addr = s->dma_dac.dmasize - curr_addr;
-#else
-       curr_addr = inl(s->iobase + CODEC_CMI_CH1_FRAME1);
-       curr_addr &= ~(sample_size[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK]-1);
-       curr_addr -= s->dma_dac.rawphys;
-#endif
+
        return curr_addr;
 }
 
@@ -467,39 +402,45 @@ static inline unsigned get_dmaadc(struct cm_state *s)
 {
        unsigned int curr_addr;
 
-#if 1
        curr_addr = inw(s->iobase + CODEC_CMI_CH0_FRAME2) + 1;
        curr_addr <<= sample_shift[(s->fmt >> CM_CFMT_ADCSHIFT) & CM_CFMT_MASK];
        curr_addr = s->dma_adc.dmasize - curr_addr;
-#else
-       curr_addr = inl(s->iobase + CODEC_CMI_CH0_FRAME1);
-       curr_addr &= ~(sample_size[(s->fmt >> CM_CFMT_ADCSHIFT) & CM_CFMT_MASK]-1);
-       curr_addr -= s->dma_adc.rawphys;
-#endif
+
        return curr_addr;
 }
 
 static void wrmixer(struct cm_state *s, unsigned char idx, unsigned char data)
 {
        outb(idx, s->iobase + CODEC_SB16_ADDR);
+       udelay(10);
        outb(data, s->iobase + CODEC_SB16_DATA);
+       udelay(10);
 }
 
 static unsigned char rdmixer(struct cm_state *s, unsigned char idx)
 {
        unsigned char v;
-
+       unsigned long flags;
+       
+       spin_lock_irqsave(&s->lock, flags);
        outb(idx, s->iobase + CODEC_SB16_ADDR);
+       udelay(10);
        v = inb(s->iobase + CODEC_SB16_DATA);
+       udelay(10);
+       spin_unlock_irqrestore(&s->lock, flags);
        return v;
 }
 
 static void set_fmt_unlocked(struct cm_state *s, unsigned char mask, unsigned char data)
 {
        if (mask)
+       {
                s->fmt = inb(s->iobase + CODEC_CMI_CHFORMAT);
+               udelay(10);
+       }
        s->fmt = (s->fmt & mask) | data;
        outb(s->fmt, s->iobase + CODEC_CMI_CHFORMAT);
+       udelay(10);
 }
 
 static void set_fmt(struct cm_state *s, unsigned char mask, unsigned char data)
@@ -514,7 +455,9 @@ static void set_fmt(struct cm_state *s, unsigned char mask, unsigned char data)
 static void frobindir(struct cm_state *s, unsigned char idx, unsigned char mask, unsigned char data)
 {
        outb(idx, s->iobase + CODEC_SB16_ADDR);
+       udelay(10);
        outb((inb(s->iobase + CODEC_SB16_DATA) & mask) | data, s->iobase + CODEC_SB16_DATA);
+       udelay(10);
 }
 
 static struct {
@@ -746,6 +689,7 @@ static inline void reset_adc(struct cm_state *s)
 {
        /* reset bus master */
        outb(s->enable | CM_CH0_RESET, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
+       udelay(10);
        outb(s->enable & ~CM_CH0_RESET, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
 }
 
@@ -887,15 +831,6 @@ static void start_dac1_unlocked(struct cm_state *s)
        }
 }
 
-//static void start_dac1(struct cm_state *s)
-//{
-//     unsigned long flags;
-//
-//     spin_lock_irqsave(&s->lock, flags);
-//     start_dac1_unlocked(s);
-//     spin_unlock_irqrestore(&s->lock, flags);
-//}    
-
 static void start_dac_unlocked(struct cm_state *s)
 {
        if ((s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) {
@@ -964,7 +899,7 @@ static int set_dac_channels(struct cm_state *s, int channels)
                set_adc_rate_unlocked(s, s->ratedac);
 
            }
-           // N4SPK3D, disable 4 speaker mode (analog duplicate)
+
            if (s->speakers > 2)
                maskb(s->iobase + CODEC_CMI_MISC_CTRL + 3, ~0x04, 0);
            s->curr_channels = channels;
@@ -1041,10 +976,10 @@ static int prog_dmabuf(struct cm_state *s, unsigned rec)
                db->buforder = order;
                db->rawphys = virt_to_bus(db->rawbuf);
                if ((db->rawphys ^ (db->rawphys + (PAGE_SIZE << db->buforder) - 1)) & ~0xffff)
-                       printk(KERN_DEBUG "cm: DMA buffer crosses 64k boundary: busaddr 0x%lx  size %ld\n", 
+                       printk(KERN_DEBUG "cmpci: DMA buffer crosses 64k boundary: busaddr 0x%lx  size %ld\n", 
                               (long) db->rawphys, PAGE_SIZE << db->buforder);
                if ((db->rawphys + (PAGE_SIZE << db->buforder) - 1) & ~0xffffff)
-                       printk(KERN_DEBUG "cm: DMA buffer beyond 16MB: busaddr 0x%lx  size %ld\n", 
+                       printk(KERN_DEBUG "cmpci: DMA buffer beyond 16MB: busaddr 0x%lx  size %ld\n", 
                               (long) db->rawphys, PAGE_SIZE << db->buforder);
                /* now mark the pages as reserved; otherwise remap_page_range doesn't do what we want */
                pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
@@ -1260,7 +1195,7 @@ static void cm_midi_timer(unsigned long data)
 
 /* --------------------------------------------------------------------- */
 
-static const char invalid_magic[] = KERN_CRIT "cm: invalid magic value\n";
+static const char invalid_magic[] = KERN_CRIT "cmpci: invalid magic value\n";
 
 #ifdef CONFIG_SOUND_CMPCI      /* support multiple chips */
 #define VALIDATE_STATE(s)
@@ -1298,59 +1233,6 @@ static const struct {
        [SOUND_MIXER_SPEAKER]= { DSP_MIX_SPKRVOLIDX,     DSP_MIX_SPKRVOLIDX,     MT_5MUTEMONO, 0x01, 0x01 }
 };
 
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-
-static int return_mixval(struct cm_state *s, unsigned i, int *arg)
-{
-       unsigned long flags;
-       unsigned char l, r, rl, rr;
-
-       spin_lock_irqsave(&s->lock, flags);
-       l = rdmixer(s, mixtable[i].left);
-       r = rdmixer(s, mixtable[i].right);
-       spin_unlock_irqrestore(&s->lock, flags);
-       switch (mixtable[i].type) {
-       case MT_4:
-               r &= 0xf;
-               l &= 0xf;
-               rl = 10 + 6 * (l & 15);
-               rr = 10 + 6 * (r & 15);
-               break;
-
-       case MT_4MUTEMONO:
-               rl = 55 - 3 * (l & 15);
-               if (r & 0x10)
-                       rl += 45;
-               rr = rl;
-               r = l;
-               break;
-
-       case MT_5MUTEMONO:
-               r = l;
-               rl = 100 - 3 * ((l >> 3) & 31);
-               rr = rl;
-               break;
-                               
-       case MT_5MUTE:
-       default:
-               rl = 100 - 3 * ((l >> 3) & 31);
-               rr = 100 - 3 * ((r >> 3) & 31);
-               break;
-                               
-       case MT_6MUTE:
-               rl = 100 - 3 * (l & 63) / 2;
-               rr = 100 - 3 * (r & 63) / 2;
-               break;
-       }
-       if (l & 0x80)
-               rl = 0;
-       if (r & 0x80)
-               rr = 0;
-       return put_user((rr << 8) | rl, arg);
-}
-
-#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-
 static const unsigned char volidx[SOUND_MIXER_NRDEVICES] = 
 {
        [SOUND_MIXER_CD]     = 1,
@@ -1362,16 +1244,11 @@ static const unsigned char volidx[SOUND_MIXER_NRDEVICES] =
        [SOUND_MIXER_SPEAKER]= 7
 };
 
-#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-
 static unsigned mixer_recmask(struct cm_state *s)
 {
-       unsigned long flags;
        int i, j, k;
 
-       spin_lock_irqsave(&s->lock, flags);
        j = rdmixer(s, DSP_MIX_ADCMIXIDX_L);
-       spin_unlock_irqrestore(&s->lock, flags);
        j &= 0x7f;
        for (k = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
                if (j & mixtable[i].rec)
@@ -1446,13 +1323,9 @@ static int mixer_ioctl(struct cm_state *s, unsigned int cmd, unsigned long arg)
                        i = _IOC_NR(cmd);
                         if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
                                 return -EINVAL;
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-                       return return_mixval(s, i, (int *)arg);
-#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
                        if (!volidx[i])
                                return -EINVAL;
                        return put_user(s->mix.vol[volidx[i]-1], (int *)arg);
-#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
                }
        }
         if (_IOC_DIR(cmd) != (_IOC_READ|_IOC_WRITE)) 
@@ -1462,7 +1335,7 @@ static int mixer_ioctl(struct cm_state *s, unsigned int cmd, unsigned long arg)
        case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
                if (get_user(val, (int *)arg))
                        return -EFAULT;
-               i = hweight32(val);
+               i = generic_hweight32(val);
                for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
                        if (!(val & (1 << i)))
                                continue;
@@ -1554,14 +1427,11 @@ static int mixer_ioctl(struct cm_state *s, unsigned int cmd, unsigned long arg)
                        break;
                }
                spin_unlock_irqrestore(&s->lock, flags);
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-                return return_mixval(s, i, (int *)arg);
-#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
+
                if (!volidx[i])
                        return -EINVAL;
                s->mix.vol[volidx[i]-1] = val;
                return put_user(s->mix.vol[volidx[i]-1], (int *)arg);
-#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
        }
 }
 
@@ -1631,7 +1501,7 @@ static int drain_dac(struct cm_state *s, int nonblock)
                tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->ratedac;
                tmo >>= sample_shift[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK];
                if (!schedule_timeout(tmo + 1))
-                       printk(KERN_DEBUG "cm: dma timed out??\n");
+                       printk(KERN_DEBUG "cmpci: dma timed out??\n");
         }
         remove_wait_queue(&s->dma_dac.wait, &wait);
         current->state = TASK_RUNNING;
@@ -1660,11 +1530,7 @@ static ssize_t cm_read(struct file *file, char *buffer, size_t count, loff_t *pp
        if (!access_ok(VERIFY_WRITE, buffer, count))
                return -EFAULT;
        ret = 0;
-#if 0
-   spin_lock_irqsave(&s->lock, flags);
-   cm_update_ptr(s);
-   spin_unlock_irqrestore(&s->lock, flags);
-#endif
+
        while (count > 0) {
                spin_lock_irqsave(&s->lock, flags);
                swptr = s->dma_adc.swptr;
@@ -1679,7 +1545,7 @@ static ssize_t cm_read(struct file *file, char *buffer, size_t count, loff_t *pp
                        if (file->f_flags & O_NONBLOCK)
                                return ret ? ret : -EAGAIN;
                        if (!interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ)) {
-                               printk(KERN_DEBUG "cm: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
+                               printk(KERN_DEBUG "cmpci: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
                                       s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count,
                                       s->dma_adc.hwptr, s->dma_adc.swptr);
                                spin_lock_irqsave(&s->lock, flags);
@@ -1735,11 +1601,7 @@ static ssize_t cm_write(struct file *file, const char *buffer, size_t count, lof
                        return -EFAULT;
        }
        ret = 0;
-#if 0
-   spin_lock_irqsave(&s->lock, flags);
-   cm_update_ptr(s);
-   spin_unlock_irqrestore(&s->lock, flags);
-#endif                                                        
+
        while (count > 0) {
                spin_lock_irqsave(&s->lock, flags);
                if (s->dma_dac.count < 0) {
@@ -1770,7 +1632,7 @@ static ssize_t cm_write(struct file *file, const char *buffer, size_t count, lof
                        if (file->f_flags & O_NONBLOCK)
                                return ret ? ret : -EAGAIN;
                        if (!interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ)) {
-                               printk(KERN_DEBUG "cm: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
+                               printk(KERN_DEBUG "cmpci: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
                                       s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count,
                                       s->dma_dac.hwptr, s->dma_dac.swptr);
                                spin_lock_irqsave(&s->lock, flags);
@@ -2387,11 +2249,11 @@ static int cm_release(struct inode *inode, struct file *file)
        down(&s->open_sem);
        if (file->f_mode & FMODE_WRITE) {
                stop_dac(s);
-#ifndef FIXEDDMA
+
                dealloc_dmabuf(&s->dma_dac);
                if (s->status & DO_DUAL_DAC)
                        dealloc_dmabuf(&s->dma_adc);
-#endif
+
                if (s->status & DO_MULTI_CH)
                        set_dac_channels(s, 0);
                if (s->status & DO_AC3)
@@ -2401,9 +2263,7 @@ static int cm_release(struct inode *inode, struct file *file)
        }
        if (file->f_mode & FMODE_READ) {
                stop_adc(s);
-#ifndef FIXEDDMA
                dealloc_dmabuf(&s->dma_adc);
-#endif
        }
        s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
        up(&s->open_sem);
@@ -2668,7 +2528,7 @@ static int cm_midi_release(struct inode *inode, struct file *file)
                        }
                        tmo = (count * HZ) / 3100;
                        if (!schedule_timeout(tmo ? : 1) && tmo)
-                               printk(KERN_DEBUG "cm: midi timed out??\n");
+                               printk(KERN_DEBUG "cmpci: midi timed out??\n");
                }
                remove_wait_queue(&s->midi.owait, &wait);
                set_current_state(TASK_RUNNING);
@@ -2867,18 +2727,7 @@ static /*const*/ struct file_operations cm_dmfm_fops = {
 };
 #endif /* CONFIG_SOUND_CMPCI_FM */
 
-/* --------------------------------------------------------------------- */
-
-/* maximum number of devices */
-#define NR_DEVICE 5
-
-#if 0
-static int reverb[NR_DEVICE] = { 0, };
 
-static int wavetable[NR_DEVICE] = { 0, };
-#endif
-
-/* --------------------------------------------------------------------- */
 
 static struct initvol {
        int mixch;
@@ -2941,14 +2790,14 @@ static int query_chip(struct cm_state *s)
 }
 
 #ifdef CONFIG_SOUND_CMPCI_MIDI
-static int     mpu_io = CONFIG_SOUND_CMPCI_MPUIO;
+static int     mpuio = CONFIG_SOUND_CMPCI_MPUIO;
 #else
-static int     mpu_io;
+static int     mpuio;
 #endif
 #ifdef CONFIG_SOUND_CMPCI_FM
-static int     fm_io = CONFIG_SOUND_CMPCI_FMIO;
+static int     fmio = CONFIG_SOUND_CMPCI_FMIO;
 #else
-static int     fm_io;
+static int     fmio;
 #endif
 #ifdef CONFIG_SOUND_CMPCI_SPDIFINVERSE
 static int     spdif_inverse = 1;
@@ -2980,16 +2829,16 @@ static  int     joystick = 1;
 #else
 static int     joystick;
 #endif
-MODULE_PARM(mpu_io, "i");
-MODULE_PARM(fm_io, "i");
+MODULE_PARM(mpuio, "i");
+MODULE_PARM(fmio, "i");
 MODULE_PARM(spdif_inverse, "i");
 MODULE_PARM(spdif_loop, "i");
 MODULE_PARM(speakers, "i");
 MODULE_PARM(use_line_as_rear, "i");
 MODULE_PARM(use_line_as_bass, "i");
 MODULE_PARM(joystick, "i");
-MODULE_PARM_DESC(mpu_io, "(0x330, 0x320, 0x310, 0x300) Base of MPU-401, 0 to disable");
-MODULE_PARM_DESC(fm_io, "(0x388, 0x3C8, 0x3E0) Base of OPL3, 0 to disable");
+MODULE_PARM_DESC(mpuio, "(0x330, 0x320, 0x310, 0x300) Base of MPU-401, 0 to disable");
+MODULE_PARM_DESC(fmio, "(0x388, 0x3C8, 0x3E0) Base of OPL3, 0 to disable");
 MODULE_PARM_DESC(spdif_inverse, "(1/0) Invert S/PDIF-in signal");
 MODULE_PARM_DESC(spdif_loop, "(1/0) Route S/PDIF-in to S/PDIF-out directly");
 MODULE_PARM_DESC(speakers, "(2-6) Number of speakers you connect");
@@ -3021,7 +2870,7 @@ void initialize_chip(struct pci_dev *pcidev)
                        return;
                s = kmalloc(sizeof(*s), GFP_KERNEL);
                if (!s) {
-                       printk(KERN_WARNING "cm: out of memory\n");
+                       printk(KERN_WARNING "cmpci: out of memory\n");
                        return;
                }
                /* search device name */
@@ -3042,8 +2891,8 @@ void initialize_chip(struct pci_dev *pcidev)
                spin_lock_init(&s->lock);
                s->magic = CM_MAGIC;
                s->iobase = pci_resource_start(pcidev, 0);
-               s->iosynth = fm_io;
-               s->iomidi = mpu_io;
+               s->iosynth = fmio;
+               s->iomidi = mpuio;
                s->status = 0;
                /* range check */
                if (speakers < 2)
@@ -3056,7 +2905,7 @@ void initialize_chip(struct pci_dev *pcidev)
                s->irq = pcidev->irq;
 
                if (!request_region(s->iobase, CM_EXTENT_CODEC, "cmpci")) {
-                       printk(KERN_ERR "cm: io ports %#x-%#x in use\n", s->iobase, s->iobase+CM_EXTENT_CODEC-1);
+                       printk(KERN_ERR "cmpci: io ports %#x-%#x in use\n", s->iobase, s->iobase+CM_EXTENT_CODEC-1);
                        goto err_region5;
                }
 #ifdef CONFIG_SOUND_CMPCI_MIDI
@@ -3064,7 +2913,7 @@ void initialize_chip(struct pci_dev *pcidev)
                maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x04, 0);
                if (s->iomidi) {
                    if (!request_region(s->iomidi, CM_EXTENT_MIDI, "cmpci Midi")) {
-                       printk(KERN_ERR "cm: io ports %#x-%#x in use\n", s->iomidi, s->iomidi+CM_EXTENT_MIDI-1);
+                       printk(KERN_ERR "cmpci: io ports %#x-%#x in use\n", s->iomidi, s->iomidi+CM_EXTENT_MIDI-1);
                        s->iomidi = 0;
                    } else {
                        /* set IO based at 0x330 */
@@ -3098,7 +2947,7 @@ void initialize_chip(struct pci_dev *pcidev)
                maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~8, 0);
                if (s->iosynth) {
                    if (!request_region(s->iosynth, CM_EXTENT_SYNTH, "cmpci FM")) {
-                       printk(KERN_ERR "cm: io ports %#x-%#x in use\n", s->iosynth, s->iosynth+CM_EXTENT_SYNTH-1);
+                       printk(KERN_ERR "cmpci: io ports %#x-%#x in use\n", s->iosynth, s->iosynth+CM_EXTENT_SYNTH-1);
                        s->iosynth = 0;
                    } else {
                        /* set IO based at 0x388 */
@@ -3140,10 +2989,10 @@ void initialize_chip(struct pci_dev *pcidev)
 
                /* request irq */
                if (request_irq(s->irq, cm_interrupt, SA_SHIRQ, "cmpci", s)) {
-                       printk(KERN_ERR "cm: irq %u in use\n", s->irq);
+                       printk(KERN_ERR "cmpci: irq %u in use\n", s->irq);
                        goto err_irq;
                }
-               printk(KERN_INFO "cm: found %s adapter at io %#06x irq %u\n",
+               printk(KERN_INFO "cmpci: found %s adapter at io %#06x irq %u\n",
                       devicename, s->iobase, s->irq);
                /* register devices */
                if ((s->dev_audio = register_sound_dsp(&cm_audio_fops, -1)) < 0)
@@ -3174,15 +3023,18 @@ void initialize_chip(struct pci_dev *pcidev)
                /* use channel 0 for record, channel 1 for play */
                maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~2, 1);
                s->deviceid = pcidev->device;
+
                if (pcidev->device == PCI_DEVICE_ID_CMEDIA_CM8738) {
+
                        /* chip version and hw capability check */
                        s->chip_version = query_chip(s);
-                       printk(KERN_INFO "chip version = 0%d\n", s->chip_version);
+                       printk(KERN_INFO "cmpci: chip version = 0%d\n", s->chip_version);
+
                        /* seet SPDIF-in inverse before enable SPDIF loop */
                        if (spdif_inverse) {
                                /* turn on spdif-in inverse */
                                maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0, 1);
-                               printk(KERN_INFO "cm: Inverse SPDIF-in\n");
+                               printk(KERN_INFO "cmpci: Inverse SPDIF-in\n");
                        } else {
                                /* turn off spdif-ininverse */
                                maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~1, 0);
@@ -3193,7 +3045,7 @@ void initialize_chip(struct pci_dev *pcidev)
                                s->status |= DO_SPDIF_LOOP;
                                /* turn on spdif-in to spdif-out */
                                maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x80);
-                               printk(KERN_INFO "cm: Enable SPDIF loop\n");
+                               printk(KERN_INFO "cmpci: Enable SPDIF loop\n");
                        } else {
                                s->status &= ~DO_SPDIF_LOOP;
                                /* turn off spdif-in to spdif-out */
@@ -3234,7 +3086,7 @@ void initialize_chip(struct pci_dev *pcidev)
        err_dev2:
                unregister_sound_dsp(s->dev_audio);
        err_dev1:
-               printk(KERN_ERR "cm: cannot register misc device\n");
+               printk(KERN_ERR "cmpci: cannot register misc device\n");
                free_irq(s->irq, s);
        err_irq:
 #ifdef CONFIG_SOUND_CMPCI_FM
@@ -3264,11 +3116,8 @@ static int __init init_cmpci(void)
        if (!pci_present())   /* No PCI bus in this machine! */
 #endif
                return -ENODEV;
-       printk(KERN_INFO "cm: version $Revision: 5.64 $ time " __TIME__ " " __DATE__ "\n");
-#if 0
-       if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT)))
-               printk(KERN_INFO "cm: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n");
-#endif
+       printk(KERN_INFO "cmpci: version $Revision: 5.64 $ time " __TIME__ " " __DATE__ "\n");
+
        while (index < NR_DEVICE && (
               (pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738, pcidev)))) { 
                initialize_chip(pcidev);
@@ -3302,10 +3151,6 @@ static void __exit cleanup_cmpci(void)
                synchronize_irq();
                outb(0, s->iobase + CODEC_CMI_FUNCTRL0 + 2); /* disable channels */
                free_irq(s->irq, s);
-#ifdef FIXEDDMA
-               dealloc_dmabuf(&s->dma_dac);
-               dealloc_dmabuf(&s->dma_adc);
-#endif
 
                /* reset mixer */
                wrmixer(s, DSP_MIX_DATARESETIDX, 0);
@@ -3329,7 +3174,7 @@ static void __exit cleanup_cmpci(void)
        }
        if (wavetable_mem)
                free_pages(wavetable_mem, 20-PAGE_SHIFT);
-       printk(KERN_INFO "cm: unloading\n");
+       printk(KERN_INFO "cmpci: unloading\n");
 }
 
 module_init(init_cmpci);
index 6ac371c93fd79853606506d87b11ddfd21c16b43..c8f8d8bea2a5403379086ccea9f9ae006f6801d3 100644 (file)
@@ -1887,7 +1887,7 @@ static int cs_midi_open(struct inode *inode, struct file *file)
         spin_unlock_irqrestore(&card->midi.lock, flags);
         card->midi.open_mode |= (file->f_mode & (FMODE_READ | FMODE_WRITE));
         up(&card->midi.open_sem);
-        MOD_INC_USE_COUNT;
+        MOD_INC_USE_COUNT; /* for 2.2 */
         return 0;
 }
 
@@ -1926,7 +1926,7 @@ static int cs_midi_release(struct inode *inode, struct file *file)
         card->midi.open_mode &= (~(file->f_mode & (FMODE_READ | FMODE_WRITE)));
         up(&card->midi.open_sem);
         wake_up(&card->midi.open_wait);
-        MOD_DEC_USE_COUNT;
+        MOD_DEC_USE_COUNT; /* for 2.2 */
         return 0;
 }
 
@@ -3294,7 +3294,6 @@ static int cs_open(struct inode *inode, struct file *file)
 
                state->open_mode |= FMODE_READ;
                up(&state->open_sem);
-               MOD_INC_USE_COUNT;
        }
        if(file->f_mode & FMODE_WRITE)
        {
@@ -3366,10 +3365,10 @@ static int cs_open(struct inode *inode, struct file *file)
 
                state->open_mode |= FMODE_WRITE;
                up(&state->open_sem);
-               MOD_INC_USE_COUNT;
                if((ret = prog_dmabuf(state)))
                        return ret;
        }
+       MOD_INC_USE_COUNT;      /* for 2.2 */
        CS_DBGOUT(CS_OPEN | CS_FUNCTION, 2, printk("cs46xx: cs_open()- 0\n") );
        return 0;
 }
@@ -3421,7 +3420,6 @@ static int cs_release(struct inode *inode, struct file *file)
 
                        kfree(state);
                }
-               MOD_DEC_USE_COUNT;
        }
 
        state = card->states[0];
@@ -3454,10 +3452,10 @@ static int cs_release(struct inode *inode, struct file *file)
 
                        kfree(state);
                }
-               MOD_DEC_USE_COUNT;
        }
 
        CS_DBGOUT(CS_FUNCTION | CS_RELEASE, 2, printk("cs46xx: cs_release()- 0\n") );
+       MOD_DEC_USE_COUNT;      /* For 2.2 */
        return 0;
 }
 
@@ -4088,7 +4086,7 @@ static int cs_open_mixdev(struct inode *inode, struct file *file)
        }
        card->amplifier_ctrl(card, 1);
        CS_INC_USE_COUNT(&card->mixer_use_cnt);
-       MOD_INC_USE_COUNT;
+       MOD_INC_USE_COUNT; /* for 2.2 */
        CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4,
                  printk(KERN_INFO "cs46xx: cs_open_mixdev()- 0\n"));
        return 0;
@@ -4119,7 +4117,7 @@ static int cs_release_mixdev(struct inode *inode, struct file *file)
                return -ENODEV;
        }
 match:
-       MOD_DEC_USE_COUNT;
+       MOD_DEC_USE_COUNT; /* for 2.2 */
        if(!CS_DEC_AND_TEST(&card->mixer_use_cnt))
        {
                CS_DBGOUT(CS_FUNCTION | CS_RELEASE, 4,
index 3868f27b4a816e319488ecec1baa853548c1b2cb..decf5057a7c1e2b8f64dc9a38e7fcaf1a8125312 100644 (file)
@@ -2262,7 +2262,7 @@ static int
 solo1_suspend(struct pci_dev *pci_dev, u32 state) {
        struct solo1_state *s = (struct solo1_state*)pci_get_drvdata(pci_dev);
        if (!s)
-               return;
+               return 1;
        outb(0, s->iobase+6);
        /* DMA master clear */
        outb(0, s->ddmabase+0xd); 
index f3b0922799386c0eaa06073da3f09fd2c048921f..dac53001ccc31513b76534d3f84ce4f58880a02f 100644 (file)
@@ -191,7 +191,7 @@ enum {
 #define INT_MASK (INT_SEC|INT_PRI|INT_MC|INT_PO|INT_PI|INT_MO|INT_NI|INT_GPI)
 
 
-#define DRIVER_VERSION "0.03"
+#define DRIVER_VERSION "0.04"
 
 /* magic numbers to protect our data structures */
 #define I810_CARD_MAGIC                0x5072696E /* "Prin" */
@@ -429,20 +429,11 @@ static unsigned int i810_set_dac_rate(struct i810_state * state, unsigned int ra
                dmabuf->rate = (rate * 48000)/clocking;
        }
        
-       if(rate != i810_ac97_get(codec, AC97_PCM_FRONT_DAC_RATE))
-       {
-               /* Power down the DAC */
-               dacp=i810_ac97_get(codec, AC97_POWER_CONTROL);
-               i810_ac97_set(codec, AC97_POWER_CONTROL, dacp|0x0200);
-               /* Load the rate and read the effective rate */
-               i810_ac97_set(codec, AC97_PCM_FRONT_DAC_RATE, rate);
-               new_rate=i810_ac97_get(codec, AC97_PCM_FRONT_DAC_RATE);
-               /* Power it back up */
-               i810_ac97_set(codec, AC97_POWER_CONTROL, dacp);
-               if(new_rate != rate) {
-                       dmabuf->rate = (new_rate * 48000)/clocking;
-                       rate = new_rate;
-               }
+       new_rate = ac97_set_dac_rate(codec, rate);
+
+       if(new_rate != rate) {
+               dmabuf->rate = (new_rate * 48000)/clocking;
+               rate = new_rate;
        }
 #ifdef DEBUG
        printk("i810_audio: called i810_set_dac_rate : rate = %d/%d\n", dmabuf->rate, rate);
@@ -478,21 +469,12 @@ static unsigned int i810_set_adc_rate(struct i810_state * state, unsigned int ra
                rate = 8000;
                dmabuf->rate = (rate * 48000)/clocking;
        }
+
+       new_rate = ac97_set_adc_rate(codec, rate);
        
-       if(rate != i810_ac97_get(codec, AC97_PCM_LR_DAC_RATE))
-       {
-               /* Power down the ADC */
-               dacp=i810_ac97_get(codec, AC97_POWER_CONTROL);
-               i810_ac97_set(codec, AC97_POWER_CONTROL, dacp|0x0100);
-               /* Load the rate and read the effective rate */
-               i810_ac97_set(codec, AC97_PCM_LR_DAC_RATE, rate);
-               new_rate=i810_ac97_get(codec, AC97_PCM_LR_DAC_RATE);
-               /* Power it back up */
-               i810_ac97_set(codec, AC97_POWER_CONTROL, dacp);
-               if(new_rate != rate) {
-                       dmabuf->rate = (new_rate * 48000)/clocking;
-                       rate = new_rate;
-               }
+       if(new_rate != rate) {
+               dmabuf->rate = (new_rate * 48000)/clocking;
+               rate = new_rate;
        }
 #ifdef DEBUG
        printk("i810_audio: called i810_set_adc_rate : rate = %d/%d\n", dmabuf->rate, rate);
@@ -985,8 +967,10 @@ static void i810_channel_interrupt(struct i810_card *card)
                dmabuf = &state->dmabuf;
                if(dmabuf->enable & DAC_RUNNING)
                        c=dmabuf->write_channel;
-               else
+               else if(dmabuf->enable & ADC_RUNNING)
                        c=dmabuf->read_channel;
+               else    /* This can occur going from R/W to close */
+                       continue;
                
                port+=c->port;
                
@@ -1450,18 +1434,14 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 #endif
                if (get_user(val, (int *)arg))
                        return -EFAULT;
-               if(val==0) {
-                       return -EINVAL;
-               } else {
-                       ret = 1;
-               }
+
                if (dmabuf->enable & DAC_RUNNING) {
                        stop_dac(state);
                }
                if (dmabuf->enable & ADC_RUNNING) {
                        stop_adc(state);
                }
-               return put_user(ret, (int *)arg);
+               return put_user(1, (int *)arg);
 
        case SNDCTL_DSP_GETBLKSIZE:
                if (file->f_mode & FMODE_WRITE) {
@@ -1493,6 +1473,17 @@ static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 #ifdef DEBUG
                printk("SNDCTL_DSP_CHANNELS\n");
 #endif
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
+
+               if (val > 0) {
+                       if (dmabuf->enable & DAC_RUNNING) {
+                               stop_dac(state);
+                       }
+                       if (dmabuf->enable & ADC_RUNNING) {
+                               stop_adc(state);
+                       }
+               }
                return put_user(2, (int *)arg);
 
        case SNDCTL_DSP_POST: /* the user has sent all data and is notifying us */
@@ -2038,6 +2029,75 @@ static int __init i810_ac97_init(struct i810_card *card)
        return num_ac97;
 }
 
+static void __init i810_configure_clocking (void)
+{
+       struct i810_card *card;
+       struct i810_state *state;
+       struct dmabuf *dmabuf;
+       unsigned int i, offset, new_offset;
+       unsigned long flags;
+
+       card = devs;
+       /* We could try to set the clocking for multiple cards, but can you even have
+        * more than one i810 in a machine?  Besides, clocking is global, so unless
+        * someone actually thinks more than one i810 in a machine is possible and
+        * decides to rewrite that little bit, setting the rate for more than one card
+        * is a waste of time.
+        */
+       if(card != NULL) {
+               state = card->states[0] = (struct i810_state *)
+                                       kmalloc(sizeof(struct i810_state), GFP_KERNEL);
+               if (state == NULL)
+                       return;
+               memset(state, 0, sizeof(struct i810_state));
+               dmabuf = &state->dmabuf;
+
+               dmabuf->write_channel = card->alloc_pcm_channel(card);
+               state->virt = 0;
+               state->card = card;
+               state->magic = I810_STATE_MAGIC;
+               init_waitqueue_head(&dmabuf->wait);
+               init_MUTEX(&state->open_sem);
+               dmabuf->fmt = I810_FMT_STEREO | I810_FMT_16BIT;
+               dmabuf->trigger = PCM_ENABLE_OUTPUT;
+               i810_set_dac_rate(state, 48000);
+               if(prog_dmabuf(state, 0) != 0) {
+                       goto config_out_nodmabuf;
+               }
+               if(dmabuf->dmasize < 16384) {
+                       goto config_out;
+               }
+               dmabuf->count = dmabuf->dmasize;
+               outb(31,card->iobase+dmabuf->write_channel->port+OFF_LVI);
+               save_flags(flags);
+               cli();
+               start_dac(state);
+               offset = i810_get_dma_addr(state, 0);
+               mdelay(50);
+               new_offset = i810_get_dma_addr(state, 0);
+               stop_dac(state);
+               outb(2,card->iobase+dmabuf->write_channel->port+OFF_CR);
+               restore_flags(flags);
+               i = new_offset - offset;
+#ifdef DEBUG
+               printk("i810_audio: %d bytes in 50 milliseconds\n", i);
+#endif
+               if(i == 0)
+                       goto config_out;
+               i = i / 4 * 20;
+               if (i > 48500 || i < 47500) {
+                       clocking = clocking * clocking / i;
+                       printk("i810_audio: setting clocking to %d\n", clocking);
+               }
+config_out:
+               dealloc_dmabuf(state);
+config_out_nodmabuf:
+               state->card->free_pcm_channel(state->card,state->dmabuf.write_channel->num);
+               kfree(state);
+               card->states[0] = NULL;
+       }
+}
+
 /* install the driver, we do not allocate hardware channel nor DMA buffer now, they are defered 
    until "ACCESS" time (in prog_dmabuf called by open/read/write/ioctl/mmap) */
    
@@ -2102,27 +2162,37 @@ static int __init i810_probe(struct pci_dev *pci_dev, const struct pci_device_id
                kfree(card);
                return -ENODEV;
        }
-       /* register /dev/dsp */
-       if ((card->dev_audio = register_sound_dsp(&i810_audio_fops, -1)) < 0) {
-               printk(KERN_ERR "i810_audio: couldn't register DSP device!\n");
+
+       /* initialize AC97 codec and register /dev/mixer */
+       if (i810_ac97_init(card) <= 0) {
                release_region(card->iobase, 64);
                release_region(card->ac97base, 256);
                free_irq(card->irq, card);
                kfree(card);
                return -ENODEV;
        }
+       pci_dev->driver_data = card;
 
+       if(clocking == 48000) {
+               i810_configure_clocking();
+       }
 
-       /* initialize AC97 codec and register /dev/mixer */
-       if (i810_ac97_init(card) <= 0) {
-               unregister_sound_dsp(card->dev_audio);
+       /* register /dev/dsp */
+       if ((card->dev_audio = register_sound_dsp(&i810_audio_fops, -1)) < 0) {
+               int i;
+               printk(KERN_ERR "i810_audio: couldn't register DSP device!\n");
                release_region(card->iobase, 64);
                release_region(card->ac97base, 256);
                free_irq(card->irq, card);
+               for (i = 0; i < NR_AC97; i++)
+               if (card->ac97_codec[i] != NULL) {
+                       unregister_sound_mixer(card->ac97_codec[i]->dev_mixer);
+                       kfree (card->ac97_codec[i]);
+               }
                kfree(card);
                return -ENODEV;
        }
-       pci_dev->driver_data = card;
+
        return 0;
 }
 
@@ -2137,7 +2207,7 @@ static void __exit i810_remove(struct pci_dev *pci_dev)
 
        /* unregister audio devices */
        for (i = 0; i < NR_AC97; i++)
-               if (devs->ac97_codec[i] != NULL) {
+               if (card->ac97_codec[i] != NULL) {
                        unregister_sound_mixer(card->ac97_codec[i]->dev_mixer);
                        kfree (card->ac97_codec[i]);
                }
@@ -2161,74 +2231,6 @@ static struct pci_driver i810_pci_driver = {
        remove:         i810_remove,
 };
 
-static void __init i810_configure_clocking (void)
-{
-       struct i810_card *card;
-       struct i810_state *state;
-       struct dmabuf *dmabuf;
-       unsigned int i, offset, new_offset;
-       unsigned long flags;
-
-       card = devs;
-       /* We could try to set the clocking for multiple cards, but can you even have
-        * more than one i810 in a machine?  Besides, clocking is global, so unless
-        * someone actually thinks more than one i810 in a machine is possible and
-        * decides to rewrite that little bit, setting the rate for more than one card
-        * is a waste of time.
-        */
-       if(card != NULL) {
-               state = card->states[0] = (struct i810_state *)
-                                       kmalloc(sizeof(struct i810_state), GFP_KERNEL);
-               if (state == NULL)
-                       return;
-               memset(state, 0, sizeof(struct i810_state));
-               dmabuf = &state->dmabuf;
-
-               dmabuf->write_channel = card->alloc_pcm_channel(card);
-               state->virt = 0;
-               state->card = card;
-               state->magic = I810_STATE_MAGIC;
-               init_waitqueue_head(&dmabuf->wait);
-               init_MUTEX(&state->open_sem);
-               dmabuf->fmt = I810_FMT_STEREO | I810_FMT_16BIT;
-               dmabuf->trigger = PCM_ENABLE_OUTPUT;
-               i810_set_dac_rate(state, 48000);
-               if(prog_dmabuf(state, 0) != 0) {
-                       goto config_out_nodmabuf;
-               }
-               if(dmabuf->dmasize < 16384) {
-                       goto config_out;
-               }
-               dmabuf->count = dmabuf->dmasize;
-               outb(31,card->iobase+dmabuf->write_channel->port+OFF_LVI);
-               save_flags(flags);
-               cli();
-               start_dac(state);
-               offset = i810_get_dma_addr(state, 0);
-               mdelay(50);
-               new_offset = i810_get_dma_addr(state, 0);
-               stop_dac(state);
-               outb(2,card->iobase+dmabuf->write_channel->port+OFF_CR);
-               restore_flags(flags);
-               i = new_offset - offset;
-#ifdef DEBUG
-               printk("i810_audio: %d bytes in 50 milliseconds\n", i);
-#endif
-               if(i == 0)
-                       goto config_out;
-               i = i / 4 * 20;
-               if (i > 48500 || i < 47500) {
-                       clocking = clocking * clocking / i;
-                       printk("i810_audio: setting clocking to %d\n", clocking);
-               }
-config_out:
-               dealloc_dmabuf(state);
-config_out_nodmabuf:
-               state->card->free_pcm_channel(state->card,state->dmabuf.write_channel->num);
-               kfree(state);
-               card->states[0] = NULL;
-       }
-}
 
 static int __init i810_init_module (void)
 {
diff --git a/drivers/sound/ite8172.c b/drivers/sound/ite8172.c
new file mode 100644 (file)
index 0000000..bf07c16
--- /dev/null
@@ -0,0 +1,1957 @@
+/*
+ *      ite8172.c  --  ITE IT8172G Sound Driver.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ *             stevel@mvista.com or source@mvista.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 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * Module command line parameters:
+ *
+ *  Supported devices:
+ *  /dev/dsp    standard OSS /dev/dsp device
+ *  /dev/mixer  standard OSS /dev/mixer device
+ *
+ * Notes:
+ *
+ *  1. Much of the OSS buffer allocation, ioctl's, and mmap'ing are
+ *     taken, slightly modified or not at all, from the ES1371 driver,
+ *     so refer to the credits in es1371.c for those. The rest of the
+ *     code (probe, open, read, write, the ISR, etc.) is new.
+ *  2. The following support is untested:
+ *      * Memory mapping the audio buffers, and the ioctl controls that go
+ *        with it.
+ *      * S/PDIF output.
+ *  3. The following is not supported:
+ *      * I2S input.
+ *      * legacy audio mode.
+ *  4. Support for volume button interrupts is implemented but doesn't
+ *     work yet.
+ *
+ *  Revision history
+ *    02.08.2001  0.1   Initial release
+ */
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/sound.h>
+#include <linux/malloc.h>
+#include <linux/soundcard.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/bitops.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
+#include <linux/ac97_codec.h>
+#include <linux/wrapper.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/uaccess.h>
+#include <asm/hardirq.h>
+#include <asm/it8172/it8172.h>
+
+/* --------------------------------------------------------------------- */
+
+#undef OSS_DOCUMENTED_MIXER_SEMANTICS
+#define IT8172_DEBUG
+#undef IT8172_VERBOSE_DEBUG
+#define DBG(x) {}
+
+static const unsigned sample_shift[] = { 0, 1, 1, 2 };
+
+
+/*
+ * Audio Controller register bit definitions follow. See
+ * include/asm/it8172/it8172.h for register offsets.
+ */
+
+/* PCM Out Volume Reg */
+#define PCMOV_PCMOM    (1<<15) /* PCM Out Mute default 1: mute */
+#define        PCMOV_PCMRCG_BIT 8      /* PCM Right channel Gain */
+#define        PCMOV_PCMRCG_MASK (0x1f<<PCMOV_PCMRCG_BIT)
+#define PCMOV_PCMLCG_BIT 0     /* PCM Left channel gain  */
+#define PCMOV_PCMLCG_MASK 0x1f
+
+/* FM Out Volume Reg */
+#define FMOV_FMOM       (1<<15)        /* FM Out Mute default 1: mute */
+#define        FMOV_FMRCG_BIT  8       /* FM Right channel Gain */
+#define        FMOV_FMRCG_MASK (0x1f<<FMOV_FMRCG_BIT)
+#define FMOV_FMLCG_BIT 0       /* FM Left channel gain  */
+#define FMOV_FMLCG_MASK 0x1f
+
+/* I2S Out Volume Reg */
+#define I2SV_I2SOM      (1<<15) /* I2S Out Mute default 1: mute */
+#define        I2SV_I2SRCG_BIT  8       /* I2S Right channel Gain */
+#define        I2SV_I2SRCG_MASK (0x1f<<I2SV_I2SRCG_BIT)
+#define I2SV_I2SLCG_BIT         0       /* I2S Left channel gain  */
+#define I2SV_I2SLCG_MASK 0x1f
+
+/* Digital Recording Source Select Reg */
+#define        DRSS_BIT   0
+#define        DRSS_MASK  0x07
+#define   DRSS_AC97_PRIM 0
+#define   DRSS_FM        1
+#define   DRSS_I2S       2
+#define   DRSS_PCM       3
+#define   DRSS_AC97_SEC  4
+
+/* Playback/Capture Channel Control Registers */
+#define        CC_SM           (1<<15) /* Stereo, Mone 0: mono 1: stereo */
+#define        CC_DF           (1<<14) /* Data Format 0: 8 bit 1: 16 bit */
+#define CC_FMT_BIT      14
+#define CC_FMT_MASK     (0x03<<CC_FMT_BIT)
+#define CC_CF_BIT       12      /* Channel format (Playback only) */
+#define CC_CF_MASK      (0x03<<CC_CF_BIT)
+#define          CC_CF_2       0
+#define   CC_CF_4      (1<<CC_CF_BIT)
+#define   CC_CF_6      (2<<CC_CF_BIT)
+#define CC_SR_BIT       8       /* sample Rate */
+#define CC_SR_MASK      (0x0f<<CC_SR_BIT)
+#define          CC_SR_5500    0
+#define          CC_SR_8000    (1<<CC_SR_BIT)
+#define          CC_SR_9600    (2<<CC_SR_BIT)
+#define          CC_SR_11025   (3<<CC_SR_BIT)
+#define          CC_SR_16000   (4<<CC_SR_BIT)
+#define          CC_SR_19200   (5<<CC_SR_BIT)
+#define          CC_SR_22050   (6<<CC_SR_BIT)
+#define          CC_SR_32000   (7<<CC_SR_BIT)
+#define          CC_SR_38400   (8<<CC_SR_BIT)
+#define          CC_SR_44100   (9<<CC_SR_BIT)
+#define          CC_SR_48000   (10<<CC_SR_BIT)
+#define        CC_CSP          (1<<7)  /* Channel stop 
+                                * 0: End of Current buffer
+                                * 1: Immediately stop when rec stop */
+#define CC_CP          (1<<6)  /* Channel pause 0: normal, 1: pause */
+#define        CC_CA           (1<<5)  /* Channel Action 0: Stop , 1: start */
+#define        CC_CB2L         (1<<2)  /* Cur. buf. 2 xfr is last 0: No, 1: Yes */
+#define CC_CB1L         (1<<1) /* Cur. buf. 1 xfr is last 0: No, 1: Yes */
+#define CC_DE          1       /* DFC/DFIFO Data Empty 1: empty, 0: not empty
+                                * (Playback only)
+                                */
+
+/* Codec Control Reg */
+#define CODECC_GME     (1<<9)  /* AC97 GPIO Mode enable */
+#define        CODECC_ATM      (1<<8)  /* AC97 ATE test mode 0: test 1: normal */
+#define        CODECC_WR       (1<<6)  /* AC97 Warn reset 1: warm reset , 0: Normal */
+#define        CODECC_CR       (1<<5)  /* AC97 Cold reset 1: Cold reset , 0: Normal */
+
+
+/* I2S Control Reg     */
+#define        I2SMC_SR_BIT     6      /* I2S Sampling rate 
+                                * 00: 48KHz, 01: 44.1 KHz, 10: 32 32 KHz */
+#define        I2SMC_SR_MASK    (0x03<<I2SMC_SR_BIT)
+#define          I2SMC_SR_48000 0
+#define          I2SMC_SR_44100 (1<<I2SMC_SR_BIT)
+#define          I2SMC_SR_32000 (2<<I2SMC_SR_BIT)
+#define        I2SMC_SRSS       (1<<5) /* Sample Rate Source Select 1:S/W, 0: H/W */
+#define I2SMC_I2SF_BIT  0      /* I2S Format */
+#define I2SMC_I2SF_MASK  0x03
+#define   I2SMC_I2SF_DAC 0
+#define   I2SMC_I2SF_ADC 2
+#define   I2SMC_I2SF_I2S 3
+
+
+/* Volume up, Down, Mute */
+#define        VS_VMP  (1<<2)  /* Volume mute 1: pushed, 0: not */
+#define        VS_VDP  (1<<1)  /* Volume Down 1: pushed, 0: not */
+#define VS_VUP 1       /* Volime Up 1: pushed, 0: not */
+
+/* SRC, Mixer test control/DFC status reg */
+#define SRCS_DPUSC      (1<<5) /* DFC Playback underrun Status/clear */
+#define        SRCS_DCOSC      (1<<4)  /* DFC Capture Overrun Status/clear */
+#define SRCS_SIS       (1<<3)  /* SRC input select 1: Mixer, 0: Codec I/F */
+#define SRCS_CDIS_BIT  0       /* Codec Data Input Select */
+#define SRCS_CDIS_MASK  0x07
+#define   SRCS_CDIS_MIXER 0
+#define   SRCS_CDIS_PCM   1
+#define   SRCS_CDIS_I2S   2
+#define   SRCS_CDIS_FM    3
+#define   SRCS_CDIS_DFC   4
+
+
+/* Codec Index Reg command Port */
+#define CIRCP_CID_BIT   10
+#define CIRCP_CID_MASK  (0x03<<CIRCP_CID_BIT)
+#define CIRCP_CPS      (1<<9)  /* Command Port Status 0: ready, 1: busy */
+#define        CIRCP_DPVF      (1<<8)  /* Data Port Valid Flag 0: invalis, 1: valid */
+#define CIRCP_RWC      (1<<7)  /* Read/write command */
+#define CIRCP_CIA_BIT   0
+#define CIRCP_CIA_MASK  0x007F /* Codec Index Address */
+
+/* Test Mode Control/Test group Select Control */
+
+/* General Control Reg */
+#define GC_VDC_BIT     6       /* Volume Division Control */
+#define GC_VDC_MASK     (0x03<<GC_VDC_BIT)
+#define   GC_VDC_NONE   0
+#define   GC_VDC_DIV2   (1<<GC_VDC_BIT)
+#define   GC_VDC_DIV4   (2<<GC_VDC_BIT)
+#define        GC_SOE          (1<<2)  /* S/PDIF Output enable */
+#define        GC_SWR          1       /* Software warn reset */
+
+/* Interrupt mask Control Reg */
+#define        IMC_VCIM        (1<<6)  /* Volume CNTL interrupt mask */
+#define        IMC_CCIM        (1<<1)  /* Capture Chan. iterrupt mask */
+#define        IMC_PCIM        1       /* Playback Chan. interrupt mask */
+
+/* Interrupt status/clear reg */
+#define        ISC_VCI         (1<<6)  /* Volume CNTL interrupt 1: clears */
+#define        ISC_CCI         (1<<1)  /* Capture Chan. interrupt 1: clears  */
+#define        ISC_PCI         1       /* Playback Chan. interrupt 1: clears */
+
+/* misc stuff */
+#define POLL_COUNT   0x5000
+
+
+#define IT8172_MODULE_NAME "IT8172 audio"
+#define PFX IT8172_MODULE_NAME ": "
+
+
+/* --------------------------------------------------------------------- */
+
+struct it8172_state {
+    /* list of it8172 devices */
+    struct list_head devs;
+
+    /* the corresponding pci_dev structure */
+    struct pci_dev *dev;
+
+    /* soundcore stuff */
+    int dev_audio;
+
+    /* hardware resources */
+    unsigned long io;
+    unsigned int irq;
+
+    /* PCI ID's */
+    u16 vendor;
+    u16 device;
+    u8 rev; /* the chip revision */
+
+    /* options */
+    int spdif_volume; /* S/PDIF output is enabled if != -1 */
+
+#ifdef IT8172_DEBUG
+    /* debug /proc entry */
+    struct proc_dir_entry *ps;
+    struct proc_dir_entry *ac97_ps;
+#endif /* IT8172_DEBUG */
+
+    struct ac97_codec codec;
+
+    unsigned short pcc, capcc;
+    unsigned dacrate, adcrate;
+
+    spinlock_t lock;
+    struct semaphore open_sem;
+    mode_t open_mode;
+    wait_queue_head_t open_wait;
+
+    struct dmabuf {
+       void *rawbuf;
+       dma_addr_t dmaaddr;
+       unsigned buforder;
+       unsigned numfrag;
+       unsigned fragshift;
+       void* nextIn;
+       void* nextOut;
+       int count;
+       int curBufPtr;
+       unsigned total_bytes;
+       unsigned error; /* over/underrun */
+       wait_queue_head_t wait;
+       /* redundant, but makes calculations easier */
+       unsigned fragsize;
+       unsigned dmasize;
+       unsigned fragsamples;
+       /* OSS stuff */
+       unsigned mapped:1;
+       unsigned ready:1;
+       unsigned stopped:1;
+       unsigned ossfragshift;
+       int ossmaxfrags;
+       unsigned subdivision;
+    } dma_dac, dma_adc;
+};
+
+/* --------------------------------------------------------------------- */
+
+static LIST_HEAD(devs);
+
+/* --------------------------------------------------------------------- */
+
+extern inline unsigned ld2(unsigned int x)
+{
+    unsigned r = 0;
+       
+    if (x >= 0x10000) {
+       x >>= 16;
+       r += 16;
+    }
+    if (x >= 0x100) {
+       x >>= 8;
+       r += 8;
+    }
+    if (x >= 0x10) {
+       x >>= 4;
+       r += 4;
+    }
+    if (x >= 4) {
+       x >>= 2;
+       r += 2;
+    }
+    if (x >= 2)
+       r++;
+    return r;
+}
+
+/* --------------------------------------------------------------------- */
+
+static void it8172_delay(int msec)
+{
+    unsigned long tmo;
+    signed long tmo2;
+
+    if (in_interrupt())
+       return;
+    
+    tmo = jiffies + (msec*HZ)/1000;
+    for (;;) {
+       tmo2 = tmo - jiffies;
+       if (tmo2 <= 0)
+           break;
+       schedule_timeout(tmo2);
+    }
+}
+
+
+static unsigned short
+get_compat_rate(unsigned* rate)
+{
+    unsigned rate_out = *rate;
+    unsigned short sr;
+    
+    if (rate_out >= 46050) {
+       sr = CC_SR_48000; rate_out = 48000;
+    } else if (rate_out >= 41250) {
+       sr = CC_SR_44100; rate_out = 44100;
+    } else if (rate_out >= 35200) {
+       sr = CC_SR_38400; rate_out = 38400;
+    } else if (rate_out >= 27025) {
+       sr = CC_SR_32000; rate_out = 32000;
+    } else if (rate_out >= 20625) {
+       sr = CC_SR_22050; rate_out = 22050;
+    } else if (rate_out >= 17600) {
+       sr = CC_SR_19200; rate_out = 19200;
+    } else if (rate_out >= 13513) {
+       sr = CC_SR_16000; rate_out = 16000;
+    } else if (rate_out >= 10313) {
+       sr = CC_SR_11025; rate_out = 11025;
+    } else if (rate_out >= 8800) {
+       sr = CC_SR_9600; rate_out = 9600;
+    } else if (rate_out >= 6750) {
+       sr = CC_SR_8000; rate_out = 8000;
+    } else {
+       sr = CC_SR_5500; rate_out = 5500;
+    }
+
+    *rate = rate_out;
+    return sr;
+}
+
+static void set_adc_rate(struct it8172_state *s, unsigned rate)
+{
+    unsigned long flags;
+    unsigned short sr;
+    
+    sr = get_compat_rate(&rate);
+
+    spin_lock_irqsave(&s->lock, flags);
+    s->capcc &= ~CC_SR_MASK;
+    s->capcc |= sr;
+    outw(s->capcc, s->io+IT_AC_CAPCC);
+    spin_unlock_irqrestore(&s->lock, flags);
+
+    s->adcrate = rate;
+}
+
+
+static void set_dac_rate(struct it8172_state *s, unsigned rate)
+{
+    unsigned long flags;
+    unsigned short sr;
+    
+    sr = get_compat_rate(&rate);
+
+    spin_lock_irqsave(&s->lock, flags);
+    s->pcc &= ~CC_SR_MASK;
+    s->pcc |= sr;
+    outw(s->pcc, s->io+IT_AC_PCC);
+    spin_unlock_irqrestore(&s->lock, flags);
+
+    s->dacrate = rate;
+}
+
+
+/* --------------------------------------------------------------------- */
+
+static u16 rdcodec(struct ac97_codec *codec, u8 addr)
+{
+    struct it8172_state *s = (struct it8172_state *)codec->private_data;
+    unsigned long flags;
+    unsigned short circp, data;
+    int i;
+    
+    spin_lock_irqsave(&s->lock, flags);
+
+    for (i = 0; i < POLL_COUNT; i++)
+       if (!(inw(s->io+IT_AC_CIRCP) & CIRCP_CPS))
+           break;
+    if (i == POLL_COUNT)
+       printk(KERN_INFO PFX "rdcodec: codec ready poll expired!\n");
+
+    circp = addr & CIRCP_CIA_MASK;
+    circp |= (codec->id << CIRCP_CID_BIT);
+    circp |= CIRCP_RWC; // read command
+    outw(circp, s->io+IT_AC_CIRCP);
+
+    /* now wait for the data */
+    for (i = 0; i < POLL_COUNT; i++)
+       if (inw(s->io+IT_AC_CIRCP) & CIRCP_DPVF)
+           break;
+    if (i == POLL_COUNT)
+       printk(KERN_INFO PFX "rdcodec: read poll expired!\n");
+
+    data = inw(s->io+IT_AC_CIRDP);
+    spin_unlock_irqrestore(&s->lock, flags);
+
+    return data;
+}
+
+
+static void wrcodec(struct ac97_codec *codec, u8 addr, u16 data)
+{
+    struct it8172_state *s = (struct it8172_state *)codec->private_data;
+    unsigned long flags;
+    unsigned short circp;
+    int i;
+    
+    spin_lock_irqsave(&s->lock, flags);
+
+    for (i = 0; i < POLL_COUNT; i++)
+       if (!(inw(s->io+IT_AC_CIRCP) & CIRCP_CPS))
+           break;
+    if (i == POLL_COUNT)
+       printk(KERN_INFO PFX "wrcodec: codec ready poll expired!\n");
+
+    circp = addr & CIRCP_CIA_MASK;
+    circp |= (codec->id << CIRCP_CID_BIT);
+    circp &= ~CIRCP_RWC; // write command
+
+    outw(data,  s->io+IT_AC_CIRDP);  // send data first
+    outw(circp, s->io+IT_AC_CIRCP);
+
+    spin_unlock_irqrestore(&s->lock, flags);
+}
+
+
+static void waitcodec(struct ac97_codec *codec)
+{
+    unsigned short temp;
+
+    /* codec_wait is used to wait for a ready state after
+       an AC97_RESET. */
+    it8172_delay(10);
+
+    temp = rdcodec(codec, 0x26);
+
+    // If power down, power up
+    if (temp & 0x3f00) {
+       // Power on
+       wrcodec(codec, 0x26, 0);
+       it8172_delay(100);
+       // Reread
+       temp = rdcodec(codec, 0x26);
+    }
+    
+    // Check if Codec REF,ANL,DAC,ADC ready***/
+    if ((temp & 0x3f0f) != 0x000f) {
+       printk(KERN_INFO PFX "codec reg 26 status (0x%x) not ready!!\n",
+              temp);
+       return;
+    }
+}
+
+
+/* --------------------------------------------------------------------- */
+
+extern inline void stop_adc(struct it8172_state *s)
+{
+    struct dmabuf* db = &s->dma_adc;
+    unsigned long flags;
+    unsigned char imc;
+    
+    if (db->stopped)
+       return;
+
+    spin_lock_irqsave(&s->lock, flags);
+
+    s->capcc &= ~(CC_CA | CC_CP | CC_CB2L | CC_CB1L);
+    s->capcc |= CC_CSP;
+    outw(s->capcc, s->io+IT_AC_CAPCC);
+    
+    // disable capture interrupt
+    imc = inb(s->io+IT_AC_IMC);
+    outb(imc | IMC_CCIM, s->io+IT_AC_IMC);
+
+    db->stopped = 1;
+
+    spin_unlock_irqrestore(&s->lock, flags);
+}      
+
+extern inline void stop_dac(struct it8172_state *s)
+{
+    struct dmabuf* db = &s->dma_dac;
+    unsigned long flags;
+    unsigned char imc;
+    
+    if (db->stopped)
+       return;
+
+    spin_lock_irqsave(&s->lock, flags);
+
+    s->pcc &= ~(CC_CA | CC_CP | CC_CB2L | CC_CB1L);
+    s->pcc |= CC_CSP;
+    outw(s->pcc, s->io+IT_AC_PCC);
+    
+    // disable playback interrupt
+    imc = inb(s->io+IT_AC_IMC);
+    outb(imc | IMC_PCIM, s->io+IT_AC_IMC);
+
+    db->stopped = 1;
+    
+    spin_unlock_irqrestore(&s->lock, flags);
+}      
+
+static void start_dac(struct it8172_state *s)
+{
+    struct dmabuf* db = &s->dma_dac;
+    unsigned long flags;
+    unsigned char imc;
+    unsigned long buf1, buf2;
+    
+    if (!db->stopped)
+       return;
+    
+    spin_lock_irqsave(&s->lock, flags);
+
+    // reset Buffer 1 and 2 pointers to nextOut and nextOut+fragsize
+    buf1 = virt_to_bus(db->nextOut);
+    buf2 = buf1 + db->fragsize;
+    if (buf2 >= db->dmaaddr + db->dmasize)
+       buf2 -= db->dmasize;
+    
+    outl(buf1, s->io+IT_AC_PCB1STA);
+    outl(buf2, s->io+IT_AC_PCB2STA);
+    db->curBufPtr = IT_AC_PCB1STA;
+    
+    // enable playback interrupt
+    imc = inb(s->io+IT_AC_IMC);
+    outb(imc & ~IMC_PCIM, s->io+IT_AC_IMC);
+
+    s->pcc &= ~(CC_CSP | CC_CP | CC_CB2L | CC_CB1L);
+    s->pcc |= CC_CA;
+    outw(s->pcc, s->io+IT_AC_PCC);
+    
+    db->stopped = 0;
+
+    spin_unlock_irqrestore(&s->lock, flags);
+}      
+
+static void start_adc(struct it8172_state *s)
+{
+    struct dmabuf* db = &s->dma_adc;
+    unsigned long flags;
+    unsigned char imc;
+    unsigned long buf1, buf2;
+    
+    if (!db->stopped)
+       return;
+
+    spin_lock_irqsave(&s->lock, flags);
+
+    // reset Buffer 1 and 2 pointers to nextIn and nextIn+fragsize
+    buf1 = virt_to_bus(db->nextIn);
+    buf2 = buf1 + db->fragsize;
+    if (buf2 >= db->dmaaddr + db->dmasize)
+       buf2 -= db->dmasize;
+    
+    outl(buf1, s->io+IT_AC_CAPB1STA);
+    outl(buf2, s->io+IT_AC_CAPB2STA);
+    db->curBufPtr = IT_AC_CAPB1STA;
+
+    // enable capture interrupt
+    imc = inb(s->io+IT_AC_IMC);
+    outb(imc & ~IMC_CCIM, s->io+IT_AC_IMC);
+
+    s->capcc &= ~(CC_CSP | CC_CP | CC_CB2L | CC_CB1L);
+    s->capcc |= CC_CA;
+    outw(s->capcc, s->io+IT_AC_CAPCC);
+    
+    db->stopped = 0;
+
+    spin_unlock_irqrestore(&s->lock, flags);
+}      
+
+/* --------------------------------------------------------------------- */
+
+#define DMABUF_DEFAULTORDER (17-PAGE_SHIFT)
+#define DMABUF_MINORDER 1
+
+extern inline void dealloc_dmabuf(struct it8172_state *s, struct dmabuf *db)
+{
+    struct page *page, *pend;
+
+    if (db->rawbuf) {
+       /* undo marking the pages as reserved */
+       pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
+       for (page = virt_to_page(db->rawbuf); page <= pend; page++)
+           mem_map_unreserve(page);
+       pci_free_consistent(s->dev, PAGE_SIZE << db->buforder,
+                           db->rawbuf, db->dmaaddr);
+    }
+    db->rawbuf = db->nextIn = db->nextOut = NULL;
+    db->mapped = db->ready = 0;
+}
+
+static int prog_dmabuf(struct it8172_state *s, struct dmabuf *db,
+                      unsigned rate, unsigned fmt, unsigned reg)
+{
+    int order;
+    unsigned bytepersec;
+    unsigned bufs;
+    struct page *page, *pend;
+
+    if (!db->rawbuf) {
+       db->ready = db->mapped = 0;
+       for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
+           if ((db->rawbuf = pci_alloc_consistent(s->dev,
+                                                  PAGE_SIZE << order,
+                                                  &db->dmaaddr)))
+               break;
+       if (!db->rawbuf)
+           return -ENOMEM;
+       db->buforder = order;
+       /* now mark the pages as reserved;
+          otherwise remap_page_range doesn't do what we want */
+       pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
+       for (page = virt_to_page(db->rawbuf); page <= pend; page++)
+           mem_map_reserve(page);
+    }
+
+    db->count = 0;
+    db->nextIn = db->nextOut = db->rawbuf;
+    
+    bytepersec = rate << sample_shift[fmt];
+    bufs = PAGE_SIZE << db->buforder;
+    if (db->ossfragshift) {
+       if ((1000 << db->ossfragshift) < bytepersec)
+           db->fragshift = ld2(bytepersec/1000);
+       else
+           db->fragshift = db->ossfragshift;
+    } else {
+       db->fragshift = ld2(bytepersec/100/(db->subdivision ?
+                                           db->subdivision : 1));
+       if (db->fragshift < 3)
+           db->fragshift = 3;
+    }
+    db->numfrag = bufs >> db->fragshift;
+    while (db->numfrag < 4 && db->fragshift > 3) {
+       db->fragshift--;
+       db->numfrag = bufs >> db->fragshift;
+    }
+    db->fragsize = 1 << db->fragshift;
+    if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
+       db->numfrag = db->ossmaxfrags;
+    db->fragsamples = db->fragsize >> sample_shift[fmt];
+    db->dmasize = db->numfrag << db->fragshift;
+    memset(db->rawbuf, (fmt & (CC_DF>>CC_FMT_BIT)) ? 0 : 0x80, db->dmasize);
+    
+    // set data length register
+    outw(db->fragsize, s->io+reg+2);
+    db->ready = 1;
+
+    return 0;
+}
+
+extern inline int prog_dmabuf_adc(struct it8172_state *s)
+{
+    stop_adc(s);
+    return prog_dmabuf(s, &s->dma_adc, s->adcrate,
+                      (s->capcc & CC_FMT_MASK) >> CC_FMT_BIT,
+                      IT_AC_CAPCC);
+}
+
+extern inline int prog_dmabuf_dac(struct it8172_state *s)
+{
+    stop_dac(s);
+    return prog_dmabuf(s, &s->dma_dac, s->dacrate,
+                      (s->pcc & CC_FMT_MASK) >> CC_FMT_BIT,
+                      IT_AC_PCC);
+}
+
+
+/* hold spinlock for the following! */
+
+static void it8172_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+    struct it8172_state *s = (struct it8172_state *)dev_id;
+    struct dmabuf* dac = &s->dma_dac;
+    struct dmabuf* adc = &s->dma_adc;
+    unsigned char isc, vs;
+    unsigned short vol, mute;
+    unsigned long newptr;
+    
+    spin_lock(&s->lock);
+
+    isc = inb(s->io+IT_AC_ISC);
+
+    /* fastpath out, to ease interrupt sharing */
+    if (!(isc & (ISC_VCI | ISC_CCI | ISC_PCI)))
+       return;
+
+    /* clear audio interrupts first */
+    outb(isc | ISC_VCI | ISC_CCI | ISC_PCI, s->io+IT_AC_ISC);
+    
+    /* handle volume button events */
+    if (isc & ISC_VCI) {
+       vs = inb(s->io+IT_AC_VS);
+       outb(0, s->io+IT_AC_VS);
+       vol = inw(s->io+IT_AC_PCMOV);
+       mute = vol & PCMOV_PCMOM;
+       vol &= PCMOV_PCMLCG_MASK;
+       if ((vs & VS_VUP) && vol > 0)
+           vol--;
+       if ((vs & VS_VDP) && vol < 0x1f)
+           vol++;
+       vol |= (vol << PCMOV_PCMRCG_BIT);
+       if (vs & VS_VMP)
+           vol |= (mute ^ PCMOV_PCMOM);
+       outw(vol, s->io+IT_AC_PCMOV);
+    }
+    
+    /* update capture pointers */
+    if (isc & ISC_CCI) {
+       if (adc->count > adc->dmasize - adc->fragsize) {
+           // Overrun. Stop ADC and log the error
+           stop_adc(s);
+           adc->error++;
+           printk(KERN_INFO PFX "adc overrun\n");
+       } else {
+           newptr = virt_to_bus(adc->nextIn) + 2*adc->fragsize;
+           if (newptr >= adc->dmaaddr + adc->dmasize)
+               newptr -= adc->dmasize;
+           
+           outl(newptr, s->io+adc->curBufPtr);
+           adc->curBufPtr = (adc->curBufPtr == IT_AC_CAPB1STA) ?
+               IT_AC_CAPB2STA : IT_AC_CAPB1STA;
+           
+           adc->nextIn += adc->fragsize;
+           if (adc->nextIn >= adc->rawbuf + adc->dmasize)
+               adc->nextIn -= adc->dmasize;
+           
+           adc->count += adc->fragsize;
+           adc->total_bytes += adc->fragsize;
+
+           /* wake up anybody listening */
+           if (waitqueue_active(&adc->wait))
+               wake_up_interruptible(&adc->wait);
+       }
+    }
+    
+    /* update playback pointers */
+    if (isc & ISC_PCI) {
+       newptr = virt_to_bus(dac->nextOut) + 2*dac->fragsize;
+       if (newptr >= dac->dmaaddr + dac->dmasize)
+           newptr -= dac->dmasize;
+       
+       outl(newptr, s->io+dac->curBufPtr);
+       dac->curBufPtr = (dac->curBufPtr == IT_AC_PCB1STA) ?
+           IT_AC_PCB2STA : IT_AC_PCB1STA;
+       
+       dac->nextOut += dac->fragsize;
+       if (dac->nextOut >= dac->rawbuf + dac->dmasize)
+           dac->nextOut -= dac->dmasize;
+       
+       dac->count -= dac->fragsize;
+       dac->total_bytes += dac->fragsize;
+
+       /* wake up anybody listening */
+       if (waitqueue_active(&dac->wait))
+           wake_up_interruptible(&dac->wait);
+       
+       if (dac->count <= 0)
+           stop_dac(s);
+    }
+    
+    spin_unlock(&s->lock);
+}
+
+/* --------------------------------------------------------------------- */
+
+static loff_t it8172_llseek(struct file *file, loff_t offset, int origin)
+{
+    return -ESPIPE;
+}
+
+
+static int it8172_open_mixdev(struct inode *inode, struct file *file)
+{
+    int minor = MINOR(inode->i_rdev);
+    struct list_head *list;
+    struct it8172_state *s;
+
+    for (list = devs.next; ; list = list->next) {
+       if (list == &devs)
+           return -ENODEV;
+       s = list_entry(list, struct it8172_state, devs);
+       if (s->codec.dev_mixer == minor)
+           break;
+    }
+    file->private_data = s;
+    return 0;
+}
+
+static int it8172_release_mixdev(struct inode *inode, struct file *file)
+{
+    return 0;
+}
+
+
+static int mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd,
+                       unsigned long arg)
+{
+    return codec->mixer_ioctl(codec, cmd, arg);
+}
+
+static int it8172_ioctl_mixdev(struct inode *inode, struct file *file,
+                              unsigned int cmd, unsigned long arg)
+{
+    struct it8172_state *s = (struct it8172_state *)file->private_data;
+    struct ac97_codec *codec = &s->codec;
+
+    return mixdev_ioctl(codec, cmd, arg);
+}
+
+static /*const*/ struct file_operations it8172_mixer_fops = {
+    owner:     THIS_MODULE,
+    llseek:    it8172_llseek,
+    ioctl:     it8172_ioctl_mixdev,
+    open:      it8172_open_mixdev,
+    release:   it8172_release_mixdev,
+};
+
+/* --------------------------------------------------------------------- */
+
+static int drain_dac(struct it8172_state *s, int nonblock)
+{
+    unsigned long flags;
+    int count, tmo;
+       
+    if (s->dma_dac.mapped || !s->dma_dac.ready)
+       return 0;
+
+    for (;;) {
+       spin_lock_irqsave(&s->lock, flags);
+       count = s->dma_dac.count;
+       spin_unlock_irqrestore(&s->lock, flags);
+       if (count <= 0)
+           break;
+       if (signal_pending(current))
+           break;
+       if (nonblock)
+           return -EBUSY;
+       tmo = 1000 * count / s->dacrate;
+       tmo >>= sample_shift[(s->pcc & CC_FMT_MASK) >> CC_FMT_BIT];
+       it8172_delay(tmo);
+    }
+    if (signal_pending(current))
+       return -ERESTARTSYS;
+    return 0;
+}
+
+/* --------------------------------------------------------------------- */
+
+static ssize_t it8172_read(struct file *file, char *buffer,
+                          size_t count, loff_t *ppos)
+{
+    struct it8172_state *s = (struct it8172_state *)file->private_data;
+    struct dmabuf *db = &s->dma_adc;
+    ssize_t ret;
+    unsigned long flags;
+    int cnt, bufcnt, avail;
+
+    if (ppos != &file->f_pos)
+       return -ESPIPE;
+    if (db->mapped)
+       return -ENXIO;
+    if (!access_ok(VERIFY_WRITE, buffer, count))
+       return -EFAULT;
+    ret = 0;
+
+    while (count > 0) {
+       // wait for samples in capture buffer
+       do {
+           spin_lock_irqsave(&s->lock, flags);
+           if (db->stopped)
+               start_adc(s);
+           avail = db->count;
+           spin_unlock_irqrestore(&s->lock, flags);
+           if (avail <= 0) {
+               if (file->f_flags & O_NONBLOCK) {
+                   if (!ret)
+                       ret = -EAGAIN;
+                   return ret;
+               }
+               interruptible_sleep_on(&db->wait);
+               if (signal_pending(current)) {
+                   if (!ret)
+                       ret = -ERESTARTSYS;
+                   return ret;
+               }
+           }
+       } while (avail <= 0);
+
+       cnt = count > avail ? avail : count;
+       bufcnt = cnt;
+       if (cnt % db->fragsize) {
+           // round count up to nearest fragment
+           int newcnt = db->fragsize * ((cnt + db->fragsize) / db->fragsize);
+           cnt = newcnt;
+       }
+
+       // copy from nextOut to user
+       if (copy_to_user(buffer, db->nextOut, bufcnt)) {
+           if (!ret)
+               ret = -EFAULT;
+           return ret;
+       }
+
+       spin_lock_irqsave(&s->lock, flags);
+       db->count -= cnt;
+       spin_unlock_irqrestore(&s->lock, flags);
+
+       db->nextOut += cnt;
+       if (db->nextOut >= db->rawbuf + db->dmasize)
+           db->nextOut -= db->dmasize; 
+
+       count -= bufcnt;
+       buffer += bufcnt;
+       ret += bufcnt;
+    } // while (count > 0)
+
+    return ret;
+}
+
+static ssize_t it8172_write(struct file *file, const char *buffer,
+                           size_t count, loff_t *ppos)
+{
+    struct it8172_state *s = (struct it8172_state *)file->private_data;
+    struct dmabuf *db = &s->dma_dac;
+    ssize_t ret;
+    unsigned long flags;
+    int cnt, bufcnt, avail;
+
+    if (ppos != &file->f_pos)
+       return -ESPIPE;
+    if (db->mapped)
+       return -ENXIO;
+    if (!access_ok(VERIFY_READ, buffer, count))
+       return -EFAULT;
+    ret = 0;
+    
+    while (count > 0) {
+       // wait for space in playback buffer
+       do {
+           spin_lock_irqsave(&s->lock, flags);
+           avail = db->dmasize - db->count;
+           spin_unlock_irqrestore(&s->lock, flags);
+           if (avail <= 0) {
+               if (file->f_flags & O_NONBLOCK) {
+                   if (!ret)
+                       ret = -EAGAIN;
+                   return ret;
+               }
+               interruptible_sleep_on(&db->wait);
+               if (signal_pending(current)) {
+                   if (!ret)
+                       ret = -ERESTARTSYS;
+                   return ret;
+               }
+           }
+       } while (avail <= 0);
+       
+       cnt = count > avail ? avail : count;
+       // copy to nextIn
+       if (copy_from_user(db->nextIn, buffer, cnt)) {
+           if (!ret)
+               ret = -EFAULT;
+           return ret;
+       }
+
+       bufcnt = cnt;
+       if (cnt % db->fragsize) {
+           // round count up to nearest fragment, and fill remainder of
+           // fragment with silence
+           int newcnt = db->fragsize * ((cnt + db->fragsize) / db->fragsize);
+           memset(db->nextIn + cnt, (s->pcc & CC_DF) ? 0 : 0x80, newcnt - cnt);
+           cnt = newcnt;
+       }
+
+       spin_lock_irqsave(&s->lock, flags);
+       db->count += cnt;
+       if (db->stopped)
+           start_dac(s);
+       spin_unlock_irqrestore(&s->lock, flags);
+       
+       db->nextIn += cnt;
+       if (db->nextIn >= db->rawbuf + db->dmasize)
+           db->nextIn -= db->dmasize;
+       
+       count -= bufcnt;
+       buffer += bufcnt;
+       ret += bufcnt;
+    } // while (count > 0)
+       
+    return ret;
+}
+
+/* No kernel lock - we have our own spinlock */
+static unsigned int it8172_poll(struct file *file,
+                               struct poll_table_struct *wait)
+{
+    struct it8172_state *s = (struct it8172_state *)file->private_data;
+    unsigned long flags;
+    unsigned int mask = 0;
+
+    if (file->f_mode & FMODE_WRITE)
+       poll_wait(file, &s->dma_dac.wait, wait);
+    if (file->f_mode & FMODE_READ)
+       poll_wait(file, &s->dma_adc.wait, wait);
+    spin_lock_irqsave(&s->lock, flags);
+    if (file->f_mode & FMODE_READ) {
+       if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
+           mask |= POLLIN | POLLRDNORM;
+    }
+    if (file->f_mode & FMODE_WRITE) {
+       if (s->dma_dac.mapped) {
+           if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) 
+               mask |= POLLOUT | POLLWRNORM;
+       } else {
+           if ((signed)s->dma_dac.dmasize >=
+               s->dma_dac.count + (signed)s->dma_dac.fragsize)
+               mask |= POLLOUT | POLLWRNORM;
+       }
+    }
+    spin_unlock_irqrestore(&s->lock, flags);
+    return mask;
+}
+
+static int it8172_mmap(struct file *file, struct vm_area_struct *vma)
+{
+    struct it8172_state *s = (struct it8172_state *)file->private_data;
+    struct dmabuf *db;
+    unsigned long size;
+
+    lock_kernel();
+    if (vma->vm_flags & VM_WRITE)
+       db = &s->dma_dac;
+    else if (vma->vm_flags & VM_READ)
+       db = &s->dma_adc;
+    else {
+       unlock_kernel();
+       return -EINVAL;
+    }
+    if (vma->vm_pgoff != 0) {
+       unlock_kernel();
+       return -EINVAL;
+    }
+    size = vma->vm_end - vma->vm_start;
+    if (size > (PAGE_SIZE << db->buforder)) {
+       unlock_kernel();
+       return -EINVAL;
+    }
+    if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf),
+                        size, vma->vm_page_prot)) {
+       unlock_kernel();
+       return -EAGAIN;
+    }
+    db->mapped = 1;
+    unlock_kernel();
+    return 0;
+}
+
+
+#ifdef IT8172_VERBOSE_DEBUG
+static struct ioctl_str_t {
+    unsigned int cmd;
+    const char* str;
+} ioctl_str[] = {
+    {SNDCTL_DSP_RESET, "SNDCTL_DSP_RESET"},
+    {SNDCTL_DSP_SYNC, "SNDCTL_DSP_SYNC"},
+    {SNDCTL_DSP_SPEED, "SNDCTL_DSP_SPEED"},
+    {SNDCTL_DSP_STEREO, "SNDCTL_DSP_STEREO"},
+    {SNDCTL_DSP_GETBLKSIZE, "SNDCTL_DSP_GETBLKSIZE"},
+    {SNDCTL_DSP_SAMPLESIZE, "SNDCTL_DSP_SAMPLESIZE"},
+    {SNDCTL_DSP_CHANNELS, "SNDCTL_DSP_CHANNELS"},
+    {SOUND_PCM_WRITE_CHANNELS, "SOUND_PCM_WRITE_CHANNELS"},
+    {SOUND_PCM_WRITE_FILTER, "SOUND_PCM_WRITE_FILTER"},
+    {SNDCTL_DSP_POST, "SNDCTL_DSP_POST"},
+    {SNDCTL_DSP_SUBDIVIDE, "SNDCTL_DSP_SUBDIVIDE"},
+    {SNDCTL_DSP_SETFRAGMENT, "SNDCTL_DSP_SETFRAGMENT"},
+    {SNDCTL_DSP_GETFMTS, "SNDCTL_DSP_GETFMTS"},
+    {SNDCTL_DSP_SETFMT, "SNDCTL_DSP_SETFMT"},
+    {SNDCTL_DSP_GETOSPACE, "SNDCTL_DSP_GETOSPACE"},
+    {SNDCTL_DSP_GETISPACE, "SNDCTL_DSP_GETISPACE"},
+    {SNDCTL_DSP_NONBLOCK, "SNDCTL_DSP_NONBLOCK"},
+    {SNDCTL_DSP_GETCAPS, "SNDCTL_DSP_GETCAPS"},
+    {SNDCTL_DSP_GETTRIGGER, "SNDCTL_DSP_GETTRIGGER"},
+    {SNDCTL_DSP_SETTRIGGER, "SNDCTL_DSP_SETTRIGGER"},
+    {SNDCTL_DSP_GETIPTR, "SNDCTL_DSP_GETIPTR"},
+    {SNDCTL_DSP_GETOPTR, "SNDCTL_DSP_GETOPTR"},
+    {SNDCTL_DSP_MAPINBUF, "SNDCTL_DSP_MAPINBUF"},
+    {SNDCTL_DSP_MAPOUTBUF, "SNDCTL_DSP_MAPOUTBUF"},
+    {SNDCTL_DSP_SETSYNCRO, "SNDCTL_DSP_SETSYNCRO"},
+    {SNDCTL_DSP_SETDUPLEX, "SNDCTL_DSP_SETDUPLEX"},
+    {SNDCTL_DSP_GETODELAY, "SNDCTL_DSP_GETODELAY"},
+    {SNDCTL_DSP_GETCHANNELMASK, "SNDCTL_DSP_GETCHANNELMASK"},
+    {SNDCTL_DSP_BIND_CHANNEL, "SNDCTL_DSP_BIND_CHANNEL"},
+    {OSS_GETVERSION, "OSS_GETVERSION"},
+    {SOUND_PCM_READ_RATE, "SOUND_PCM_READ_RATE"},
+    {SOUND_PCM_READ_CHANNELS, "SOUND_PCM_READ_CHANNELS"},
+    {SOUND_PCM_READ_BITS, "SOUND_PCM_READ_BITS"},
+    {SOUND_PCM_READ_FILTER, "SOUND_PCM_READ_FILTER"}
+};
+#endif    
+
+static int it8172_ioctl(struct inode *inode, struct file *file,
+                       unsigned int cmd, unsigned long arg)
+{
+    struct it8172_state *s = (struct it8172_state *)file->private_data;
+    unsigned long flags;
+    audio_buf_info abinfo;
+    count_info cinfo;
+    int count;
+    int val, mapped, ret, diff;
+
+    mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
+       ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
+
+#ifdef IT8172_VERBOSE_DEBUG
+    for (count=0; count<sizeof(ioctl_str)/sizeof(ioctl_str[0]); count++) {
+       if (ioctl_str[count].cmd == cmd)
+           break;
+    }
+    if (count < sizeof(ioctl_str)/sizeof(ioctl_str[0]))
+       printk(KERN_INFO PFX "ioctl %s\n", ioctl_str[count].str);
+    else
+       printk(KERN_INFO PFX "ioctl unknown, 0x%x\n", cmd);
+#endif
+    
+    switch (cmd) {
+    case OSS_GETVERSION:
+       return put_user(SOUND_VERSION, (int *)arg);
+
+    case SNDCTL_DSP_SYNC:
+       if (file->f_mode & FMODE_WRITE)
+           return drain_dac(s, file->f_flags & O_NONBLOCK);
+       return 0;
+               
+    case SNDCTL_DSP_SETDUPLEX:
+       return 0;
+
+    case SNDCTL_DSP_GETCAPS:
+       return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
+                       DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+               
+    case SNDCTL_DSP_RESET:
+       if (file->f_mode & FMODE_WRITE) {
+           stop_dac(s);
+           synchronize_irq();
+           s->dma_dac.count = s->dma_dac.total_bytes = 0;
+           s->dma_dac.nextIn = s->dma_dac.nextOut = s->dma_dac.rawbuf;
+       }
+       if (file->f_mode & FMODE_READ) {
+           stop_adc(s);
+           synchronize_irq();
+           s->dma_adc.count = s->dma_adc.total_bytes = 0;
+           s->dma_adc.nextIn = s->dma_adc.nextOut = s->dma_adc.rawbuf;
+       }
+       return 0;
+
+    case SNDCTL_DSP_SPEED:
+       if (get_user(val, (int *)arg))
+           return -EFAULT;
+       if (val >= 0) {
+           if (file->f_mode & FMODE_READ) {
+               stop_adc(s);
+               set_adc_rate(s, val);
+               if ((ret = prog_dmabuf_adc(s)))
+                   return ret;
+           }
+           if (file->f_mode & FMODE_WRITE) {
+               stop_dac(s);
+               set_dac_rate(s, val);
+               if ((ret = prog_dmabuf_dac(s)))
+                   return ret;
+           }
+       }
+       return put_user((file->f_mode & FMODE_READ) ?
+                       s->adcrate : s->dacrate, (int *)arg);
+
+    case SNDCTL_DSP_STEREO:
+       if (get_user(val, (int *)arg))
+           return -EFAULT;
+       if (file->f_mode & FMODE_READ) {
+           stop_adc(s);
+           if (val)
+               s->capcc |= CC_SM;
+           else
+               s->capcc &= ~CC_SM;
+           outw(s->capcc, s->io+IT_AC_CAPCC);
+           if ((ret = prog_dmabuf_adc(s)))
+               return ret;
+       }
+       if (file->f_mode & FMODE_WRITE) {
+           stop_dac(s);
+           if (val)
+               s->pcc |= CC_SM;
+           else
+               s->pcc &= ~CC_SM;
+           outw(s->pcc, s->io+IT_AC_PCC);
+           if ((ret = prog_dmabuf_dac(s)))
+               return ret;
+       }
+       return 0;
+
+    case SNDCTL_DSP_CHANNELS:
+       if (get_user(val, (int *)arg))
+           return -EFAULT;
+       if (val != 0) {
+           if (file->f_mode & FMODE_READ) {
+               stop_adc(s);
+               if (val >= 2) {
+                   val = 2;
+                   s->capcc |= CC_SM;
+               }
+               else
+                   s->capcc &= ~CC_SM;
+               outw(s->capcc, s->io+IT_AC_CAPCC);
+               if ((ret = prog_dmabuf_adc(s)))
+                   return ret;
+           }
+           if (file->f_mode & FMODE_WRITE) {
+               stop_dac(s);
+               switch (val) {
+               case 1:
+                   s->pcc &= ~CC_SM;
+                   break;
+               case 2:
+                   s->pcc |= CC_SM;
+                   break;
+               default:
+                   // FIX! support multichannel???
+                   val = 2;
+                   s->pcc |= CC_SM;
+                   break;
+               }
+               outw(s->pcc, s->io+IT_AC_PCC);
+               if ((ret = prog_dmabuf_dac(s)))
+                   return ret;
+           }
+       }
+       return put_user(val, (int *)arg);
+               
+    case SNDCTL_DSP_GETFMTS: /* Returns a mask */
+       return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
+               
+    case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
+       if (get_user(val, (int *)arg))
+           return -EFAULT;
+       if (val != AFMT_QUERY) {
+           if (file->f_mode & FMODE_READ) {
+               stop_adc(s);
+               if (val == AFMT_S16_LE)
+                   s->capcc |= CC_DF;
+               else {
+                   val = AFMT_U8;
+                   s->capcc &= ~CC_DF;
+               }
+               outw(s->capcc, s->io+IT_AC_CAPCC);
+               if ((ret = prog_dmabuf_adc(s)))
+                   return ret;
+           }
+           if (file->f_mode & FMODE_WRITE) {
+               stop_dac(s);
+               if (val == AFMT_S16_LE)
+                   s->pcc |= CC_DF;
+               else {
+                   val = AFMT_U8;
+                   s->pcc &= ~CC_DF;
+               }
+               outw(s->pcc, s->io+IT_AC_PCC);
+               if ((ret = prog_dmabuf_dac(s)))
+                   return ret;
+           }
+       } else {
+           if (file->f_mode & FMODE_READ)
+               val = (s->capcc & CC_DF) ? AFMT_S16_LE : AFMT_U8;
+           else
+               val = (s->pcc & CC_DF) ? AFMT_S16_LE : AFMT_U8;
+       }
+       return put_user(val, (int *)arg);
+               
+    case SNDCTL_DSP_POST:
+       return 0;
+
+    case SNDCTL_DSP_GETTRIGGER:
+       val = 0;
+       spin_lock_irqsave(&s->lock, flags);
+       if (file->f_mode & FMODE_READ && !s->dma_adc.stopped)
+           val |= PCM_ENABLE_INPUT;
+       if (file->f_mode & FMODE_WRITE && !s->dma_dac.stopped)
+           val |= PCM_ENABLE_OUTPUT;
+       spin_unlock_irqrestore(&s->lock, flags);
+       return put_user(val, (int *)arg);
+               
+    case SNDCTL_DSP_SETTRIGGER:
+       if (get_user(val, (int *)arg))
+           return -EFAULT;
+       if (file->f_mode & FMODE_READ) {
+           if (val & PCM_ENABLE_INPUT)
+               start_adc(s);
+           else
+               stop_adc(s);
+       }
+       if (file->f_mode & FMODE_WRITE) {
+           if (val & PCM_ENABLE_OUTPUT)
+               start_dac(s);
+           else
+               stop_dac(s);
+       }
+       return 0;
+
+    case SNDCTL_DSP_GETOSPACE:
+       if (!(file->f_mode & FMODE_WRITE))
+           return -EINVAL;
+       abinfo.fragsize = s->dma_dac.fragsize;
+       spin_lock_irqsave(&s->lock, flags);
+       count = s->dma_dac.count;
+       if (!s->dma_dac.stopped)
+           count -= (s->dma_dac.fragsize - inw(s->io+IT_AC_PCDL));
+       spin_unlock_irqrestore(&s->lock, flags);
+       if (count < 0)
+           count = 0;
+       abinfo.bytes = s->dma_dac.dmasize - count;
+       abinfo.fragstotal = s->dma_dac.numfrag;
+       abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;      
+       return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+
+    case SNDCTL_DSP_GETISPACE:
+       if (!(file->f_mode & FMODE_READ))
+           return -EINVAL;
+       abinfo.fragsize = s->dma_adc.fragsize;
+       spin_lock_irqsave(&s->lock, flags);
+       count = s->dma_adc.count;
+       if (!s->dma_adc.stopped)
+           count += (s->dma_adc.fragsize - inw(s->io+IT_AC_CAPCDL));
+       spin_unlock_irqrestore(&s->lock, flags);
+       if (count < 0)
+           count = 0;
+       abinfo.bytes = count;
+       abinfo.fragstotal = s->dma_adc.numfrag;
+       abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
+       return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               
+    case SNDCTL_DSP_NONBLOCK:
+       file->f_flags |= O_NONBLOCK;
+       return 0;
+
+    case SNDCTL_DSP_GETODELAY:
+       if (!(file->f_mode & FMODE_WRITE))
+           return -EINVAL;
+       spin_lock_irqsave(&s->lock, flags);
+       count = s->dma_dac.count;
+       if (!s->dma_dac.stopped)
+           count -= (s->dma_dac.fragsize - inw(s->io+IT_AC_PCDL));
+       spin_unlock_irqrestore(&s->lock, flags);
+       if (count < 0)
+           count = 0;
+       return put_user(count, (int *)arg);
+
+    case SNDCTL_DSP_GETIPTR:
+       if (!(file->f_mode & FMODE_READ))
+           return -EINVAL;
+       spin_lock_irqsave(&s->lock, flags);
+       cinfo.bytes = s->dma_adc.total_bytes;
+       count = s->dma_adc.count;
+       if (!s->dma_adc.stopped) {
+           diff = s->dma_adc.fragsize - inw(s->io+IT_AC_CAPCDL);
+           count += diff;
+           cinfo.bytes += diff;
+           cinfo.ptr = inl(s->io+s->dma_adc.curBufPtr) - s->dma_adc.dmaaddr;
+       } else
+           cinfo.ptr = virt_to_bus(s->dma_adc.nextIn) - s->dma_adc.dmaaddr;
+       if (s->dma_adc.mapped)
+           s->dma_adc.count &= s->dma_adc.fragsize-1;
+       spin_unlock_irqrestore(&s->lock, flags);
+       if (count < 0)
+           count = 0;
+       cinfo.blocks = count >> s->dma_adc.fragshift;
+       return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+
+    case SNDCTL_DSP_GETOPTR:
+       if (!(file->f_mode & FMODE_READ))
+           return -EINVAL;
+       spin_lock_irqsave(&s->lock, flags);
+       cinfo.bytes = s->dma_dac.total_bytes;
+       count = s->dma_dac.count;
+       if (!s->dma_dac.stopped) {
+           diff = s->dma_dac.fragsize - inw(s->io+IT_AC_CAPCDL);
+           count -= diff;
+           cinfo.bytes += diff;
+           cinfo.ptr = inl(s->io+s->dma_dac.curBufPtr) - s->dma_dac.dmaaddr;
+       } else
+           cinfo.ptr = virt_to_bus(s->dma_dac.nextOut) - s->dma_dac.dmaaddr;
+       if (s->dma_dac.mapped)
+           s->dma_dac.count &= s->dma_dac.fragsize-1;
+       spin_unlock_irqrestore(&s->lock, flags);
+       if (count < 0)
+           count = 0;
+       cinfo.blocks = count >> s->dma_dac.fragshift;
+       return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+
+    case SNDCTL_DSP_GETBLKSIZE:
+       if (file->f_mode & FMODE_WRITE)
+           return put_user(s->dma_dac.fragsize, (int *)arg);
+       else
+           return put_user(s->dma_adc.fragsize, (int *)arg);
+
+    case SNDCTL_DSP_SETFRAGMENT:
+       if (get_user(val, (int *)arg))
+           return -EFAULT;
+       if (file->f_mode & FMODE_READ) {
+           stop_adc(s);
+           s->dma_adc.ossfragshift = val & 0xffff;
+           s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
+           if (s->dma_adc.ossfragshift < 4)
+               s->dma_adc.ossfragshift = 4;
+           if (s->dma_adc.ossfragshift > 15)
+               s->dma_adc.ossfragshift = 15;
+           if (s->dma_adc.ossmaxfrags < 4)
+               s->dma_adc.ossmaxfrags = 4;
+           if ((ret = prog_dmabuf_adc(s)))
+               return ret;
+       }
+       if (file->f_mode & FMODE_WRITE) {
+           stop_dac(s);
+           s->dma_dac.ossfragshift = val & 0xffff;
+           s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
+           if (s->dma_dac.ossfragshift < 4)
+               s->dma_dac.ossfragshift = 4;
+           if (s->dma_dac.ossfragshift > 15)
+               s->dma_dac.ossfragshift = 15;
+           if (s->dma_dac.ossmaxfrags < 4)
+               s->dma_dac.ossmaxfrags = 4;
+           if ((ret = prog_dmabuf_dac(s)))
+               return ret;
+       }
+       return 0;
+
+    case SNDCTL_DSP_SUBDIVIDE:
+       if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
+           (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
+           return -EINVAL;
+       if (get_user(val, (int *)arg))
+           return -EFAULT;
+       if (val != 1 && val != 2 && val != 4)
+           return -EINVAL;
+       if (file->f_mode & FMODE_READ) {
+           stop_adc(s);
+           s->dma_adc.subdivision = val;
+           if ((ret = prog_dmabuf_adc(s)))
+               return ret;
+       }
+       if (file->f_mode & FMODE_WRITE) {
+           stop_dac(s);
+           s->dma_dac.subdivision = val;
+           if ((ret = prog_dmabuf_dac(s)))
+               return ret;
+       }
+       return 0;
+
+    case SOUND_PCM_READ_RATE:
+       return put_user((file->f_mode & FMODE_READ) ?
+                       s->adcrate : s->dacrate, (int *)arg);
+
+    case SOUND_PCM_READ_CHANNELS:
+       if (file->f_mode & FMODE_READ)
+           return put_user((s->capcc & CC_SM) ? 2 : 1, (int *)arg);
+       else
+           return put_user((s->pcc & CC_SM) ? 2 : 1, (int *)arg);
+           
+    case SOUND_PCM_READ_BITS:
+       if (file->f_mode & FMODE_READ)
+           return put_user((s->capcc & CC_DF) ? 16 : 8, (int *)arg);
+       else
+           return put_user((s->pcc & CC_DF) ? 16 : 8, (int *)arg);
+
+    case SOUND_PCM_WRITE_FILTER:
+    case SNDCTL_DSP_SETSYNCRO:
+    case SOUND_PCM_READ_FILTER:
+       return -EINVAL;
+    }
+
+    return mixdev_ioctl(&s->codec, cmd, arg);
+}
+
+
+static int it8172_open(struct inode *inode, struct file *file)
+{
+    int minor = MINOR(inode->i_rdev);
+    DECLARE_WAITQUEUE(wait, current);
+    unsigned long flags;
+    struct list_head *list;
+    struct it8172_state *s;
+    int ret;
+    
+    for (list = devs.next; ; list = list->next) {
+       if (list == &devs)
+           return -ENODEV;
+       s = list_entry(list, struct it8172_state, devs);
+       if (!((s->dev_audio ^ minor) & ~0xf))
+           break;
+    }
+    file->private_data = s;
+    /* wait for device to become free */
+    down(&s->open_sem);
+    while (s->open_mode & file->f_mode) {
+       if (file->f_flags & O_NONBLOCK) {
+           up(&s->open_sem);
+           return -EBUSY;
+       }
+       add_wait_queue(&s->open_wait, &wait);
+       __set_current_state(TASK_INTERRUPTIBLE);
+       up(&s->open_sem);
+       schedule();
+       remove_wait_queue(&s->open_wait, &wait);
+       set_current_state(TASK_RUNNING);
+       if (signal_pending(current))
+           return -ERESTARTSYS;
+       down(&s->open_sem);
+    }
+
+    spin_lock_irqsave(&s->lock, flags);
+
+    if (file->f_mode & FMODE_READ) {
+       s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
+           s->dma_adc.subdivision = s->dma_adc.total_bytes = 0;
+       s->capcc &= ~(CC_SM | CC_DF);
+       set_adc_rate(s, 8000);
+       if ((minor & 0xf) == SND_DEV_DSP16)
+           s->capcc |= CC_DF;
+       outw(s->capcc, s->io+IT_AC_CAPCC);
+       if ((ret = prog_dmabuf_adc(s)))
+           return ret;
+    }
+    if (file->f_mode & FMODE_WRITE) {
+       s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
+           s->dma_dac.subdivision = s->dma_dac.total_bytes = 0;
+       s->pcc &= ~(CC_SM | CC_DF);
+       set_dac_rate(s, 8000);
+       if ((minor & 0xf) == SND_DEV_DSP16)
+           s->pcc |= CC_DF;
+       outw(s->pcc, s->io+IT_AC_PCC);
+       if ((ret = prog_dmabuf_dac(s)))
+           return ret;
+    }
+
+    spin_unlock_irqrestore(&s->lock, flags);
+
+    s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
+    up(&s->open_sem);
+    return 0;
+}
+
+static int it8172_release(struct inode *inode, struct file *file)
+{
+    struct it8172_state *s = (struct it8172_state *)file->private_data;
+
+    lock_kernel();
+    if (file->f_mode & FMODE_WRITE)
+       drain_dac(s, file->f_flags & O_NONBLOCK);
+    down(&s->open_sem);
+    if (file->f_mode & FMODE_WRITE) {
+       stop_dac(s);
+       dealloc_dmabuf(s, &s->dma_dac);
+    }
+    if (file->f_mode & FMODE_READ) {
+       stop_adc(s);
+       dealloc_dmabuf(s, &s->dma_adc);
+    }
+    s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
+    up(&s->open_sem);
+    wake_up(&s->open_wait);
+    unlock_kernel();
+    return 0;
+}
+
+static /*const*/ struct file_operations it8172_audio_fops = {
+    owner:     THIS_MODULE,
+    llseek:    it8172_llseek,
+    read:      it8172_read,
+    write:     it8172_write,
+    poll:      it8172_poll,
+    ioctl:     it8172_ioctl,
+    mmap:      it8172_mmap,
+    open:      it8172_open,
+    release:   it8172_release,
+};
+
+
+/* --------------------------------------------------------------------- */
+
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * for debugging purposes, we'll create a proc device that dumps the
+ * CODEC chipstate
+ */
+
+#ifdef IT8172_DEBUG
+static int proc_it8172_dump (char *buf, char **start, off_t fpos,
+                            int length, int *eof, void *data)
+{
+    struct it8172_state *s;
+    int cnt, len = 0;
+
+    if (list_empty(&devs))
+       return 0;
+    s = list_entry(devs.next, struct it8172_state, devs);
+
+    /* print out header */
+    len += sprintf(buf + len, "\n\t\tIT8172 Audio Debug\n\n");
+
+    // print out digital controller state
+    len += sprintf (buf + len, "IT8172 Audio Controller registers\n");
+    len += sprintf (buf + len, "---------------------------------\n");
+    cnt=0;
+    while (cnt < 0x72) {
+       if (cnt == IT_AC_PCB1STA || cnt == IT_AC_PCB2STA ||
+           cnt == IT_AC_CAPB1STA || cnt == IT_AC_CAPB2STA ||
+           cnt == IT_AC_PFDP) {
+           len+= sprintf (buf + len, "reg %02x = %08x\n",
+                          cnt, inl(s->io+cnt));
+           cnt += 4;
+       } else {
+           len+= sprintf (buf + len, "reg %02x = %04x\n",
+                          cnt, inw(s->io+cnt));
+           cnt += 2;
+       }
+    }
+    
+    /* print out CODEC state */
+    len += sprintf (buf + len, "\nAC97 CODEC registers\n");
+    len += sprintf (buf + len, "----------------------\n");
+    for (cnt=0; cnt <= 0x7e; cnt = cnt +2)
+       len+= sprintf (buf + len, "reg %02x = %04x\n",
+                      cnt, rdcodec(&s->codec, cnt));
+
+    if (fpos >=len){
+       *start = buf;
+       *eof =1;
+       return 0;
+    }
+    *start = buf + fpos;
+    if ((len -= fpos) > length)
+       return length;
+    *eof =1;
+    return len;
+
+}
+#endif /* IT8172_DEBUG */
+
+/* --------------------------------------------------------------------- */
+
+/* maximum number of devices; only used for command line params */
+#define NR_DEVICE 5
+
+static int spdif[NR_DEVICE] = { 0, };
+
+static unsigned int devindex = 0;
+
+MODULE_PARM(spdif, "1-" __MODULE_STRING(NR_DEVICE) "i");
+MODULE_PARM_DESC(spdif, "if 1 the S/PDIF digital output is enabled");
+
+MODULE_AUTHOR("Monta Vista Software, stevel@mvista.com");
+MODULE_DESCRIPTION("IT8172 AudioPCI97 Driver");
+
+/* --------------------------------------------------------------------- */
+
+static int __devinit it8172_probe(struct pci_dev *pcidev,
+                                 const struct pci_device_id *pciid)
+{
+    struct it8172_state *s;
+    int i, val;
+    unsigned short pcisr, vol;
+    unsigned char legacy, imc;
+    char proc_str[80];
+    
+    if (pcidev->irq == 0) 
+       return -1;
+
+    if (!(s = kmalloc(sizeof(struct it8172_state), GFP_KERNEL))) {
+       printk(KERN_ERR PFX "alloc of device struct failed\n");
+       return -1;
+    }
+       
+    memset(s, 0, sizeof(struct it8172_state));
+    init_waitqueue_head(&s->dma_adc.wait);
+    init_waitqueue_head(&s->dma_dac.wait);
+    init_waitqueue_head(&s->open_wait);
+    init_MUTEX(&s->open_sem);
+    spin_lock_init(&s->lock);
+    s->dev = pcidev;
+    s->io = pci_resource_start(pcidev, 0);
+    s->irq = pcidev->irq;
+    s->vendor = pcidev->vendor;
+    s->device = pcidev->device;
+    pci_read_config_byte(pcidev, PCI_REVISION_ID, &s->rev);
+    s->codec.private_data = s;
+    s->codec.id = 0;
+    s->codec.codec_read = rdcodec;
+    s->codec.codec_write = wrcodec;
+    s->codec.codec_wait = waitcodec;
+
+    if (!request_region(s->io, pci_resource_len(pcidev,0),
+                       IT8172_MODULE_NAME)) {
+       printk(KERN_ERR PFX "io ports %#lx->%#lx in use\n",
+               s->io, s->io + pci_resource_len(pcidev,0)-1);
+       goto err_region;
+    }
+    if (request_irq(s->irq, it8172_interrupt, SA_INTERRUPT,
+                   IT8172_MODULE_NAME, s)) {
+       printk(KERN_ERR PFX "irq %u in use\n", s->irq);
+       goto err_irq;
+    }
+
+    printk(KERN_INFO PFX "IO at %#lx, IRQ %d\n", s->io, s->irq);
+
+    /* register devices */
+    if ((s->dev_audio = register_sound_dsp(&it8172_audio_fops, -1)) < 0)
+       goto err_dev1;
+    if ((s->codec.dev_mixer =
+        register_sound_mixer(&it8172_mixer_fops, -1)) < 0)
+       goto err_dev2;
+
+#ifdef IT8172_DEBUG
+    /* intialize the debug proc device */
+    s->ps = create_proc_read_entry(IT8172_MODULE_NAME, 0, NULL,
+                                  proc_it8172_dump, NULL);
+#endif /* IT8172_DEBUG */
+       
+    /*
+     * Reset the Audio device using the IT8172 PCI Reset register. This
+     * creates an audible double click on a speaker connected to Line-out.
+     */
+    IT_IO_READ16(IT_PM_PCISR, pcisr);
+    pcisr |= IT_PM_PCISR_ACSR;
+    IT_IO_WRITE16(IT_PM_PCISR, pcisr);
+    /* wait up to 100msec for reset to complete */
+    for (i=0; pcisr & IT_PM_PCISR_ACSR; i++) {
+       it8172_delay(10);
+       if (i == 10)
+           break;
+       IT_IO_READ16(IT_PM_PCISR, pcisr);
+    }
+    if (i == 10) {
+       printk(KERN_ERR PFX "chip reset timeout!\n");
+       goto err_dev3;
+    }
+    
+    /* enable pci io and bus mastering */
+    if (pci_enable_device(pcidev))
+       goto err_dev3;
+    pci_set_master(pcidev);
+
+    /* get out of legacy mode */
+    pci_read_config_byte (pcidev, 0x40, &legacy);
+    pci_write_config_byte (pcidev, 0x40, legacy & ~1);
+    
+    s->spdif_volume = -1;
+    /* check to see if s/pdif mode is being requested */
+    if (spdif[devindex]) {
+       printk(KERN_INFO PFX "enabling S/PDIF output\n");
+       s->spdif_volume = 0;
+       outb(GC_SOE, s->io+IT_AC_GC);
+    } else {
+       printk(KERN_INFO PFX "disabling S/PDIF output\n");
+       outb(0, s->io+IT_AC_GC);
+    }
+    
+    /* cold reset the AC97 */
+    outw(CODECC_CR, s->io+IT_AC_CODECC);
+    udelay(1000);
+    outw(0, s->io+IT_AC_CODECC);
+    /* need to delay around 500msec(bleech) to give
+       some CODECs enough time to wakeup */
+    it8172_delay(500);
+    
+    /* AC97 warm reset to start the bitclk */
+    outw(CODECC_WR, s->io+IT_AC_CODECC);
+    udelay(1000);
+    outw(0, s->io+IT_AC_CODECC);
+    
+    /* codec init */
+    if (!ac97_probe_codec(&s->codec))
+       goto err_dev3;
+
+    /* Enable Volume button interrupts */
+    imc = inb(s->io+IT_AC_IMC);
+    outb(imc & ~IMC_VCIM, s->io+IT_AC_IMC);
+
+    /* Un-mute PCM and FM out on the controller */
+    vol = inw(s->io+IT_AC_PCMOV);
+    outw(vol & ~PCMOV_PCMOM, s->io+IT_AC_PCMOV);
+    vol = inw(s->io+IT_AC_FMOV);
+    outw(vol & ~FMOV_FMOM, s->io+IT_AC_FMOV);
+
+    /* set channel defaults to 8-bit, mono, 8 Khz */
+    s->pcc = 0;
+    s->capcc = 0;
+    set_dac_rate(s, 8000);
+    set_adc_rate(s, 8000);
+
+    /* set mic to be the recording source */
+    val = SOUND_MASK_MIC;
+    mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
+
+    /* mute master and PCM when in S/PDIF mode */
+    if (s->spdif_volume != -1) {
+       val = 0x0000;
+       mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_VOLUME,
+                    (unsigned long)&val);
+       mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_PCM,
+                    (unsigned long)&val);
+    }
+    
+#ifdef IT8172_DEBUG
+    sprintf(proc_str, "driver/%s/%d/ac97", IT8172_MODULE_NAME, s->codec.id);
+    s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
+                                        ac97_read_proc, &s->codec);
+#endif
+    
+    /* store it in the driver field */
+    pci_set_drvdata(pcidev, s);
+    pcidev->dma_mask = 0xffffffff;
+    /* put it into driver list */
+    list_add_tail(&s->devs, &devs);
+    /* increment devindex */
+    if (devindex < NR_DEVICE-1)
+       devindex++;
+    return 0;
+
+ err_dev3:
+    unregister_sound_mixer(s->codec.dev_mixer);
+ err_dev2:
+    unregister_sound_dsp(s->dev_audio);
+ err_dev1:
+    printk(KERN_ERR PFX "cannot register misc device\n");
+    free_irq(s->irq, s);
+ err_irq:
+    release_region(s->io, pci_resource_len(pcidev,0));
+ err_region:
+    kfree(s);
+    return -1;
+}
+
+static void __devinit it8172_remove(struct pci_dev *dev)
+{
+    struct it8172_state *s = pci_get_drvdata(dev);
+
+    if (!s)
+       return;
+    list_del(&s->devs);
+#ifdef IT8172_DEBUG
+    if (s->ps)
+       remove_proc_entry(IT8172_MODULE_NAME, NULL);
+#endif /* IT8172_DEBUG */
+    synchronize_irq();
+    free_irq(s->irq, s);
+    release_region(s->io, pci_resource_len(dev,0));
+    unregister_sound_dsp(s->dev_audio);
+    unregister_sound_mixer(s->codec.dev_mixer);
+    kfree(s);
+    pci_set_drvdata(dev, NULL);
+}
+
+
+
+static struct pci_device_id id_table[] __devinitdata = {
+    { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_IT8172G_AUDIO, PCI_ANY_ID,
+      PCI_ANY_ID, 0, 0 },
+    { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, id_table);
+
+static struct pci_driver it8172_driver = {
+    name: IT8172_MODULE_NAME,
+    id_table: id_table,
+    probe: it8172_probe,
+    remove: it8172_remove
+};
+
+static int __init init_it8172(void)
+{
+    if (!pci_present())   /* No PCI bus in this machine! */
+       return -ENODEV;
+    printk("version v0.26 time " __TIME__ " " __DATE__ "\n");
+    return pci_module_init(&it8172_driver);
+}
+
+static void __exit cleanup_it8172(void)
+{
+    printk(KERN_INFO PFX "unloading\n");
+    pci_unregister_driver(&it8172_driver);
+}
+
+module_init(init_it8172);
+module_exit(cleanup_it8172);
+
index 3c7f956512017bad892c5e4c294fd5ccb663809e..91150cd96a0e1de9da858710bcb8e062c8768973 100644 (file)
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * $Id: msnd_pinnacle.c,v 1.75 1999/03/21 16:50:09 andrewtv Exp $
+ * $Id: msnd_pinnacle.c,v 1.8 2000/12/30 00:33:21 sycamore Exp $
+ *
+ * 12-3-2000  Modified IO port validation  Steve Sycamore
+ *
+ *
+ * $$$: msnd_pinnacle.c,v 1.75 1999/03/21 16:50:09 andrewtv $$$ $
  *
  ********************************************************************/
 
@@ -1703,6 +1708,7 @@ static int __init msnd_init(void)
        if (io == -1 || irq == -1 || mem == -1)
                printk(KERN_WARNING LOGNAME ": io, irq and mem must be set\n");
 
+#ifdef MSND_CLASSIC
        if (io == -1 ||
            !(io == 0x290 ||
              io == 0x260 ||
@@ -1715,6 +1721,15 @@ static int __init msnd_init(void)
                printk(KERN_ERR LOGNAME ": \"io\" - DSP I/O base must be set to 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x290, or 0x3E0\n");
                return -EINVAL;
        }
+#else
+       if (io == -1 ||
+               io < 0x100 ||
+               io > 0x3e0 ||
+               (io % 0x10) != 0) {
+                       printk(KERN_ERR LOGNAME ": \"io\" - DSP I/O base must within the range 0x100 to 0x3E0 and must be evenly divisible by 0x10\n");
+                       return -EINVAL;
+       }
+#endif /* MSND_CLASSIC */
 
        if (irq == -1 ||
            !(irq == 5 ||
diff --git a/drivers/sound/nec_vrc5477.c b/drivers/sound/nec_vrc5477.c
new file mode 100644 (file)
index 0000000..8a81f5f
--- /dev/null
@@ -0,0 +1,2044 @@
+/***********************************************************************
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * drivers/sound/nec_vrc5477.c
+ *     AC97 sound dirver for NEC Vrc5477 chip (an integrated, 
+ *     multi-function controller chip for MIPS CPUs)
+ *
+ * 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 code is derived from ite8172.c, which is written by Steve Longerbeam.
+ *
+ * Features:
+ *   Currently we only support the following capabilities:
+ *     . mono output to PCM L/R (line out).
+ *     . stereo output to PCM L/R (line out).
+ *     . mono input from PCM L (line in).
+ *     . stereo output from PCM (line in).
+ *     . sampling rate at 48k or variable sampling rate 
+ *     . support /dev/dsp, /dev/mixer devices, standard OSS devices.
+ *     . only support 16-bit PCM format (hardware limit, no software
+ *       translation) 
+ *     . support duplex, but no trigger or realtime.
+ *     
+ *   Specifically the following are not supported:
+ *     . app-set frag size.
+ *     . mmap'ed buffer access
+ */
+
+/* 
+ * Original comments from ite8172.c file.
+ */
+
+/*
+ *
+ * Notes:
+ *
+ *  1. Much of the OSS buffer allocation, ioctl's, and mmap'ing are
+ *     taken, slightly modified or not at all, from the ES1371 driver,
+ *     so refer to the credits in es1371.c for those. The rest of the
+ *     code (probe, open, read, write, the ISR, etc.) is new.
+ *  2. The following support is untested:
+ *      * Memory mapping the audio buffers, and the ioctl controls that go
+ *        with it.
+ *      * S/PDIF output.
+ *  3. The following is not supported:
+ *      * I2S input.
+ *      * legacy audio mode.
+ *  4. Support for volume button interrupts is implemented but doesn't
+ *     work yet.
+ *
+ *  Revision history
+ *    02.08.2001  0.1   Initial release
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/sound.h>
+#include <linux/malloc.h>
+#include <linux/soundcard.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/bitops.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
+#include <linux/ac97_codec.h>
+#include <linux/wrapper.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/uaccess.h>
+#include <asm/hardirq.h>
+
+#include <asm/ddb5xxx/debug.h>
+
+#undef VRC5477_AC97_VERBOSE_DEBUG
+
+/* one must turn on CONFIG_LL_DEBUG before VERBOSE_DEBUG is turned */
+#if defined(VRC5477_AC97_VERBOSE_DEBUG)
+#if !defined(CONFIG_LL_DEBUG)
+#error "You must turn CONFIG_LL_DEBUG"
+#endif
+#endif
+
+#if defined(VRC5477_AC97_VERBOSE_DEBUG)
+static u16 inTicket=0;                 /* check sync between intr & write */
+static u16 outTicket=0;
+#endif
+
+/* --------------------------------------------------------------------- */
+
+#undef OSS_DOCUMENTED_MIXER_SEMANTICS
+
+static const unsigned sample_shift[] = { 0, 1, 1, 2 };
+
+#define         VRC5477_INT_CLR         0x0
+#define         VRC5477_INT_STATUS     0x0
+#define         VRC5477_CODEC_WR        0x4
+#define         VRC5477_CODEC_RD        0x8
+#define         VRC5477_CTRL            0x18
+#define         VRC5477_ACLINK_CTRL     0x1c
+#define         VRC5477_INT_MASK        0x24
+
+#define                VRC5477_DAC1_CTRL       0x30
+#define                VRC5477_DAC1L           0x34
+#define                VRC5477_DAC1_BADDR      0x38
+#define                VRC5477_DAC2_CTRL       0x3c
+#define                VRC5477_DAC2L           0x40
+#define                VRC5477_DAC2_BADDR      0x44
+#define                VRC5477_DAC3_CTRL       0x48
+#define                VRC5477_DAC3L           0x4c
+#define                VRC5477_DAC3_BADDR      0x50
+
+#define                VRC5477_ADC1_CTRL       0x54
+#define                VRC5477_ADC1L           0x58
+#define                VRC5477_ADC1_BADDR      0x5c
+#define                VRC5477_ADC2_CTRL       0x60
+#define                VRC5477_ADC2L           0x64
+#define                VRC5477_ADC2_BADDR      0x68
+#define                VRC5477_ADC3_CTRL       0x6c
+#define                VRC5477_ADC3L           0x70
+#define                VRC5477_ADC3_BADDR      0x74
+
+#define                VRC5477_CODEC_WR_RWC    (1 << 23)
+
+#define                VRC5477_CODEC_RD_RRDYA  (1 << 31)
+#define                VRC5477_CODEC_RD_RRDYD  (1 << 30)
+
+#define                VRC5477_ACLINK_CTRL_RST_ON      (1 << 15)
+#define                VRC5477_ACLINK_CTRL_RST_TIME    0x7f
+#define                VRC5477_ACLINK_CTRL_SYNC_ON     (1 << 30)
+#define                VRC5477_ACLINK_CTRL_CK_STOP_ON  (1 << 31)
+
+#define                VRC5477_CTRL_DAC2ENB            (1 << 15) 
+#define                VRC5477_CTRL_ADC2ENB            (1 << 14) 
+#define                VRC5477_CTRL_DAC1ENB            (1 << 13) 
+#define                VRC5477_CTRL_ADC1ENB            (1 << 12) 
+
+#define                VRC5477_INT_MASK_NMASK          (1 << 31) 
+#define                VRC5477_INT_MASK_DAC1END        (1 << 5) 
+#define                VRC5477_INT_MASK_DAC2END        (1 << 4) 
+#define                VRC5477_INT_MASK_DAC3END        (1 << 3) 
+#define                VRC5477_INT_MASK_ADC1END        (1 << 2) 
+#define                VRC5477_INT_MASK_ADC2END        (1 << 1) 
+#define                VRC5477_INT_MASK_ADC3END        (1 << 0) 
+
+#define                VRC5477_DMA_ACTIVATION          (1 << 31)
+#define                VRC5477_DMA_WIP                 (1 << 30)
+
+
+#define VRC5477_AC97_MODULE_NAME "NEC_Vrc5477_audio"
+#define PFX VRC5477_AC97_MODULE_NAME ": "
+
+/* --------------------------------------------------------------------- */
+
+struct vrc5477_ac97_state {
+       /* list of vrc5477_ac97 devices */
+       struct list_head devs;
+
+       /* the corresponding pci_dev structure */
+       struct pci_dev *dev;
+
+       /* soundcore stuff */
+       int dev_audio;
+
+       /* hardware resources */
+       unsigned long io;
+       unsigned int irq;
+
+#ifdef CONFIG_LL_DEBUG
+       /* debug /proc entry */
+       struct proc_dir_entry *ps;
+       struct proc_dir_entry *ac97_ps;
+#endif /* CONFIG_LL_DEBUG */
+
+       struct ac97_codec codec;
+
+       unsigned dacChannels, adcChannels;
+       unsigned short dacRate, adcRate;
+
+       spinlock_t lock;
+       struct semaphore open_sem;
+       mode_t open_mode;
+       wait_queue_head_t open_wait;
+
+       struct dmabuf {
+               void *lbuf, *rbuf;
+               dma_addr_t lbufDma, rbufDma;
+               unsigned bufOrder;
+               unsigned numFrag;
+               unsigned fragShift;
+               unsigned fragSize;      /* redundant */
+               unsigned fragTotalSize; /* = numFrag * fragSize(real)  */
+               unsigned nextIn;
+               unsigned nextOut;
+               int count;
+               unsigned error; /* over/underrun */
+               wait_queue_head_t wait;
+               /* OSS stuff */
+               unsigned stopped:1;
+               unsigned ready:1;
+       } dma_dac, dma_adc;
+
+       #define WORK_BUF_SIZE   2048
+       struct {
+               u16 lchannel;
+               u16 rchannel;
+       } workBuf[WORK_BUF_SIZE/4];
+};
+
+/* --------------------------------------------------------------------- */
+
+static LIST_HEAD(devs);
+
+/* --------------------------------------------------------------------- */
+
+extern inline unsigned ld2(unsigned int x)
+{
+    unsigned r = 0;
+       
+    if (x >= 0x10000) {
+       x >>= 16;
+       r += 16;
+    }
+    if (x >= 0x100) {
+       x >>= 8;
+       r += 8;
+    }
+    if (x >= 0x10) {
+       x >>= 4;
+       r += 4;
+    }
+    if (x >= 4) {
+       x >>= 2;
+       r += 2;
+    }
+    if (x >= 2)
+       r++;
+    return r;
+}
+
+/* --------------------------------------------------------------------- */
+
+static u16 rdcodec(struct ac97_codec *codec, u8 addr)
+{
+       struct vrc5477_ac97_state *s = 
+               (struct vrc5477_ac97_state *)codec->private_data;
+       unsigned long flags;
+       u32 result;
+
+       spin_lock_irqsave(&s->lock, flags);
+
+       /* wait until we can access codec registers */
+       while (inl(s->io + VRC5477_CODEC_WR) & 0x80000000);
+
+       /* write the address and "read" command to codec */
+       addr = addr & 0x7f;
+       outl((addr << 16) | VRC5477_CODEC_WR_RWC, s->io + VRC5477_CODEC_WR);
+
+       /* get the return result */
+       udelay(100); /* workaround hardware bug */
+       while ( (result = inl(s->io + VRC5477_CODEC_RD)) & 
+                (VRC5477_CODEC_RD_RRDYA | VRC5477_CODEC_RD_RRDYD) ) {
+               /* we get either addr or data, or both */
+               if (result & VRC5477_CODEC_RD_RRDYA) {
+                       MIPS_ASSERT(addr == ((result >> 16) & 0x7f) );
+               }
+               if (result & VRC5477_CODEC_RD_RRDYD) {
+                       break;
+               }
+       }
+
+       spin_unlock_irqrestore(&s->lock, flags);
+
+       return result & 0xffff;;
+}
+
+
+static void wrcodec(struct ac97_codec *codec, u8 addr, u16 data)
+{
+       struct vrc5477_ac97_state *s = 
+               (struct vrc5477_ac97_state *)codec->private_data;
+       unsigned long flags;
+
+       spin_lock_irqsave(&s->lock, flags);
+
+       /* wait until we can access codec registers */
+       while (inl(s->io + VRC5477_CODEC_WR) & 0x80000000);
+
+       /* write the address and value to codec */
+       outl((addr << 16) | data, s->io + VRC5477_CODEC_WR);
+
+       spin_unlock_irqrestore(&s->lock, flags);
+}
+
+
+static void waitcodec(struct ac97_codec *codec)
+{
+       struct vrc5477_ac97_state *s = 
+               (struct vrc5477_ac97_state *)codec->private_data;
+
+       /* wait until we can access codec registers */
+       while (inl(s->io + VRC5477_CODEC_WR) & 0x80000000);
+}
+
+
+/* --------------------------------------------------------------------- */
+
+static void vrc5477_ac97_delay(int msec)
+{
+       unsigned long tmo;
+       signed long tmo2;
+
+       if (in_interrupt())
+               return;
+    
+       tmo = jiffies + (msec*HZ)/1000;
+       for (;;) {
+               tmo2 = tmo - jiffies;
+               if (tmo2 <= 0)
+                       break;
+               schedule_timeout(tmo2);
+       }
+}
+
+
+static void set_adc_rate(struct vrc5477_ac97_state *s, unsigned rate)
+{
+       wrcodec(&s->codec, AC97_PCM_LR_ADC_RATE, rate);
+       s->adcRate = rate;
+}
+
+
+static void set_dac_rate(struct vrc5477_ac97_state *s, unsigned rate)
+{
+       wrcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE, rate);
+       s->dacRate = rate;
+}
+
+
+/* --------------------------------------------------------------------- */
+
+extern inline void 
+stop_dac(struct vrc5477_ac97_state *s)
+{
+       struct dmabuf* db = &s->dma_dac;
+       unsigned long flags;
+       u32 temp;
+    
+       spin_lock_irqsave(&s->lock, flags);
+
+       if (db->stopped) {
+               spin_unlock_irqrestore(&s->lock, flags);
+               return;
+       }
+
+       /* deactivate the dma */
+       outl(0, s->io + VRC5477_DAC1_CTRL);
+       outl(0, s->io + VRC5477_DAC2_CTRL);
+
+       /* wait for DAM completely stop */
+       while (inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP);
+       while (inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP);
+
+       /* disable dac slots in aclink */
+       temp = inl(s->io + VRC5477_CTRL);
+       temp &= ~ (VRC5477_CTRL_DAC1ENB | VRC5477_CTRL_DAC2ENB);
+       outl (temp, s->io + VRC5477_CTRL);
+
+       /* disable interrupts */
+       temp = inl(s->io + VRC5477_INT_MASK);
+       temp &= ~ (VRC5477_INT_MASK_DAC1END | VRC5477_INT_MASK_DAC2END); 
+       outl (temp, s->io + VRC5477_INT_MASK);
+
+       /* clear pending ones */
+       outl(VRC5477_INT_MASK_DAC1END | VRC5477_INT_MASK_DAC2END, 
+            s->io +  VRC5477_INT_CLR);
+    
+       db->stopped = 1;
+    
+       spin_unlock_irqrestore(&s->lock, flags);
+}      
+
+static void start_dac(struct vrc5477_ac97_state *s)
+{
+       struct dmabuf* db = &s->dma_dac;
+       unsigned long flags;
+       u32 dmaLength;
+       u32 temp;
+
+       spin_lock_irqsave(&s->lock, flags);
+
+       if (!db->stopped) {
+               spin_unlock_irqrestore(&s->lock, flags);
+               return;
+       }
+
+       /* we should have some data to do the DMA trasnfer */
+       MIPS_ASSERT(db->count >= db->fragSize);
+
+       /* clear pending fales interrupts */
+       outl(VRC5477_INT_MASK_DAC1END | VRC5477_INT_MASK_DAC2END, 
+            s->io +  VRC5477_INT_CLR);
+
+       /* enable interrupts */
+       temp = inl(s->io + VRC5477_INT_MASK);
+       temp |= VRC5477_INT_MASK_DAC1END | VRC5477_INT_MASK_DAC2END;
+       outl(temp, s->io +  VRC5477_INT_MASK);
+
+       /* setup dma base addr */
+       outl(db->lbufDma + db->nextOut, s->io + VRC5477_DAC1_BADDR);
+       if (s->dacChannels == 1) {
+               outl(db->lbufDma + db->nextOut, s->io + VRC5477_DAC2_BADDR);
+       } else {
+               outl(db->rbufDma + db->nextOut, s->io + VRC5477_DAC2_BADDR);
+       }
+
+       /* set dma length, in the unit of 0x10 bytes */
+       dmaLength = db->fragSize >> 4;
+       outl(dmaLength, s->io + VRC5477_DAC1L);
+       outl(dmaLength, s->io + VRC5477_DAC2L);
+
+       /* activate dma */
+       outl(VRC5477_DMA_ACTIVATION, s->io + VRC5477_DAC1_CTRL);
+       outl(VRC5477_DMA_ACTIVATION, s->io + VRC5477_DAC2_CTRL);
+
+       /* enable dac slots - we should hear the music now! */
+       temp = inl(s->io + VRC5477_CTRL);
+       temp |= (VRC5477_CTRL_DAC1ENB | VRC5477_CTRL_DAC2ENB);
+       outl (temp, s->io + VRC5477_CTRL);
+
+       /* it is time to setup next dma transfer */
+       MIPS_ASSERT(inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP);
+       MIPS_ASSERT(inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP);
+
+       temp = db->nextOut + db->fragSize;
+       if (temp >= db->fragTotalSize) {
+               MIPS_ASSERT(temp == db->fragTotalSize);
+               temp = 0;
+       }
+
+       outl(db->lbufDma + temp, s->io + VRC5477_DAC1_BADDR);
+       if (s->dacChannels == 1) {
+               outl(db->lbufDma + temp, s->io + VRC5477_DAC2_BADDR);
+       } else {
+               outl(db->rbufDma + temp, s->io + VRC5477_DAC2_BADDR);
+       }
+
+       db->stopped = 0;
+
+#if defined(VRC5477_AC97_VERBOSE_DEBUG)
+       outTicket = *(u16*)(db->lbuf+db->nextOut);
+       if (db->count > db->fragSize) {
+               MIPS_ASSERT((u16)(outTicket+1) == *(u16*)(db->lbuf+temp));
+       }
+#endif
+
+       spin_unlock_irqrestore(&s->lock, flags);
+}      
+
+extern inline void stop_adc(struct vrc5477_ac97_state *s)
+{
+       struct dmabuf* db = &s->dma_adc;
+       unsigned long flags;
+       u32 temp;
+    
+       spin_lock_irqsave(&s->lock, flags);
+
+       if (db->stopped) {
+               spin_unlock_irqrestore(&s->lock, flags);
+               return;
+       }
+
+       /* deactivate the dma */
+       outl(0, s->io + VRC5477_ADC1_CTRL);
+       outl(0, s->io + VRC5477_ADC2_CTRL);
+
+       /* disable adc slots in aclink */
+       temp = inl(s->io + VRC5477_CTRL);
+       temp &= ~ (VRC5477_CTRL_ADC1ENB | VRC5477_CTRL_ADC2ENB);
+       outl (temp, s->io + VRC5477_CTRL);
+
+       /* disable interrupts */
+        temp = inl(s->io + VRC5477_INT_MASK);
+        temp &= ~ (VRC5477_INT_MASK_ADC1END | VRC5477_INT_MASK_ADC2END); 
+        outl (temp, s->io + VRC5477_INT_MASK);
+
+       /* clear pending ones */
+       outl(VRC5477_INT_MASK_ADC1END | VRC5477_INT_MASK_ADC2END, 
+            s->io +  VRC5477_INT_CLR);
+    
+       db->stopped = 1;
+
+       spin_unlock_irqrestore(&s->lock, flags);
+}      
+
+static void start_adc(struct vrc5477_ac97_state *s)
+{
+       struct dmabuf* db = &s->dma_adc;
+       unsigned long flags;
+       u32 dmaLength;
+       u32 temp;
+
+       spin_lock_irqsave(&s->lock, flags);
+
+       if (!db->stopped) {
+               spin_unlock_irqrestore(&s->lock, flags);
+               return;
+       }
+
+       /* we should at least have some free space in the buffer */
+       MIPS_ASSERT(db->count < db->fragTotalSize - db->fragSize * 2);
+
+       /* clear pending ones */
+       outl(VRC5477_INT_MASK_ADC1END | VRC5477_INT_MASK_ADC2END, 
+            s->io +  VRC5477_INT_CLR);
+
+        /* enable interrupts */
+        temp = inl(s->io + VRC5477_INT_MASK);
+        temp |= VRC5477_INT_MASK_ADC1END | VRC5477_INT_MASK_ADC2END;
+        outl(temp, s->io +  VRC5477_INT_MASK);
+
+       /* setup dma base addr */
+       outl(db->lbufDma + db->nextIn, s->io + VRC5477_ADC1_BADDR);
+       outl(db->rbufDma + db->nextIn, s->io + VRC5477_ADC2_BADDR);
+
+       /* setup dma length */
+       dmaLength = db->fragSize >> 4;
+       outl(dmaLength, s->io + VRC5477_ADC1L);
+       outl(dmaLength, s->io + VRC5477_ADC2L);
+
+       /* activate dma */
+       outl(VRC5477_DMA_ACTIVATION, s->io + VRC5477_ADC1_CTRL);
+       outl(VRC5477_DMA_ACTIVATION, s->io + VRC5477_ADC2_CTRL);
+
+       /* enable adc slots */
+       temp = inl(s->io + VRC5477_CTRL);
+       temp |= (VRC5477_CTRL_ADC1ENB | VRC5477_CTRL_ADC2ENB);
+       outl (temp, s->io + VRC5477_CTRL);
+
+       /* it is time to setup next dma transfer */
+       temp = db->nextIn + db->fragSize;
+       if (temp >= db->fragTotalSize) {
+               MIPS_ASSERT(temp == db->fragTotalSize);
+               temp = 0;
+       }
+       outl(db->lbufDma + temp, s->io + VRC5477_ADC1_BADDR);
+       outl(db->rbufDma + temp, s->io + VRC5477_ADC2_BADDR);
+
+       db->stopped = 0;
+
+       spin_unlock_irqrestore(&s->lock, flags);
+}      
+
+/* --------------------------------------------------------------------- */
+
+#define DMABUF_DEFAULTORDER (16-PAGE_SHIFT)
+#define DMABUF_MINORDER 1
+
+extern inline void dealloc_dmabuf(struct vrc5477_ac97_state *s, 
+                                 struct dmabuf *db)
+{
+       if (db->lbuf) {
+               MIPS_ASSERT(db->rbuf);
+               pci_free_consistent(s->dev, PAGE_SIZE << db->bufOrder,
+                                   db->lbuf, db->lbufDma);
+               pci_free_consistent(s->dev, PAGE_SIZE << db->bufOrder,
+                                   db->rbuf, db->rbufDma);
+               db->lbuf = db->rbuf = NULL;
+       }
+       db->nextIn = db->nextOut = 0;
+       db->ready = 0;
+}
+
+static int prog_dmabuf(struct vrc5477_ac97_state *s, 
+                      struct dmabuf *db,
+                      unsigned rate)
+{
+       int order;
+       unsigned bufsize;
+
+       if (!db->lbuf) {
+               MIPS_ASSERT(!db->rbuf);
+
+               db->ready = 0;
+               for (order = DMABUF_DEFAULTORDER; 
+                    order >= DMABUF_MINORDER; 
+                    order--) {
+                       db->lbuf = pci_alloc_consistent(s->dev,
+                                                       PAGE_SIZE << order,
+                                                       &db->lbufDma);
+                       db->rbuf = pci_alloc_consistent(s->dev,
+                                                       PAGE_SIZE << order,
+                                                       &db->rbufDma);
+                       if (db->lbuf && db->rbuf) break;
+                       if (db->lbuf) {
+                           MIPS_ASSERT(!db->rbuf);
+                           pci_free_consistent(s->dev, 
+                                               PAGE_SIZE << order,
+                                               db->lbuf,
+                                               db->lbufDma);
+                       }
+               }
+               if (!db->lbuf) {
+                       MIPS_ASSERT(!db->rbuf);
+                       return -ENOMEM;
+               }
+
+               db->bufOrder = order;
+       }
+
+       db->count = 0;
+       db->nextIn = db->nextOut = 0;
+    
+       bufsize = PAGE_SIZE << db->bufOrder;
+       db->fragShift = ld2(rate * 2 / 100);
+       if (db->fragShift < 4) db->fragShift = 4;
+
+       db->numFrag = bufsize >> db->fragShift;
+       while (db->numFrag < 4 && db->fragShift > 4) {
+               db->fragShift--;
+               db->numFrag = bufsize >> db->fragShift;
+       }
+       db->fragSize = 1 << db->fragShift;
+       db->fragTotalSize = db->numFrag << db->fragShift;
+       memset(db->lbuf, 0, db->fragTotalSize);
+       memset(db->rbuf, 0, db->fragTotalSize);
+    
+       db->ready = 1;
+
+       return 0;
+}
+
+extern inline int prog_dmabuf_adc(struct vrc5477_ac97_state *s)
+{
+    stop_adc(s);
+    return prog_dmabuf(s, &s->dma_adc, s->adcRate);
+}
+
+extern inline int prog_dmabuf_dac(struct vrc5477_ac97_state *s)
+{
+    stop_dac(s);
+    return prog_dmabuf(s, &s->dma_dac, s->dacRate);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* hold spinlock for the following! */
+
+static inline void vrc5477_ac97_adc_interrupt(struct vrc5477_ac97_state *s)
+{
+       struct dmabuf* adc = &s->dma_adc;
+       unsigned temp;
+
+       /* we need two frags avaiable because one is already being used
+        * and the other will be used when next interrupt happens.
+        */
+       if (adc->count >= adc->fragTotalSize - adc->fragSize) {
+               stop_adc(s);
+               adc->error++;
+               printk(KERN_INFO PFX "adc overrun\n");
+               return;
+       }
+
+       /* set the base addr for next DMA transfer */
+       temp = adc->nextIn + 2*adc->fragSize;
+       if (temp >= adc->fragTotalSize) {
+               MIPS_ASSERT( (temp == adc->fragTotalSize) ||
+                             (temp == adc->fragTotalSize + adc->fragSize) );
+               temp -= adc->fragTotalSize;
+       }
+       outl(adc->lbufDma + temp, s->io + VRC5477_ADC1_BADDR);
+       outl(adc->rbufDma + temp, s->io + VRC5477_ADC2_BADDR);
+
+       /* adjust nextIn */
+       adc->nextIn += adc->fragSize;
+       if (adc->nextIn >= adc->fragTotalSize) {
+               MIPS_ASSERT(adc->nextIn == adc->fragTotalSize);
+               adc->nextIn = 0;
+       }
+
+       /* adjust count */
+       adc->count += adc->fragSize;
+
+       /* wake up anybody listening */
+       if (waitqueue_active(&adc->wait)) {
+               wake_up_interruptible(&adc->wait);
+       }       
+}
+
+static inline void vrc5477_ac97_dac_interrupt(struct vrc5477_ac97_state *s)
+{
+       struct dmabuf* dac = &s->dma_dac;
+       unsigned temp;
+
+       /* next DMA transfer should already started */
+       MIPS_ASSERT(inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP);
+       MIPS_ASSERT(inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP);
+
+       /* let us set for next next DMA transfer */
+       temp = dac->nextOut + dac->fragSize*2;
+       if (temp >= dac->fragTotalSize) {
+               MIPS_ASSERT( (temp == dac->fragTotalSize) || 
+                             (temp == dac->fragTotalSize + dac->fragSize) );
+               temp -= dac->fragTotalSize;
+       }
+       outl(dac->lbufDma + temp, s->io + VRC5477_DAC1_BADDR);
+       if (s->dacChannels == 1) {
+               outl(dac->lbufDma + temp, s->io + VRC5477_DAC2_BADDR);
+       } else {
+               outl(dac->rbufDma + temp, s->io + VRC5477_DAC2_BADDR);
+       }
+
+#if defined(VRC5477_AC97_VERBOSE_DEBUG)
+       if (*(u16*)(dac->lbuf +  dac->nextOut) != outTicket) {
+               printk("assert fail: - %d vs %d\n", 
+                       *(u16*)(dac->lbuf +  dac->nextOut),
+                        outTicket);
+                MIPS_ASSERT(1 == 0);
+       }
+#endif
+
+       /* adjust nextOut pointer */
+       dac->nextOut += dac->fragSize;
+       if (dac->nextOut >= dac->fragTotalSize) {
+               MIPS_ASSERT(dac->nextOut == dac->fragTotalSize);
+               dac->nextOut = 0;
+       }
+
+       /* adjust count */
+       dac->count -= dac->fragSize;
+       if (dac->count <=0 ) {
+               MIPS_ASSERT(dac->count == 0);
+               MIPS_ASSERT(dac->nextIn == dac->nextOut);
+               /* buffer under run */
+               stop_dac(s);
+       }
+
+#if defined(VRC5477_AC97_VERBOSE_DEBUG)
+       if (dac->count) {
+               outTicket ++;
+               MIPS_ASSERT(*(u16*)(dac->lbuf +  dac->nextOut) == outTicket);
+       }
+#endif
+       
+       /* we cannot have both under run and someone is waiting on us */
+       MIPS_ASSERT(! (waitqueue_active(&dac->wait) && (dac->count <= 0)) );
+
+       /* wake up anybody listening */
+       if (waitqueue_active(&dac->wait))
+               wake_up_interruptible(&dac->wait);
+}
+
+static void vrc5477_ac97_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+       struct vrc5477_ac97_state *s = (struct vrc5477_ac97_state *)dev_id;
+       u32 irqStatus;
+       u32 adcInterrupts, dacInterrupts;
+
+       spin_lock(&s->lock);
+
+       /* get irqStatus and clear the detected ones */
+       irqStatus = inl(s->io + VRC5477_INT_STATUS);
+       outl(irqStatus, s->io + VRC5477_INT_CLR);
+
+       /* let us see what we get */
+       dacInterrupts = VRC5477_INT_MASK_DAC1END | VRC5477_INT_MASK_DAC2END;
+       adcInterrupts = VRC5477_INT_MASK_ADC1END | VRC5477_INT_MASK_ADC2END;
+       if (irqStatus & dacInterrupts) {
+               /* we should get both interrupts, but just in case ...  */
+               if (irqStatus & VRC5477_INT_MASK_DAC1END) {
+                       vrc5477_ac97_dac_interrupt(s);
+               }
+               if ( (irqStatus & dacInterrupts) != dacInterrupts ) {
+                       printk(KERN_WARNING "vrc5477_ac97 : dac interrupts not in sync!!!\n");
+                       stop_dac(s);
+                       start_dac(s);
+               }
+       } else if (irqStatus & adcInterrupts) {
+               /* we should get both interrupts, but just in case ...  */
+               if(irqStatus & VRC5477_INT_MASK_ADC1END) {
+                       vrc5477_ac97_adc_interrupt(s);
+               } 
+               if ( (irqStatus & adcInterrupts) != adcInterrupts ) {
+                       printk(KERN_WARNING "vrc5477_ac97 : adc interrupts not in sync!!!\n");
+                       stop_adc(s);
+                       start_adc(s);
+               }
+       }
+
+       spin_unlock(&s->lock);
+}
+
+/* --------------------------------------------------------------------- */
+
+static loff_t vrc5477_ac97_llseek(struct file *file, loff_t offset, int origin)
+{
+       return -ESPIPE;
+}
+
+
+static int vrc5477_ac97_open_mixdev(struct inode *inode, struct file *file)
+{
+       int minor = MINOR(inode->i_rdev);
+       struct list_head *list;
+       struct vrc5477_ac97_state *s;
+
+       for (list = devs.next; ; list = list->next) {
+               if (list == &devs)
+                       return -ENODEV;
+               s = list_entry(list, struct vrc5477_ac97_state, devs);
+               if (s->codec.dev_mixer == minor)
+                       break;
+       }
+       file->private_data = s;
+       return 0;
+}
+
+static int vrc5477_ac97_release_mixdev(struct inode *inode, struct file *file)
+{
+       return 0;
+}
+
+
+static int mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd,
+                       unsigned long arg)
+{
+       return codec->mixer_ioctl(codec, cmd, arg);
+}
+
+static int vrc5477_ac97_ioctl_mixdev(struct inode *inode, struct file *file,
+                                    unsigned int cmd, unsigned long arg)
+{
+    struct vrc5477_ac97_state *s = 
+           (struct vrc5477_ac97_state *)file->private_data;
+    struct ac97_codec *codec = &s->codec;
+
+    return mixdev_ioctl(codec, cmd, arg);
+}
+
+static /*const*/ struct file_operations vrc5477_ac97_mixer_fops = {
+       owner:          THIS_MODULE,
+       llseek:         vrc5477_ac97_llseek,
+       ioctl:          vrc5477_ac97_ioctl_mixdev,
+       open:           vrc5477_ac97_open_mixdev,
+       release:        vrc5477_ac97_release_mixdev,
+};
+
+/* --------------------------------------------------------------------- */
+
+static int drain_dac(struct vrc5477_ac97_state *s, int nonblock)
+{
+       unsigned long flags;
+       int count, tmo;
+       
+       if (!s->dma_dac.ready)
+               return 0;
+
+       for (;;) {
+               spin_lock_irqsave(&s->lock, flags);
+               count = s->dma_dac.count;
+               spin_unlock_irqrestore(&s->lock, flags);
+               if (count <= 0)
+                       break;
+               if (signal_pending(current))
+                       break;
+               if (nonblock)
+                       return -EBUSY;
+               tmo = 1000 * count / s->dacRate / 2;
+               vrc5477_ac97_delay(tmo);
+       }
+       if (signal_pending(current))
+               return -ERESTARTSYS;
+       return 0;
+}
+
+/* --------------------------------------------------------------------- */
+
+static int inline 
+copy_two_channel_adc_to_user(struct vrc5477_ac97_state *s, 
+                            char *buffer, 
+                            int copyCount)
+{
+       struct dmabuf *db = &s->dma_adc;
+       int bufStart = db->nextOut;
+       for (; copyCount > 0; ) {
+               int i;
+               int count = copyCount;
+               if (count > WORK_BUF_SIZE/2) count = WORK_BUF_SIZE/2;
+               for (i=0; i< count/2; i++) {
+                       s->workBuf[i].lchannel = 
+                               *(u16*)(db->lbuf + bufStart + i*2);
+                       s->workBuf[i].rchannel = 
+                               *(u16*)(db->rbuf + bufStart + i*2);
+               }
+               if (copy_to_user(buffer, s->workBuf, count*2)) {
+                       return -1;
+               }
+
+               copyCount -= count;
+               bufStart += count;
+               MIPS_ASSERT(bufStart <= db->fragTotalSize);
+               buffer += count *2;
+       }
+       return 0;
+}
+
+/* return the total bytes that is copied */
+static int inline 
+copy_adc_to_user(struct vrc5477_ac97_state *s,
+                char * buffer,
+                size_t count,
+                int avail)
+{
+       struct dmabuf *db = &s->dma_adc;
+       int copyCount=0;
+       int copyFragCount=0;
+       int totalCopyCount = 0;
+       int totalCopyFragCount = 0;
+       unsigned long flags;
+
+       /* adjust count to signel channel byte count */
+       count >>= s->adcChannels - 1;
+
+       /* we may have to "copy" twice as ring buffer wraps around */
+       for (; (avail > 0) && (count > 0); ) {
+               /* determine max possible copy count for single channel */
+               copyCount = count;
+               if (copyCount > avail) {
+                       copyCount = avail;
+               }
+               if (copyCount + db->nextOut > db->fragTotalSize) {
+                       copyCount = db->fragTotalSize - db->nextOut;
+                       MIPS_ASSERT((copyCount % db->fragSize) == 0);
+               }
+
+               copyFragCount = (copyCount-1) >> db->fragShift;
+               copyFragCount = (copyFragCount+1) << db->fragShift;
+               MIPS_ASSERT(copyFragCount >= copyCount);
+
+               /* we copy differently based on adc channels */
+               if (s->adcChannels == 1) {
+                       if (copy_to_user(buffer, 
+                                        db->lbuf + db->nextOut, 
+                                        copyCount)) 
+                               return -1;
+               } else {
+                       /* *sigh* we have to mix two streams into one  */
+                       if (copy_two_channel_adc_to_user(s, buffer, copyCount))
+                               return -1;
+               }       
+
+               count -= copyCount;
+               totalCopyCount += copyCount;
+               avail -= copyFragCount;
+               totalCopyFragCount += copyFragCount;
+
+               buffer += copyCount << (s->adcChannels-1);
+
+               db->nextOut += copyFragCount;
+               if (db->nextOut >= db->fragTotalSize) {
+                       MIPS_ASSERT(db->nextOut == db->fragTotalSize);
+                       db->nextOut = 0;
+               }
+
+               MIPS_ASSERT((copyFragCount % db->fragSize) == 0);
+               MIPS_ASSERT( (count == 0) || (copyCount == copyFragCount));
+       }
+
+       spin_lock_irqsave(&s->lock, flags);
+        db->count -= totalCopyFragCount;
+        spin_unlock_irqrestore(&s->lock, flags);
+
+       return totalCopyCount << (s->adcChannels-1);
+}
+
+static ssize_t 
+vrc5477_ac97_read(struct file *file, 
+                 char *buffer,
+                 size_t count, 
+                 loff_t *ppos)
+{
+       struct vrc5477_ac97_state *s = 
+               (struct vrc5477_ac97_state *)file->private_data;
+       struct dmabuf *db = &s->dma_adc;
+       ssize_t ret = 0;
+       unsigned long flags;
+       int copyCount;
+       size_t avail;
+
+       if (ppos != &file->f_pos)
+               return -ESPIPE;
+       if (!access_ok(VERIFY_WRITE, buffer, count))
+               return -EFAULT;
+
+       MIPS_ASSERT(db->ready);
+
+       while (count > 0) {
+               // wait for samples in capture buffer
+               do {
+                       spin_lock_irqsave(&s->lock, flags);
+                       if (db->stopped)
+                               start_adc(s);
+                       avail = db->count;
+                       spin_unlock_irqrestore(&s->lock, flags);
+                       if (avail <= 0) {
+                               if (file->f_flags & O_NONBLOCK) {
+                                       if (!ret)
+                                               ret = -EAGAIN;
+                                       return ret;
+                               }
+                               interruptible_sleep_on(&db->wait);
+                               if (signal_pending(current)) {
+                                       if (!ret)
+                                               ret = -ERESTARTSYS;
+                                       return ret;
+                               }
+                       }
+               } while (avail <= 0);
+
+               MIPS_ASSERT( (avail % db->fragSize) == 0);
+               copyCount = copy_adc_to_user(s, buffer, count, avail);
+               if (copyCount <=0 ) {
+                       if (!ret) ret = -EFAULT;
+                       return ret;
+               }
+
+               count -= copyCount;
+               buffer += copyCount;
+               ret += copyCount;
+       } // while (count > 0)
+
+       return ret;
+}
+
+static int inline 
+copy_two_channel_dac_from_user(struct vrc5477_ac97_state *s, 
+                              const char *buffer, 
+                              int copyCount)
+{
+       struct dmabuf *db = &s->dma_dac;
+       int bufStart = db->nextIn;
+
+       MIPS_ASSERT(db->ready);
+
+        for (; copyCount > 0; ) {
+                int i;
+                int count = copyCount;
+                if (count > WORK_BUF_SIZE/2) count = WORK_BUF_SIZE/2;
+                if (copy_from_user(s->workBuf, buffer, count*2)) {
+                        return -1;
+                }
+                for (i=0; i< count/2; i++) {
+                       *(u16*)(db->lbuf + bufStart + i*2) = 
+                               s->workBuf[i].lchannel;
+                       *(u16*)(db->rbuf + bufStart + i*2) = 
+                               s->workBuf[i].rchannel;
+                }
+
+                copyCount -= count;
+               bufStart += count;
+               MIPS_ASSERT(bufStart <= db->fragTotalSize);
+                buffer += count *2;
+        }
+        return 0;
+
+}
+
+/* return the total bytes that is copied */
+static int inline 
+copy_dac_from_user(struct vrc5477_ac97_state *s, 
+                  const char *buffer, 
+                  size_t count, 
+                  int avail)
+{      
+        struct dmabuf *db = &s->dma_dac;
+        int copyCount=0;
+        int copyFragCount=0;
+        int totalCopyCount = 0;
+        int totalCopyFragCount = 0;
+        unsigned long flags;
+#if defined(VRC5477_AC97_VERBOSE_DEBUG)
+       int i;
+#endif
+
+        /* adjust count to signel channel byte count */
+        count >>= s->dacChannels - 1;
+
+        /* we may have to "copy" twice as ring buffer wraps around */
+        for (; (avail > 0) && (count > 0); ) {
+                /* determine max possible copy count for single channel */
+                copyCount = count;
+                if (copyCount > avail) {
+                        copyCount = avail;
+               }
+                if (copyCount + db->nextIn > db->fragTotalSize) {
+                        copyCount = db->fragTotalSize - db->nextIn;
+                        MIPS_ASSERT((copyCount % db->fragSize) == 0);
+                        MIPS_ASSERT(copyCount > 0);
+                }
+
+               copyFragCount = (copyCount-1) >> db->fragShift;
+               copyFragCount = (copyFragCount+1) << db->fragShift;
+               MIPS_ASSERT(copyFragCount >= copyCount);
+
+               /* we copy differently based on the number channels */
+               if (s->dacChannels == 1) {
+                       if (copy_from_user(db->lbuf + db->nextIn,
+                                          buffer,
+                                          copyCount)) 
+                               return -1;
+                       /* fill gaps with 0 */
+                       memset(db->lbuf + db->nextIn + copyCount,
+                              0,
+                              copyFragCount - copyCount);
+               } else {
+                       /* we have demux the stream into two separate ones */
+                       if (copy_two_channel_dac_from_user(s, buffer, copyCount))
+                               return -1;
+                       /* fill gaps with 0 */
+                       memset(db->lbuf + db->nextIn + copyCount,
+                              0,
+                              copyFragCount - copyCount);
+                       memset(db->rbuf + db->nextIn + copyCount,
+                              0,
+                              copyFragCount - copyCount);
+               }
+
+#if defined(VRC5477_AC97_VERBOSE_DEBUG)
+               for (i=0; i< copyFragCount; i+= db->fragSize) {
+                       *(u16*)(db->lbuf + db->nextIn + i) = inTicket ++;
+               }
+#endif
+
+               count -= copyCount;
+               totalCopyCount =+ copyCount;
+               avail -= copyFragCount;
+               totalCopyFragCount += copyFragCount;
+
+               buffer += copyCount << (s->dacChannels - 1);
+
+               db->nextIn += copyFragCount;
+               if (db->nextIn >= db->fragTotalSize) {
+                       MIPS_ASSERT(db->nextIn == db->fragTotalSize);
+                       db->nextIn = 0;
+               }
+
+               MIPS_ASSERT((copyFragCount % db->fragSize) == 0);
+               MIPS_ASSERT( (count == 0) || (copyCount == copyFragCount));
+       }
+
+       spin_lock_irqsave(&s->lock, flags);
+        db->count += totalCopyFragCount;
+       if (db->stopped) {
+               start_dac(s);
+       }
+
+       /* nextIn should not be equal to nextOut unless we are full */
+       MIPS_ASSERT( ( (db->count == db->fragTotalSize) && 
+                       (db->nextIn == db->nextOut) ) ||
+                     ( (db->count < db->fragTotalSize) &&
+                       (db->nextIn != db->nextOut) ) );
+
+        spin_unlock_irqrestore(&s->lock, flags);
+
+        return totalCopyCount << (s->dacChannels-1);
+
+}
+
+static ssize_t vrc5477_ac97_write(struct file *file, const char *buffer,
+                                 size_t count, loff_t *ppos)
+{
+       struct vrc5477_ac97_state *s = 
+               (struct vrc5477_ac97_state *)file->private_data;
+       struct dmabuf *db = &s->dma_dac;
+       ssize_t ret;
+       unsigned long flags;
+       int copyCount, avail;
+
+       if (ppos != &file->f_pos)
+               return -ESPIPE;
+       if (!access_ok(VERIFY_READ, buffer, count))
+               return -EFAULT;
+       ret = 0;
+    
+       while (count > 0) {
+               // wait for space in playback buffer
+               do {
+                       spin_lock_irqsave(&s->lock, flags);
+                       avail = db->fragTotalSize - db->count;
+                       spin_unlock_irqrestore(&s->lock, flags);
+                       if (avail <= 0) {
+                               if (file->f_flags & O_NONBLOCK) {
+                                       if (!ret)
+                                               ret = -EAGAIN;
+                                       return ret;
+                               }
+                               interruptible_sleep_on(&db->wait);
+                               if (signal_pending(current)) {
+                                       if (!ret)
+                                               ret = -ERESTARTSYS;
+                                       return ret;
+                               }
+                       }
+               } while (avail <= 0);
+       
+               MIPS_ASSERT( (avail % db->fragSize) == 0);
+               copyCount = copy_dac_from_user(s, buffer, count, avail);
+               if (copyCount < 0) {
+                       if (!ret) ret = -EFAULT;
+                       return ret;
+               }
+
+               count -= copyCount;
+               buffer += copyCount;
+               ret += copyCount;
+       } // while (count > 0)
+       
+       return ret;
+}
+
+/* No kernel lock - we have our own spinlock */
+static unsigned int vrc5477_ac97_poll(struct file *file,
+                                     struct poll_table_struct *wait)
+{
+       struct vrc5477_ac97_state *s = (struct vrc5477_ac97_state *)file->private_data;
+       unsigned long flags;
+       unsigned int mask = 0;
+
+       if (file->f_mode & FMODE_WRITE)
+               poll_wait(file, &s->dma_dac.wait, wait);
+       if (file->f_mode & FMODE_READ)
+               poll_wait(file, &s->dma_adc.wait, wait);
+       spin_lock_irqsave(&s->lock, flags);
+       if (file->f_mode & FMODE_READ) {
+               if (s->dma_adc.count >= (signed)s->dma_adc.fragSize)
+                       mask |= POLLIN | POLLRDNORM;
+       }
+       if (file->f_mode & FMODE_WRITE) {
+               if ((signed)s->dma_dac.fragTotalSize >=
+                   s->dma_dac.count + (signed)s->dma_dac.fragSize)
+                       mask |= POLLOUT | POLLWRNORM;
+       }
+       spin_unlock_irqrestore(&s->lock, flags);
+       return mask;
+}
+
+#ifdef CONFIG_LL_DEBUG
+static struct ioctl_str_t {
+    unsigned int cmd;
+    const char* str;
+} ioctl_str[] = {
+    {SNDCTL_DSP_RESET, "SNDCTL_DSP_RESET"},
+    {SNDCTL_DSP_SYNC, "SNDCTL_DSP_SYNC"},
+    {SNDCTL_DSP_SPEED, "SNDCTL_DSP_SPEED"},
+    {SNDCTL_DSP_STEREO, "SNDCTL_DSP_STEREO"},
+    {SNDCTL_DSP_GETBLKSIZE, "SNDCTL_DSP_GETBLKSIZE"},
+    {SNDCTL_DSP_SETFMT, "SNDCTL_DSP_SETFMT"},
+    {SNDCTL_DSP_SAMPLESIZE, "SNDCTL_DSP_SAMPLESIZE"},
+    {SNDCTL_DSP_CHANNELS, "SNDCTL_DSP_CHANNELS"},
+    {SOUND_PCM_WRITE_CHANNELS, "SOUND_PCM_WRITE_CHANNELS"},
+    {SOUND_PCM_WRITE_FILTER, "SOUND_PCM_WRITE_FILTER"},
+    {SNDCTL_DSP_POST, "SNDCTL_DSP_POST"},
+    {SNDCTL_DSP_SUBDIVIDE, "SNDCTL_DSP_SUBDIVIDE"},
+    {SNDCTL_DSP_SETFRAGMENT, "SNDCTL_DSP_SETFRAGMENT"},
+    {SNDCTL_DSP_GETFMTS, "SNDCTL_DSP_GETFMTS"},
+    {SNDCTL_DSP_GETOSPACE, "SNDCTL_DSP_GETOSPACE"},
+    {SNDCTL_DSP_GETISPACE, "SNDCTL_DSP_GETISPACE"},
+    {SNDCTL_DSP_NONBLOCK, "SNDCTL_DSP_NONBLOCK"},
+    {SNDCTL_DSP_GETCAPS, "SNDCTL_DSP_GETCAPS"},
+    {SNDCTL_DSP_GETTRIGGER, "SNDCTL_DSP_GETTRIGGER"},
+    {SNDCTL_DSP_SETTRIGGER, "SNDCTL_DSP_SETTRIGGER"},
+    {SNDCTL_DSP_GETIPTR, "SNDCTL_DSP_GETIPTR"},
+    {SNDCTL_DSP_GETOPTR, "SNDCTL_DSP_GETOPTR"},
+    {SNDCTL_DSP_MAPINBUF, "SNDCTL_DSP_MAPINBUF"},
+    {SNDCTL_DSP_MAPOUTBUF, "SNDCTL_DSP_MAPOUTBUF"},
+    {SNDCTL_DSP_SETSYNCRO, "SNDCTL_DSP_SETSYNCRO"},
+    {SNDCTL_DSP_SETDUPLEX, "SNDCTL_DSP_SETDUPLEX"},
+    {SNDCTL_DSP_GETODELAY, "SNDCTL_DSP_GETODELAY"},
+    {SNDCTL_DSP_GETCHANNELMASK, "SNDCTL_DSP_GETCHANNELMASK"},
+    {SNDCTL_DSP_BIND_CHANNEL, "SNDCTL_DSP_BIND_CHANNEL"},
+    {OSS_GETVERSION, "OSS_GETVERSION"},
+    {SOUND_PCM_READ_RATE, "SOUND_PCM_READ_RATE"},
+    {SOUND_PCM_READ_CHANNELS, "SOUND_PCM_READ_CHANNELS"},
+    {SOUND_PCM_READ_BITS, "SOUND_PCM_READ_BITS"},
+    {SOUND_PCM_READ_FILTER, "SOUND_PCM_READ_FILTER"}
+};
+#endif    
+
+static int vrc5477_ac97_ioctl(struct inode *inode, struct file *file,
+                       unsigned int cmd, unsigned long arg)
+{
+       struct vrc5477_ac97_state *s = (struct vrc5477_ac97_state *)file->private_data;
+       unsigned long flags;
+       audio_buf_info abinfo;
+       int count;
+       int val, ret;
+
+#ifdef CONFIG_LL_DEBUG
+       for (count=0; count<sizeof(ioctl_str)/sizeof(ioctl_str[0]); count++) {
+               if (ioctl_str[count].cmd == cmd)
+                       break;
+       }
+       if (count < sizeof(ioctl_str)/sizeof(ioctl_str[0]))
+               printk(KERN_INFO PFX "ioctl %s\n", ioctl_str[count].str);
+       else
+               printk(KERN_INFO PFX "ioctl unknown, 0x%x\n", cmd);
+#endif
+    
+       switch (cmd) {
+       case OSS_GETVERSION:
+               return put_user(SOUND_VERSION, (int *)arg);
+
+       case SNDCTL_DSP_SYNC:
+               if (file->f_mode & FMODE_WRITE)
+                       return drain_dac(s, file->f_flags & O_NONBLOCK);
+               return 0;
+               
+       case SNDCTL_DSP_SETDUPLEX:
+               return 0;
+
+       case SNDCTL_DSP_GETCAPS:
+               return put_user(DSP_CAP_DUPLEX, (int *)arg);
+               
+       case SNDCTL_DSP_RESET:
+               if (file->f_mode & FMODE_WRITE) {
+                       stop_dac(s);
+                       synchronize_irq();
+                       s->dma_dac.count = 0;
+                       s->dma_dac.nextIn = s->dma_dac.nextOut = 0;
+               }
+               if (file->f_mode & FMODE_READ) {
+                       stop_adc(s);
+                       synchronize_irq();
+                       s->dma_adc.count = 0;
+                       s->dma_adc.nextIn = s->dma_adc.nextOut = 0;
+               }
+               return 0;
+
+       case SNDCTL_DSP_SPEED:
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
+               if (val >= 0) {
+                       if (file->f_mode & FMODE_READ) {
+                               stop_adc(s);
+                               set_adc_rate(s, val);
+                               if ((ret = prog_dmabuf_adc(s)))
+                                       return ret;
+                       }
+                       if (file->f_mode & FMODE_WRITE) {
+                               stop_dac(s);
+                               set_dac_rate(s, val);
+                               if ((ret = prog_dmabuf_dac(s)))
+                                       return ret;
+                       }
+               }
+               return put_user((file->f_mode & FMODE_READ) ?
+                               s->adcRate : s->dacRate, (int *)arg);
+
+       case SNDCTL_DSP_STEREO:
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
+               if (file->f_mode & FMODE_READ) {
+                       stop_adc(s);
+                       if (val)
+                               s->adcChannels = 2;
+                       else
+                               s->adcChannels = 1;
+                       if ((ret = prog_dmabuf_adc(s)))
+                               return ret;
+               }
+               if (file->f_mode & FMODE_WRITE) {
+                       stop_dac(s);
+                       if (val)
+                               s->dacChannels = 2;
+                       else
+                               s->dacChannels = 1;
+                       if ((ret = prog_dmabuf_dac(s)))
+                               return ret;
+               }
+               return 0;
+
+       case SNDCTL_DSP_CHANNELS:
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
+               if (val != 0) {
+                       if ( (val != 1) && (val != 2)) val = 2;
+
+                       if (file->f_mode & FMODE_READ) {
+                               stop_adc(s);
+                               s->dacChannels = val;
+                               if ((ret = prog_dmabuf_adc(s)))
+                                       return ret;
+                       }
+                       if (file->f_mode & FMODE_WRITE) {
+                               stop_dac(s);
+                               s->dacChannels = val;
+                               if ((ret = prog_dmabuf_dac(s)))
+                                       return ret;
+                       }
+               }
+               return put_user(val, (int *)arg);
+               
+       case SNDCTL_DSP_GETFMTS: /* Returns a mask */
+               return put_user(AFMT_S16_LE, (int *)arg);
+               
+       case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
+               if (get_user(val, (int *)arg))
+                       return -EFAULT;
+               if (val != AFMT_QUERY) {
+                       if (val != AFMT_S16_LE) return -EINVAL;
+                       if (file->f_mode & FMODE_READ) {
+                               stop_adc(s);
+                               if ((ret = prog_dmabuf_adc(s)))
+                                       return ret;
+                       }
+                       if (file->f_mode & FMODE_WRITE) {
+                               stop_dac(s);
+                               if ((ret = prog_dmabuf_dac(s)))
+                                       return ret;
+                       }
+               } else {
+                       val = AFMT_S16_LE;
+               }
+               return put_user(val, (int *)arg);
+               
+       case SNDCTL_DSP_POST:
+               return 0;
+
+       case SNDCTL_DSP_GETTRIGGER:
+       case SNDCTL_DSP_SETTRIGGER:
+               /* NO trigger */
+               return -EINVAL;
+
+       case SNDCTL_DSP_GETOSPACE:
+               if (!(file->f_mode & FMODE_WRITE))
+                       return -EINVAL;
+               abinfo.fragsize = s->dma_dac.fragSize << (s->dacChannels-1);
+               spin_lock_irqsave(&s->lock, flags);
+               count = s->dma_dac.count;
+               spin_unlock_irqrestore(&s->lock, flags);
+               abinfo.bytes = (s->dma_dac.fragTotalSize - count) << 
+                       (s->dacChannels-1);
+               abinfo.fragstotal = s->dma_dac.numFrag;
+               abinfo.fragments = abinfo.bytes >> s->dma_dac.fragShift >> 
+                       (s->dacChannels-1);      
+               return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+
+       case SNDCTL_DSP_GETISPACE:
+               if (!(file->f_mode & FMODE_READ))
+                       return -EINVAL;
+               abinfo.fragsize = s->dma_adc.fragSize << (s->adcChannels-1);
+               spin_lock_irqsave(&s->lock, flags);
+               count = s->dma_adc.count;
+               spin_unlock_irqrestore(&s->lock, flags);
+               if (count < 0)
+                       count = 0;
+               abinfo.bytes = count << (s->adcChannels-1);
+               abinfo.fragstotal = s->dma_adc.numFrag;
+               abinfo.fragments = (abinfo.bytes >> s->dma_adc.fragShift) >>
+                       (s->adcChannels-1);      
+               return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+               
+       case SNDCTL_DSP_NONBLOCK:
+               file->f_flags |= O_NONBLOCK;
+               return 0;
+
+       case SNDCTL_DSP_GETODELAY:
+               if (!(file->f_mode & FMODE_WRITE))
+                       return -EINVAL;
+               spin_lock_irqsave(&s->lock, flags);
+               count = s->dma_dac.count;
+               spin_unlock_irqrestore(&s->lock, flags);
+               return put_user(count, (int *)arg);
+
+       case SNDCTL_DSP_GETIPTR:
+       case SNDCTL_DSP_GETOPTR:
+               /* we cannot get DMA ptr */
+               return -EINVAL;
+
+       case SNDCTL_DSP_GETBLKSIZE:
+               if (file->f_mode & FMODE_WRITE)
+                       return put_user(s->dma_dac.fragSize << (s->dacChannels-1), (int *)arg);
+               else
+                       return put_user(s->dma_adc.fragSize << (s->adcChannels-1), (int *)arg);
+
+       case SNDCTL_DSP_SETFRAGMENT:
+               /* we ignore fragment size request */
+               return 0;
+
+       case SNDCTL_DSP_SUBDIVIDE:
+               /* what is this for? [jsun] */
+               return 0;
+
+       case SOUND_PCM_READ_RATE:
+               return put_user((file->f_mode & FMODE_READ) ?
+                               s->adcRate : s->dacRate, (int *)arg);
+
+       case SOUND_PCM_READ_CHANNELS:
+               if (file->f_mode & FMODE_READ)
+                       return put_user(s->adcChannels, (int *)arg);
+               else
+                       return put_user(s->dacChannels ? 2 : 1, (int *)arg);
+           
+       case SOUND_PCM_READ_BITS:
+               return put_user(16, (int *)arg);
+
+       case SOUND_PCM_WRITE_FILTER:
+       case SNDCTL_DSP_SETSYNCRO:
+       case SOUND_PCM_READ_FILTER:
+               return -EINVAL;
+       }
+
+       return mixdev_ioctl(&s->codec, cmd, arg);
+}
+
+
+static int vrc5477_ac97_open(struct inode *inode, struct file *file)
+{
+       int minor = MINOR(inode->i_rdev);
+       DECLARE_WAITQUEUE(wait, current);
+       unsigned long flags;
+       struct list_head *list;
+       struct vrc5477_ac97_state *s;
+       int ret=0;
+    
+       for (list = devs.next; ; list = list->next) {
+               if (list == &devs)
+                       return -ENODEV;
+               s = list_entry(list, struct vrc5477_ac97_state, devs);
+               if (!((s->dev_audio ^ minor) & ~0xf))
+                       break;
+       }
+       file->private_data = s;
+
+       /* wait for device to become free */
+       down(&s->open_sem);
+       while (s->open_mode & file->f_mode) {
+
+               if (file->f_flags & O_NONBLOCK) {
+                       up(&s->open_sem);
+                       return -EBUSY;
+               }
+               add_wait_queue(&s->open_wait, &wait);
+               __set_current_state(TASK_INTERRUPTIBLE);
+               up(&s->open_sem);
+               schedule();
+               remove_wait_queue(&s->open_wait, &wait);
+               set_current_state(TASK_RUNNING);
+               if (signal_pending(current))
+                       return -ERESTARTSYS;
+               down(&s->open_sem);
+       }
+
+       spin_lock_irqsave(&s->lock, flags);
+
+       if (file->f_mode & FMODE_READ) {
+               /* set default settings */
+               set_adc_rate(s, 48000);
+               s->adcChannels = 2;
+
+               ret = prog_dmabuf_adc(s);
+               if (ret) goto bailout;
+       }
+       if (file->f_mode & FMODE_WRITE) {
+               /* set default settings */
+               set_dac_rate(s, 48000);
+               s->dacChannels = 2;
+
+               ret = prog_dmabuf_dac(s);
+               if (ret) goto bailout;
+       }
+
+       s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
+
+ bailout:
+       spin_unlock_irqrestore(&s->lock, flags);
+
+       up(&s->open_sem);
+       return ret;
+}
+
+static int vrc5477_ac97_release(struct inode *inode, struct file *file)
+{
+       struct vrc5477_ac97_state *s = 
+               (struct vrc5477_ac97_state *)file->private_data;
+
+       lock_kernel();
+       if (file->f_mode & FMODE_WRITE)
+               drain_dac(s, file->f_flags & O_NONBLOCK);
+       down(&s->open_sem);
+       if (file->f_mode & FMODE_WRITE) {
+               stop_dac(s);
+               dealloc_dmabuf(s, &s->dma_dac);
+       }
+       if (file->f_mode & FMODE_READ) {
+               stop_adc(s);
+               dealloc_dmabuf(s, &s->dma_adc);
+       }
+       s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
+       up(&s->open_sem);
+       wake_up(&s->open_wait);
+       unlock_kernel();
+       return 0;
+}
+
+static /*const*/ struct file_operations vrc5477_ac97_audio_fops = {
+       owner:  THIS_MODULE,
+       llseek:         vrc5477_ac97_llseek,
+       read:           vrc5477_ac97_read,
+       write:          vrc5477_ac97_write,
+       poll:           vrc5477_ac97_poll,
+       ioctl:          vrc5477_ac97_ioctl,
+       // mmap:        vrc5477_ac97_mmap,
+       open:           vrc5477_ac97_open,
+       release:        vrc5477_ac97_release,
+};
+
+
+/* --------------------------------------------------------------------- */
+
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * for debugging purposes, we'll create a proc device that dumps the
+ * CODEC chipstate
+ */
+
+#ifdef CONFIG_LL_DEBUG
+
+struct {
+       const char *regname;
+       unsigned regaddr;
+} vrc5477_ac97_regs[] = {
+       {"VRC5477_INT_STATUS", VRC5477_INT_STATUS},
+       {"VRC5477_CODEC_WR", VRC5477_CODEC_WR},
+       {"VRC5477_CODEC_RD", VRC5477_CODEC_RD},
+       {"VRC5477_CTRL", VRC5477_CTRL},
+       {"VRC5477_ACLINK_CTRL", VRC5477_ACLINK_CTRL},
+       {"VRC5477_INT_MASK", VRC5477_INT_MASK},
+       {"VRC5477_DAC1_CTRL", VRC5477_DAC1_CTRL},
+       {"VRC5477_DAC1L", VRC5477_DAC1L},
+       {"VRC5477_DAC1_BADDR", VRC5477_DAC1_BADDR},
+       {"VRC5477_DAC2_CTRL", VRC5477_DAC2_CTRL},
+       {"VRC5477_DAC2L", VRC5477_DAC2L},
+       {"VRC5477_DAC2_BADDR", VRC5477_DAC2_BADDR},
+       {"VRC5477_DAC3_CTRL", VRC5477_DAC3_CTRL},
+       {"VRC5477_DAC3L", VRC5477_DAC3L},
+       {"VRC5477_DAC3_BADDR", VRC5477_DAC3_BADDR},
+       {"VRC5477_ADC1_CTRL", VRC5477_ADC1_CTRL},
+       {"VRC5477_ADC1L", VRC5477_ADC1L},
+       {"VRC5477_ADC1_BADDR", VRC5477_ADC1_BADDR},
+       {"VRC5477_ADC2_CTRL", VRC5477_ADC2_CTRL},
+       {"VRC5477_ADC2L", VRC5477_ADC2L},
+       {"VRC5477_ADC2_BADDR", VRC5477_ADC2_BADDR},
+       {"VRC5477_ADC3_CTRL", VRC5477_ADC3_CTRL},
+       {"VRC5477_ADC3L", VRC5477_ADC3L},
+       {"VRC5477_ADC3_BADDR", VRC5477_ADC3_BADDR},
+       {NULL, 0x0}
+};
+
+static int proc_vrc5477_ac97_dump (char *buf, char **start, off_t fpos,
+                                  int length, int *eof, void *data)
+{
+       struct vrc5477_ac97_state *s;
+       int cnt, len = 0;
+
+       if (list_empty(&devs))
+               return 0;
+       s = list_entry(devs.next, struct vrc5477_ac97_state, devs);
+
+       /* print out header */
+       len += sprintf(buf + len, "\n\t\tVrc5477 Audio Debug\n\n");
+
+       // print out digital controller state
+       len += sprintf (buf + len, "NEC Vrc5477 Audio Controller registers\n");
+       len += sprintf (buf + len, "---------------------------------\n");
+       for (cnt=0; vrc5477_ac97_regs[cnt].regname != NULL; cnt++) {
+               len+= sprintf (buf + len, "%-20s = %08x\n",
+                              vrc5477_ac97_regs[cnt].regname,
+                              inl(s->io + vrc5477_ac97_regs[cnt].regaddr));
+       }
+   
+       /* print out driver state */
+       len += sprintf (buf + len, "NEC Vrc5477 Audio driver states\n");
+       len += sprintf (buf + len, "---------------------------------\n");
+       len += sprintf (buf + len, "dacChannels  = %d\n", s->dacChannels);
+       len += sprintf (buf + len, "adcChannels  = %d\n", s->adcChannels);
+       len += sprintf (buf + len, "dacRate  = %d\n", s->dacRate);
+       len += sprintf (buf + len, "adcRate  = %d\n", s->adcRate);
+
+       len += sprintf (buf + len, "dma_dac is %s ready\n",  
+                       s->dma_dac.ready? "" : "not");
+        if (s->dma_dac.ready) {
+               len += sprintf (buf + len, "dma_dac is %s stopped.\n",  
+                               s->dma_dac.stopped? "" : "not");
+               len += sprintf (buf + len, "dma_dac.fragSize = %x\n", 
+                                s->dma_dac.fragSize);
+               len += sprintf (buf + len, "dma_dac.fragShift = %x\n", 
+                                s->dma_dac.fragShift);
+               len += sprintf (buf + len, "dma_dac.numFrag = %x\n", 
+                                s->dma_dac.numFrag);
+               len += sprintf (buf + len, "dma_dac.fragTotalSize = %x\n", 
+                                s->dma_dac.fragTotalSize);
+               len += sprintf (buf + len, "dma_dac.nextIn = %x\n", 
+                                s->dma_dac.nextIn);
+               len += sprintf (buf + len, "dma_dac.nextOut = %x\n", 
+                                s->dma_dac.nextOut);
+               len += sprintf (buf + len, "dma_dac.count = %x\n", 
+                                s->dma_dac.count);
+       }
+
+       len += sprintf (buf + len, "dma_adc is %s ready\n",  
+                       s->dma_adc.ready? "" : "not");
+        if (s->dma_adc.ready) {
+               len += sprintf (buf + len, "dma_adc is %s stopped.\n",  
+                               s->dma_adc.stopped? "" : "not");
+               len += sprintf (buf + len, "dma_adc.fragSize = %x\n", 
+                                s->dma_adc.fragSize);
+               len += sprintf (buf + len, "dma_adc.fragShift = %x\n", 
+                                s->dma_adc.fragShift);
+               len += sprintf (buf + len, "dma_adc.numFrag = %x\n", 
+                                s->dma_adc.numFrag);
+               len += sprintf (buf + len, "dma_adc.fragTotalSize = %x\n", 
+                                s->dma_adc.fragTotalSize);
+               len += sprintf (buf + len, "dma_adc.nextIn = %x\n", 
+                                s->dma_adc.nextIn);
+               len += sprintf (buf + len, "dma_adc.nextOut = %x\n", 
+                                s->dma_adc.nextOut);
+               len += sprintf (buf + len, "dma_adc.count = %x\n", 
+                                s->dma_adc.count);
+       }
+        
+       /* print out CODEC state */
+       len += sprintf (buf + len, "\nAC97 CODEC registers\n");
+       len += sprintf (buf + len, "----------------------\n");
+       for (cnt=0; cnt <= 0x7e; cnt = cnt +2)
+               len+= sprintf (buf + len, "reg %02x = %04x\n",
+                              cnt, rdcodec(&s->codec, cnt));
+
+       if (fpos >=len){
+               *start = buf;
+               *eof =1;
+               return 0;
+       }
+       *start = buf + fpos;
+       if ((len -= fpos) > length)
+               return length;
+       *eof =1;
+       return len;
+
+}
+#endif /* CONFIG_LL_DEBUG */
+
+/* --------------------------------------------------------------------- */
+
+/* maximum number of devices; only used for command line params */
+#define NR_DEVICE 5
+
+static unsigned int devindex = 0;
+
+MODULE_AUTHOR("Monta Vista Software, jsun@mvista.com or jsun@junsun.net");
+MODULE_DESCRIPTION("NEC Vrc5477 audio (AC97) Driver");
+
+/* --------------------------------------------------------------------- */
+extern void jsun_scan_pci_bus(void);
+extern void vrc5477_show_pci_regs(void);
+extern void vrc5477_show_pdar_regs(void);
+
+/* -------------------------------------------------------- */
+#define         AC97_BASE               0xbb000000
+#define         myinl(x)                  *(volatile u32*)(AC97_BASE + (x))
+#define         myoutl(x,y)               *(volatile u32*)(AC97_BASE + (y)) = (x)
+
+u16 myrdcodec(u8 addr)
+{
+        u32 result;
+
+        /* wait until we can access codec registers */
+        // while (inl(VRC5477_CODEC_WR) & 0x80000000);
+
+        /* write the address and "read" command to codec */
+        addr = addr & 0x7f;
+        myoutl((addr << 16) | VRC5477_CODEC_WR_RWC, VRC5477_CODEC_WR);
+
+        /* get the return result */
+        udelay(100); /* workaround hardware bug */
+        // dump_memory(0xbb000000, 48);
+        while ( ((result=myinl(VRC5477_CODEC_RD)) & 0xc0000000) != 0xc0000000);
+        MIPS_ASSERT(addr == ((result >> 16) & 0x7f) );
+        return result & 0xffff;
+}
+
+void mywrcodec(u8 addr, u16 data)
+{
+        /* wait until we can access codec registers */
+        while (myinl(VRC5477_CODEC_WR) & 0x80000000);
+
+        /* write the address and value to codec */
+        myoutl((addr << 16) | data, VRC5477_CODEC_WR);
+
+}
+
+
+void jsun_ac97_test(struct vrc5477_ac97_state *s)
+{
+        int i;
+
+        /* reset codec */
+       /*
+        wrcodec(&s->codec, 0, 0);
+        while (inl(s->io + VRC5477_CODEC_WR) & 0x80000000);
+       */
+        mywrcodec(0, 0);
+        while (myinl(VRC5477_CODEC_WR) & 0x80000000);
+
+       for (i=0; i< 0x40; i+=4) {      
+       MIPS_ASSERT(inl(s->io+i) == myinl(i));
+       }
+
+        printk("codec registers : ");
+        for (i=0; i<= 0x3a; i+=2) {
+                if ( (i%0x10) == 0) {
+                        printk("\n%02x\t", i);
+                }
+                // printk("%04x\t", rdcodec(&s->codec, i));
+                printk("%04x\t", myrdcodec(i));
+        }
+        printk("\n\n");
+        printk("codec registers : ");
+        for (i=0; i<= 0x3a; i+=2) {
+                if ( (i%0x10) == 0) {
+                        printk("\n%02x\t", i);
+                }
+                printk("%04x\t", rdcodec(&s->codec, i));
+        }
+        printk("\n\n");
+}
+
+static int __devinit vrc5477_ac97_probe(struct pci_dev *pcidev,
+                                       const struct pci_device_id *pciid)
+{
+       struct vrc5477_ac97_state *s;
+       char proc_str[80];
+
+       MIPS_DEBUG(printk("vrc5477_ac97_probe() invoked\n"));
+
+       if (pcidev->irq == 0) 
+               return -1;
+
+       if (!(s = kmalloc(sizeof(struct vrc5477_ac97_state), GFP_KERNEL))) {
+               printk(KERN_ERR PFX "alloc of device struct failed\n");
+               return -1;
+       }
+       memset(s, 0, sizeof(struct vrc5477_ac97_state));
+
+       init_waitqueue_head(&s->dma_adc.wait);
+       init_waitqueue_head(&s->dma_dac.wait);
+       init_waitqueue_head(&s->open_wait);
+       init_MUTEX(&s->open_sem);
+       spin_lock_init(&s->lock);
+
+       s->dev = pcidev;
+       s->io = pci_resource_start(pcidev, 0);
+       s->irq = pcidev->irq;
+
+       s->codec.private_data = s;
+       s->codec.id = 0;
+       s->codec.codec_read = rdcodec;
+       s->codec.codec_write = wrcodec;
+       s->codec.codec_wait = waitcodec;
+
+       /* setting some other default values such as
+        * adcChannels, adcRate is done in open() so that
+         * no persistent state across file opens.
+        */
+
+       if (!request_region(s->io, pci_resource_len(pcidev,0),
+                           VRC5477_AC97_MODULE_NAME)) {
+               printk(KERN_ERR PFX "io ports %#lx->%#lx in use\n",
+                      s->io, s->io + pci_resource_len(pcidev,0)-1);
+               goto err_region;
+       }
+       if (request_irq(s->irq, vrc5477_ac97_interrupt, SA_INTERRUPT,
+                       VRC5477_AC97_MODULE_NAME, s)) {
+               printk(KERN_ERR PFX "irq %u in use\n", s->irq);
+               goto err_irq;
+       }
+
+       printk(KERN_INFO PFX "IO at %#lx, IRQ %d\n", s->io, s->irq);
+
+       /* register devices */
+       if ((s->dev_audio = register_sound_dsp(&vrc5477_ac97_audio_fops, -1)) < 0)
+               goto err_dev1;
+       if ((s->codec.dev_mixer =
+            register_sound_mixer(&vrc5477_ac97_mixer_fops, -1)) < 0)
+               goto err_dev2;
+
+#ifdef CONFIG_LL_DEBUG
+       /* intialize the debug proc device */
+       s->ps = create_proc_read_entry(VRC5477_AC97_MODULE_NAME, 0, NULL,
+                                      proc_vrc5477_ac97_dump, NULL);
+#endif /* CONFIG_LL_DEBUG */
+       
+       /* enable pci io and bus mastering */
+       if (pci_enable_device(pcidev))
+               goto err_dev3;
+       pci_set_master(pcidev);
+
+/*
+jsun_scan_pci_bus();
+vrc5477_show_pci_regs();
+vrc5477_show_pdar_regs();
+*/
+
+       /* cold reset the AC97 */
+       outl(VRC5477_ACLINK_CTRL_RST_ON | VRC5477_ACLINK_CTRL_RST_TIME,
+            s->io + VRC5477_ACLINK_CTRL);
+       while (inl(s->io + VRC5477_ACLINK_CTRL) & VRC5477_ACLINK_CTRL_RST_ON);
+
+/*
+jsun_ac97_test(s);
+*/
+
+       /* codec init */
+       if (!ac97_probe_codec(&s->codec))
+               goto err_dev3;
+
+#ifdef CONFIG_LL_DEBUG
+       sprintf(proc_str, "driver/%s/%d/ac97", 
+               VRC5477_AC97_MODULE_NAME, s->codec.id);
+       s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
+                                            ac97_read_proc, &s->codec);
+       /* TODO : why this proc file does not show up? */
+#endif
+
+        /* let us get the default volumne louder */
+        wrcodec(&s->codec, 0x2, 0);
+        wrcodec(&s->codec, 0x18, 0x0707);
+       /* mute line in loopback to line out */
+       wrcodec(&s->codec, 0x10, 0x8000);
+
+       /* by default we select line in the input */
+       wrcodec(&s->codec, 0x1a, 0x0404);
+       /* pick middle value for record gain */
+       // wrcodec(&s->codec, 0x1c, 0x0707);
+       wrcodec(&s->codec, 0x1c, 0x0f0f);
+       wrcodec(&s->codec, 0x1e, 0x07);
+
+       /* enable the master interrupt but disable all others */
+       outl(VRC5477_INT_MASK_NMASK, s->io + VRC5477_INT_MASK);
+
+       /* store it in the driver field */
+       pci_set_drvdata(pcidev, s);
+       pcidev->dma_mask = 0xffffffff;
+       /* put it into driver list */
+       list_add_tail(&s->devs, &devs);
+       /* increment devindex */
+       if (devindex < NR_DEVICE-1)
+               devindex++;
+       return 0;
+
+ err_dev3:
+       unregister_sound_mixer(s->codec.dev_mixer);
+ err_dev2:
+       unregister_sound_dsp(s->dev_audio);
+ err_dev1:
+       printk(KERN_ERR PFX "cannot register misc device\n");
+       free_irq(s->irq, s);
+ err_irq:
+       release_region(s->io, pci_resource_len(pcidev,0));
+ err_region:
+       kfree(s);
+       return -1;
+}
+
+static void __devinit vrc5477_ac97_remove(struct pci_dev *dev)
+{
+       struct vrc5477_ac97_state *s = pci_get_drvdata(dev);
+
+       if (!s)
+               return;
+       list_del(&s->devs);
+#ifdef CONFIG_LL_DEBUG
+       if (s->ps)
+               remove_proc_entry(VRC5477_AC97_MODULE_NAME, NULL);
+#endif /* CONFIG_LL_DEBUG */
+       synchronize_irq();
+       free_irq(s->irq, s);
+       release_region(s->io, pci_resource_len(dev,0));
+       unregister_sound_dsp(s->dev_audio);
+       unregister_sound_mixer(s->codec.dev_mixer);
+       kfree(s);
+       pci_set_drvdata(dev, NULL);
+}
+
+
+#define                PCI_VENDOR_ID_NEC               0x1033
+#define                PCI_DEVICE_ID_NEC_VRC5477_AC97  0x00A6
+static struct pci_device_id id_table[] __devinitdata = {
+    { PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_VRC5477_AC97, 
+      PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
+    { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, id_table);
+
+static struct pci_driver vrc5477_ac97_driver = {
+       name: VRC5477_AC97_MODULE_NAME,
+       id_table: id_table,
+       probe: vrc5477_ac97_probe,
+       remove: vrc5477_ac97_remove
+};
+
+static int __init init_vrc5477_ac97(void)
+{
+       if (!pci_present())   /* No PCI bus in this machine! */
+               return -ENODEV;
+       printk("Vrc5477 AC97 driver: version v0.1 time " __TIME__ " " __DATE__ " by Jun Sun\n");
+       return pci_module_init(&vrc5477_ac97_driver);
+}
+
+static void __exit cleanup_vrc5477_ac97(void)
+{
+       printk(KERN_INFO PFX "unloading\n");
+       pci_unregister_driver(&vrc5477_ac97_driver);
+}
+
+module_init(init_vrc5477_ac97);
+module_exit(cleanup_vrc5477_ac97);
+
index 73af759a7dae805262564a3c64e0071fc7f76b67..43803826ec9b34a875269653596d4e173aa7c179 100644 (file)
@@ -2496,7 +2496,7 @@ static struct initvol {
 
 static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
 {
-       static const char __initdata sv_ddma_name[] = "S3 Inc. SonicVibes DDMA Controller";
+       static char __initdata sv_ddma_name[] = "S3 Inc. SonicVibes DDMA Controller";
                struct sv_state *s;
        mm_segment_t fs;
        int i, val, ret;
index cf073f5930286497c4275e2083d40391f6c0e082..5e173ebea909bafd37c1aeaa8d36da9fc54cbfc2 100644 (file)
@@ -1,6 +1,10 @@
 /*
+ *     OSS driver for Linux 2.4.x for
  *
- *     Trident 4D-Wave/SiS 7018/ALi 5451 OSS driver for Linux 2.2.x
+ *     Trident 4D-Wave
+ *     SiS 7018
+ *     ALi 5451
+ *     Tvia/IGST CyberPro 5050
  *
  *     Driver: Alan Cox <alan@redhat.com>
  *
@@ -14,6 +18,7 @@
  *     Ollie Lho <ollie@sis.com.tw> SiS 7018 Audio Core Support
  *     Ching-Ling Lee <cling-li@ali.com.tw> ALi 5451 Audio Core Support 
  *     Matt Wu <mattwu@acersoftech.com.cn> ALi 5451 Audio Core Support
+ *     Peter Wächtler <pwaechtler@loewe-komp.de> CyberPro5050 support
  *
  *
  *     This program is free software; you can redistribute it and/or modify
  *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  *  History
+ *  v0.14.9c
+ *     August 10 2001 Peter Wächtler <pwaechtler@loewe-komp.de>
+ *     added support for Tvia (formerly Integraphics/IGST) CyberPro5050
+ *     this chip is often found in settop boxes (combined video+audio)
  *  v0.14.9b
  *     Switch to static inline not extern inline (gcc 3)
  *  v0.14.9a
@@ -61,7 +70,7 @@
  *     Implement multi-channels and S/PDIF in support for ALi 1535+
  *  v0.14.6 
  *     Nov 1 2000 Ching-Ling Lee
- *     Fix the bug of memory leak when swithing 5.1-channels to 2 channels.
+ *     Fix the bug of memory leak when switching 5.1-channels to 2 channels.
  *     Add lock protection into dynamic changing format of data.
  *     Oct 18 2000 Ching-Ling Lee
  *     5.1-channels support for ALi
 
 #include <linux/pm.h>
 
-#define DRIVER_VERSION "0.14.9b"
+#define DRIVER_VERSION "0.14.9c"
 
 /* magic numbers to protect our data structures */
 #define TRIDENT_CARD_MAGIC     0x5072696E /* "Prin" */
@@ -195,14 +204,16 @@ enum {
        TRIDENT_4D_DX = 0,
        TRIDENT_4D_NX,
        SIS_7018,
-       ALI_5451
+       ALI_5451,
+       CYBER5050
 };
 
 static char * card_names[] = {
        "Trident 4DWave DX",
        "Trident 4DWave NX",
        "SiS 7018 PCI Audio",
-       "ALi Audio Accelerator"
+       "ALi Audio Accelerator",
+       "Tvia/IGST CyberPro 5050"
 };
 
 static struct pci_device_id trident_pci_tbl [] __devinitdata = {
@@ -214,6 +225,8 @@ static struct pci_device_id trident_pci_tbl [] __devinitdata = {
         PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_7018},
        {PCI_VENDOR_ID_ALI, PCI_DEVICE_ID_ALI_5451,
         PCI_ANY_ID, PCI_ANY_ID, 0, 0, ALI_5451},
+       { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5050, 
+        PCI_ANY_ID, PCI_ANY_ID, 0, 0, CYBER5050},
        {0,}
 };
 
@@ -456,6 +469,7 @@ static int trident_enable_loop_interrupts(struct trident_card * card)
        case PCI_DEVICE_ID_ALI_5451:
        case PCI_DEVICE_ID_TRIDENT_4DWAVE_DX:
        case PCI_DEVICE_ID_TRIDENT_4DWAVE_NX:
+       case PCI_DEVICE_ID_INTERG_5050:
                global_control |= (ENDLP_IE | MIDLP_IE);
                break;
        default:
@@ -466,7 +480,7 @@ static int trident_enable_loop_interrupts(struct trident_card * card)
 
 #ifdef DEBUG
        printk("trident: Enable Loop Interrupts, globctl = 0x%08X\n",
-              global_control);
+                       inl(TRID_REG(card, T4D_LFO_GC_CIR)));
 #endif
        return (TRUE);
 }
@@ -497,9 +511,9 @@ static void trident_enable_voice_irq(struct trident_card * card, unsigned int ch
        outl(reg, TRID_REG(card, addr));
 
 #ifdef DEBUG
-       reg = inl(TRID_REG(card, T4D_AINTEN_B));
-       printk("trident: enabled IRQ on channel %d, AINTEN_B = 0x%08x\n",
-              channel, reg);
+       reg = inl(TRID_REG(card, addr));
+       printk("trident: enabled IRQ on channel %d, %s = 0x%08x(addr:%X)\n",
+               channel, addr==T4D_AINTEN_B? "AINTEN_B":"AINTEN_A",reg,addr);
 #endif
 }
 
@@ -517,9 +531,9 @@ static void trident_disable_voice_irq(struct trident_card * card, unsigned int c
        outl(mask, TRID_REG(card, bank->addresses->aint));
 
 #ifdef DEBUG
-       reg = inl(TRID_REG(card, T4D_AINTEN_B));
-       printk("trident: disabled IRQ on channel %d, AINTEN_B = 0x%08x\n",
-              channel, reg);
+       reg = inl(TRID_REG(card, addr));
+       printk("trident: disabled IRQ on channel %d, %s = 0x%08x(addr:%X)\n",
+               channel, addr==T4D_AINTEN_B? "AINTEN_B":"AINTEN_A",reg,addr);
 #endif
 }
 
@@ -536,9 +550,9 @@ static void trident_start_voice(struct trident_card * card, unsigned int channel
        outl(mask, TRID_REG(card, addr));
 
 #ifdef DEBUG
-       reg = inl(TRID_REG(card, T4D_START_B));
-       printk("trident: start voice on channel %d, START_B  = 0x%08x\n",
-              channel, reg);
+       reg = inl(TRID_REG(card, addr));
+       printk("trident: start voice on channel %d, %s = 0x%08x(addr:%X)\n",
+               channel, addr==T4D_START_B? "START_B":"START_A",reg,addr);
 #endif
 }
 
@@ -555,9 +569,9 @@ static void trident_stop_voice(struct trident_card * card, unsigned int channel)
        outl(mask, TRID_REG(card, addr));
 
 #ifdef DEBUG
-       reg = inl(TRID_REG(card, T4D_STOP_B));
-       printk("trident: stop voice on channel %d,  STOP_B  = 0x%08x\n",
-              channel, reg);
+       reg = inl(TRID_REG(card, addr));
+       printk("trident: stop voice on channel %d, %s = 0x%08x(addr:%X)\n",
+               channel, addr==T4D_STOP_B? "STOP_B":"STOP_A",reg,addr);
 #endif
 }
 
@@ -575,8 +589,8 @@ static int trident_check_channel_interrupt(struct trident_card * card, unsigned
 
 #ifdef DEBUG
        if (reg & mask)
-               printk("trident: channel %d has interrupt, AINT_B = 0x%08x\n",
-                      channel, reg);
+               printk("trident: channel %d has interrupt, %s = 0x%08x\n",
+                       channel,reg==T4D_AINT_B? "AINT_B":"AINT_A", reg);
 #endif
        return (reg & mask) ? TRUE : FALSE;
 }
@@ -614,7 +628,7 @@ static struct trident_channel * trident_alloc_pcm_channel(struct trident_card *c
                }
        }
 
-       /* no more free channels avaliable */
+       /* no more free channels available */
        printk(KERN_ERR "trident: no more channels available on Bank B.\n");
        return NULL;
 }
@@ -632,7 +646,94 @@ static void trident_free_pcm_channel(struct trident_card *card, unsigned int cha
        card->banks[bank].bitmap &= ~(1 << (channel));
 }
 
-/* called with spin lock held */
+static struct trident_channel * cyber_alloc_pcm_channel(struct trident_card *card)
+{
+       struct trident_pcm_bank *bank;
+       int idx;
+
+       /* The cyberpro 5050 has only 32 voices and one bank */
+       /* .. at least they are not documented (if you want to call that 
+        * crap documentation), perhaps broken ? */
+
+       bank = &card->banks[BANK_A];
+
+       for (idx = 31; idx >= 0; idx--) {
+               if (!(bank->bitmap & (1 << idx))) {
+                       struct trident_channel *channel = &bank->channels[idx];
+                       bank->bitmap |= 1 << idx;
+                       channel->num = idx;
+                       return channel;
+               }
+       }
+
+       /* no more free channels available */
+       printk(KERN_ERR "cyberpro5050: no more channels available on Bank A.\n");
+       return NULL;
+}
+
+static void cyber_free_pcm_channel(struct trident_card *card, unsigned int channel)
+{
+       if (channel > 31)
+               return;
+       card->banks[BANK_A].bitmap &= ~(1 << (channel));
+}
+
+static inline void cyber_outidx(int port,int idx,int data)
+{
+       outb(idx,port);
+       outb(data,port+1);
+}
+
+static inline int cyber_inidx(int port,int idx)
+{
+       outb(idx,port);
+       return inb(port+1);
+}
+
+static int cyber_init_ritual(struct trident_card *card)
+{
+       /* some black magic, taken from SDK samples */
+       /* remove this and nothing will work */
+       int portDat;
+       int ret = 0;
+       unsigned long flags;
+
+       /*
+        *      Keep interrupts off for the configure - we don't want to
+        *      clash with another cyberpro config event
+        */
+       save_flags(flags);
+       cli();
+       portDat = cyber_inidx(CYBER_PORT_AUDIO, CYBER_IDX_AUDIO_ENABLE);
+       /* enable, if it was disabled */
+       if( (portDat & CYBER_BMSK_AUENZ) != CYBER_BMSK_AUENZ_ENABLE ) {
+               printk(KERN_INFO "cyberpro5050: enabling audio controller\n" );
+               cyber_outidx( CYBER_PORT_AUDIO, CYBER_IDX_AUDIO_ENABLE,
+                       portDat | CYBER_BMSK_AUENZ_ENABLE );
+               /* check again if hardware is enabled now */
+               portDat = cyber_inidx(CYBER_PORT_AUDIO, CYBER_IDX_AUDIO_ENABLE);
+       }
+       if( (portDat & CYBER_BMSK_AUENZ) != CYBER_BMSK_AUENZ_ENABLE )
+       {
+               printk(KERN_ERR "cyberpro5050: initAudioAccess: no success\n" );
+               ret = -1;
+       }
+       else
+       {
+               cyber_outidx( CYBER_PORT_AUDIO, CYBER_IDX_IRQ_ENABLE, CYBER_BMSK_AUDIO_INT_ENABLE );
+               cyber_outidx( CYBER_PORT_AUDIO, 0xbf, 0x01 );
+               cyber_outidx( CYBER_PORT_AUDIO, 0xba, 0x20 );
+               cyber_outidx( CYBER_PORT_AUDIO, 0xbb, 0x08 );
+               cyber_outidx( CYBER_PORT_AUDIO, 0xbf, 0x02 );
+               cyber_outidx( CYBER_PORT_AUDIO, 0xb3, 0x06 );
+               cyber_outidx( CYBER_PORT_AUDIO, 0xbf, 0x00 );
+       }
+       restore_flags(flags);
+       return ret;
+}
+
+/*  called with spin lock held */
 
 static int trident_load_channel_registers(struct trident_card *card, u32 *data, unsigned int channel)
 {
@@ -651,7 +752,8 @@ static int trident_load_channel_registers(struct trident_card *card, u32 *data,
                        continue;
                outl(data[i], TRID_REG(card, CHANNEL_START + 4*i));
        }
-       if (card->pci_id == PCI_DEVICE_ID_ALI_5451) {
+       if (card->pci_id == PCI_DEVICE_ID_ALI_5451 ||
+               card->pci_id == PCI_DEVICE_ID_INTERG_5050) {
                outl(ALI_EMOD_Still, TRID_REG(card, ALI_EBUF1));
                outl(ALI_EMOD_Still, TRID_REG(card, ALI_EBUF2));
        }
@@ -677,6 +779,7 @@ static int trident_write_voice_regs(struct trident_state *state)
                data[3] = 0;
                break;  
        case PCI_DEVICE_ID_SI_7018:
+       case PCI_DEVICE_ID_INTERG_5050:
                data[0] = 0; /* Current Sample Offset */
                data[2] = (channel->eso << 16) | (channel->delta & 0xffff);
                data[3] = (channel->attribute << 16) | (channel->fm_vol & 0xffff);
@@ -814,7 +917,7 @@ static void trident_play_setup(struct trident_state *state)
                channel->control |= CHANNEL_STEREO;
 #ifdef DEBUG
        printk("trident: trident_play_setup, LBA = 0x%08x, "
-              "Delat = 0x%08x, ESO = 0x%08x, Control = 0x%08x\n",
+              "Delta = 0x%08x, ESO = 0x%08x, Control = 0x%08x\n",
               channel->lba, channel->delta, channel->eso, channel->control);
 #endif
        trident_write_voice_regs(state);
@@ -852,6 +955,9 @@ static void trident_rec_setup(struct trident_state *state)
                /* enable and set record channel */
                outb(0x80 | channel->num, TRID_REG(card, T4D_REC_CH));
                break;
+       case PCI_DEVICE_ID_INTERG_5050:
+               /* don't know yet, using special channel 22 in GC1(0xd4)? */
+               break;
        default:
                return;
        }
@@ -920,6 +1026,7 @@ static inline unsigned trident_get_dma_addr(struct trident_state *state)
        case PCI_DEVICE_ID_ALI_5451:
        case PCI_DEVICE_ID_SI_7018:
        case PCI_DEVICE_ID_TRIDENT_4DWAVE_DX:
+       case PCI_DEVICE_ID_INTERG_5050:
                /* 16 bits ESO, CSO for 7018 and DX */
                cso = inw(TRID_REG(state->card, CH_DX_CSO_ALPHA_FMS + 2));
                break;
@@ -1271,7 +1378,8 @@ static int drain_dac(struct trident_state *state, int nonblock)
 
                /* No matter how much data is left in the buffer, we have to wait until
                   CSO == ESO/2 or CSO == ESO when address engine interrupts */
-               if (state->card->pci_id == PCI_DEVICE_ID_ALI_5451)
+               if (state->card->pci_id == PCI_DEVICE_ID_ALI_5451 ||
+                   state->card->pci_id == PCI_DEVICE_ID_INTERG_5050)
                {       
                        diff = dmabuf->swptr - trident_get_dma_addr(state) + dmabuf->dmasize ;
                        diff = diff % (dmabuf->dmasize);
@@ -1528,6 +1636,38 @@ static void ali_queue_task(struct trident_card *card, int opt)
        ali_set_timer(card);
 }
 
+static void cyber_address_interrupt(struct trident_card *card)
+{
+       int i,irq_status;
+       struct trident_state *state;
+
+       /* Update the pointers for all channels we are running. */
+       /* FIXED: read interrupt status only once */
+       irq_status=inl(TRID_REG(card, T4D_AINT_A) );
+#ifdef DEBUG   
+       printk("cyber_address_interrupt: irq_status 0x%X\n",irq_status);
+#endif
+       for (i = 0; i < NR_HW_CH; i++) {
+               if (irq_status & ( 1 << (31 - i)) ) {
+
+                       /* clear bit by writing a 1, zeroes are ignored */              
+                       outl( (1 <<(31-i)), TRID_REG(card, T4D_AINT_A));
+               
+#ifdef DEBUG   
+       printk("cyber_interrupt: channel %d\n", 31-i);
+#endif
+                       if ((state = card->states[i]) != NULL) {
+                               trident_update_ptr(state);
+                       } else {
+                               printk("cyber5050: spurious channel irq %d.\n",
+                                      31 - i);
+                               trident_stop_voice(card, 31 - i);
+                               trident_disable_voice_irq(card, 31 - i);
+                       }
+               }
+       }
+}
+
 static void trident_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
        struct trident_card *card = (struct trident_card *)dev_id;
@@ -2537,6 +2677,11 @@ static int trident_release(struct inode *inode, struct file *file)
                drain_dac(state, file->f_flags & O_NONBLOCK);
        }
 
+#ifdef DEBUG
+       printk(KERN_ERR "trident: closing virtual channel %d, hard channel %d\n", 
+               state->virt, dmabuf->channel->num);
+#endif
+
        /* stop DMA state machine and free DMA buffers/channels */
        down(&card->open_sem);
 
@@ -2626,6 +2771,12 @@ static void trident_ac97_set(struct ac97_codec *codec, u8 reg, u16 val)
                        mask |= NX_AC97_WRITE_SECONDARY;
                busy = NX_AC97_BUSY_WRITE;
                break;
+       case PCI_DEVICE_ID_INTERG_5050:
+               address = SI_AC97_WRITE;
+               mask = busy = SI_AC97_BUSY_WRITE;
+               if (codec->id)
+                       mask |= SI_AC97_SECONDARY;
+               break;
        }
 
        spin_lock_irqsave(&card->lock, flags);
@@ -2678,6 +2829,12 @@ static u16 trident_ac97_get(struct ac97_codec *codec, u8 reg)
                mask = NX_AC97_BUSY_READ;
                busy = NX_AC97_BUSY_READ | NX_AC97_BUSY_DATA;
                break;
+       case PCI_DEVICE_ID_INTERG_5050:
+               address = SI_AC97_READ;
+               mask = busy = SI_AC97_BUSY_READ;
+               if (codec->id)
+                       mask |= SI_AC97_SECONDARY;
+               break;
        }
 
        data = (mask | (reg & AC97_REG_ADDR));
@@ -3707,6 +3864,18 @@ static int __init trident_ac97_init(struct trident_card *card)
                ready_2nd = inl(TRID_REG(card, NX_ACR0_AC97_COM_STAT));
                ready_2nd &= NX_AC97_SECONDARY_READY;
                break;
+       case PCI_DEVICE_ID_INTERG_5050:
+               /* disable AC97 GPIO interrupt */
+               outl(0x00, TRID_REG(card, SI_AC97_GPIO));
+               /* when power up, the AC link is in cold reset mode, so stop it */
+               outl(PCMOUT|SURROUT|CENTEROUT|LFEOUT,
+                    TRID_REG(card, SI_SERIAL_INTF_CTRL));
+               /* it take a long time to recover from a cold reset (especially when you have
+                  more than one codec) */
+               udelay(2000);
+               ready_2nd = inl(TRID_REG(card, SI_SERIAL_INTF_CTRL));
+               ready_2nd &= SI_AC97_SECONDARY_READY;
+               break;
        }
 
        for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) {
@@ -3769,7 +3938,7 @@ static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device
        struct pci_dev *pci_dev_m1533 = NULL;
 
        if (pci_enable_device(pci_dev))
-           return -ENODEV;
+               return -ENODEV;
 
        if (pci_set_dma_mask(pci_dev, TRIDENT_DMA_MASK)) {
                printk(KERN_ERR "trident: architecture does not support"
@@ -3778,7 +3947,11 @@ static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device
        }
        pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &revision);
 
-       iobase = pci_resource_start(pci_dev, 0);
+       if (pci_id->device == PCI_DEVICE_ID_INTERG_5050)
+               iobase = pci_resource_start(pci_dev, 1);
+       else
+               iobase = pci_resource_start(pci_dev, 0);
+
        if (check_region(iobase, 256)) {
                printk(KERN_ERR "trident: can't allocate I/O space at 0x%4.4lx\n",
                       iobase);
@@ -3855,7 +4028,16 @@ static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device
                        pci_write_config_byte(pci_dev_m1533, 0x7b, bits);
                }
        }
-       else {
+       else if(card->pci_id == PCI_DEVICE_ID_INTERG_5050)
+       {
+               card->alloc_pcm_channel = cyber_alloc_pcm_channel;
+               card->alloc_rec_pcm_channel = cyber_alloc_pcm_channel;
+               card->free_pcm_channel = cyber_free_pcm_channel;
+               card->address_interrupt = cyber_address_interrupt;
+               cyber_init_ritual(card);
+       }
+       else
+       {
                card->alloc_pcm_channel = trident_alloc_pcm_channel;
                card->alloc_rec_pcm_channel = trident_alloc_pcm_channel;
                card->free_pcm_channel = trident_free_pcm_channel;
@@ -3982,7 +4164,7 @@ static void __exit trident_remove(struct pci_dev *pci_dev)
 }
 
 MODULE_AUTHOR("Alan Cox, Aaron Holtzman, Ollie Lho, Ching Ling Lee");
-MODULE_DESCRIPTION("Trident 4DWave/SiS 7018/ALi 5451 PCI Audio Driver");
+MODULE_DESCRIPTION("Trident 4DWave/SiS 7018/ALi 5451 and Tvia/IGST CyberPro5050 PCI Audio Driver");
 
 #define TRIDENT_MODULE_NAME "trident"
 
@@ -4000,7 +4182,7 @@ static int __init trident_init_module (void)
        if (!pci_present())   /* No PCI bus in this machine! */
                return -ENODEV;
 
-       printk(KERN_INFO "Trident 4DWave/SiS 7018/ALi 5451 PCI Audio, version "
+       printk(KERN_INFO "Trident 4DWave/SiS 7018/ALi 5451,Tvia CyberPro 5050 PCI Audio, version "
               DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
 
        if (!pci_register_driver(&trident_pci_driver)) {
index b3b6724d327bd639459fad63926e12c22694fb8a..656cc7cfd2e96e7f0d507bb6f5a8b1515a2b9a70 100644 (file)
@@ -315,12 +315,19 @@ enum miscint_bits {
 
 #define TRID_REG( trident, x ) ( (trident) -> iobase + (x) )
 
+#define                CYBER_PORT_AUDIO                0x3CE
+#define                CYBER_IDX_AUDIO_ENABLE          0x7B
+#define                CYBER_BMSK_AUDIO_INT_ENABLE     0x09
+#define                CYBER_BMSK_AUENZ                0x01
+#define                CYBER_BMSK_AUENZ_ENABLE         0x00
+#define                CYBER_IDX_IRQ_ENABLE            0x12
+      
 #define VALIDATE_MAGIC(FOO,MAG)                                \
-({                                               \
-       if (!(FOO) || (FOO)->magic != MAG) { \
-               printk(invalid_magic,__FUNCTION__);            \
-               return -ENXIO;                    \
-       }                                         \
+({                                                     \
+       if (!(FOO) || (FOO)->magic != MAG) {            \
+               printk(invalid_magic,__FUNCTION__);     \
+               return -ENXIO;                          \
+       }                                               \
 })
 
 #define VALIDATE_STATE(a) VALIDATE_MAGIC(a,TRIDENT_STATE_MAGIC)
index 29b81b13945b078b237c1036cebc7e3c6afbd835..cf8f040ee493acb4b3de19355d34d8683933e250 100644 (file)
 
 #define VIA_MIN_FRAG_NUMBER            2       
 
-#ifndef AC97_PCM_LR_ADC_RATE
-#  define AC97_PCM_LR_ADC_RATE AC97_PCM_LR_DAC_RATE
-#endif
-
 /* 82C686 function 5 (audio codec) PCI configuration registers */
 #define VIA_ACLINK_CTRL                0x41
 #define VIA_FUNC_ENABLE                0x42
index 84b18c818955ec2e539ce59065d898c8df0cd8cc..d13601df6dc5ceed4471acef3b7558b1fad2e8a1 100644 (file)
@@ -6,4 +6,5 @@ comment 'Telephony Support'
 
 tristate 'Linux telephony support' CONFIG_PHONE
 dep_tristate 'QuickNet Internet LineJack/PhoneJack support' CONFIG_PHONE_IXJ $CONFIG_PHONE
+dep_tristate 'QuickNet Internet LineJack/PhoneJack PCMCIA support' CONFIG_PHONE_IXJ_PCMCIA $CONFIG_PHONE_IXJ
 endmenu
index 30cff4ad4c9bb66bd55ce7089ac8a60872f0401f..e8375c96fc606f8f4cb197ff626921fb5a1b79e0 100644 (file)
@@ -10,10 +10,11 @@ obj-y   :=
 obj-n   :=
 obj-m   :=
 obj-    :=
-export-objs := phonedev.o
+export-objs := phonedev.o ixj.o
 
 obj-$(CONFIG_PHONE) += phonedev.o
 obj-$(CONFIG_PHONE_IXJ) += ixj.o
+obj-$(CONFIG_PHONE_IXJ_PCMCIA) += ixj_pcmcia.o
 
 O_TARGET := telephony.o
 
diff --git a/drivers/telephony/ixj-ver.h b/drivers/telephony/ixj-ver.h
new file mode 100644 (file)
index 0000000..2031ac6
--- /dev/null
@@ -0,0 +1,4 @@
+/* configuration management identifiers */
+#define IXJ_VER_MAJOR 1
+#define IXJ_VER_MINOR 0
+#define IXJ_BLD_VER   1
index 1089b94088178a7a4ccfb64e24225fa52776fcf4..f118838131d06e77a935a2f0801b444bf2ed3a5d 100644 (file)
@@ -1,10 +1,12 @@
 /****************************************************************************
  *    ixj.c
  *
- *    Device Driver for the Internet PhoneJACK and
- *    Internet LineJACK Telephony Cards.
+ * Device Driver for Quicknet Technologies, Inc.'s Telephony cards
+ * including the Internet PhoneJACK, Internet PhoneJACK Lite,
+ * Internet PhoneJACK PCI, Internet LineJACK, Internet PhoneCARD and
+ * SmartCABLE
  *
- *    (c) Copyright 1999-2000  Quicknet Technologies, Inc.
+ *    (c) Copyright 1999-2001  Quicknet Technologies, Inc.
  *
  *    This program is free software; you can redistribute it and/or
  *    modify it under the terms of the GNU General Public License
  *                  John Sellers, <jsellers@quicknet.net>
  *                  Mike Preston, <mpreston@quicknet.net>
  *    
- * Fixes:
- *                  Marc Boucher, <marc@mbsi.ca>
- *                 David Huggins-Daines <dhd@cepstral.com>
- * 
+ * Fixes:           David Huggins-Daines, <dhd@cepstral.com>
+ *                  Fabio Ferrari, <fabio.ferrari@digitro.com.br>
+ *                  Artis Kugevics, <artis@mt.lv>
+ *
  * More information about the hardware related to this driver can be found  
  * at our website:    http://www.quicknet.net
  *
  * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR
  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET
- * TECHNOLOGIES, INC.HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * TECHNOLOGIES, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *    
  * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  *
  ***************************************************************************/
 
-static char ixj_c_rcsid[] = "$Id: ixj.c,v 3.31 2000/04/14 19:24:47 jaugenst Exp $";
-static char ixj_c_revision[] = "$Revision: 3.31 $";
+static char ixj_c_rcsid[] = "$Id: ixj.c,v 4.7 2001/08/13 06:19:33 craigs Exp $";
+static char ixj_c_revision[] = "$Revision: 4.7 $";
+
+/*
+ * $Log: ixj.c,v $
+ * Revision 4.7  2001/08/13 06:19:33  craigs
+ * Added additional changes from Alan Cox and John Anderson for
+ * 2.2 to 2.4 cleanup and bounds checking
+ *
+ * Revision 4.6  2001/08/13 01:05:05  craigs
+ * Really fixed PHONE_QUERY_CODEC problem this time
+ *
+ * Revision 4.5  2001/08/13 00:11:03  craigs
+ * Fixed problem in handling of PHONE_QUERY_CODEC, thanks to Shane Anderson
+ *
+ * Revision 4.4  2001/08/07 07:58:12  craigs
+ * Changed back to three digit version numbers
+ * Added tagbuild target to allow automatic and easy tagging of versions
+ *
+ * Revision 4.3  2001/08/07 07:24:47  craigs
+ * Added ixj-ver.h to allow easy configuration management of driver
+ * Added display of version number in /prox/ixj
+ *
+ * Revision 4.2  2001/08/06 07:07:19  craigs
+ * Reverted IXJCTL_DSP_TYPE and IXJCTL_DSP_VERSION files to original
+ * behaviour of returning int rather than short *
+ *
+ * Revision 4.1  2001/08/05 00:17:37  craigs
+ * More changes for correct PCMCIA installation
+ * Start of changes for backward Linux compatibility
+ *
+ * Revision 4.0  2001/08/04 12:33:12  craigs
+ * New version using GNU autoconf
+ *
+ * Revision 3.105  2001/07/20 23:14:32  eokerson
+ * More work on CallerID generation when using ring cadences.
+ *
+ * Revision 3.104  2001/07/06 01:33:55  eokerson
+ * Some bugfixes from Robert Vojta <vojta@ipex.cz> and a few mods to the Makefile.
+ *
+ * Revision 3.103  2001/07/05 19:20:16  eokerson
+ * Updated HOWTO
+ * Changed mic gain to 30dB on Internet LineJACK mic/speaker port.
+ *
+ * Revision 3.102  2001/07/03 23:51:21  eokerson
+ * Un-mute mic on Internet LineJACK when in speakerphone mode.
+ *
+ * Revision 3.101  2001/07/02 19:26:56  eokerson
+ * Removed initialiazation of ixjdebug and ixj_convert_loaded so they will go in the .bss instead of the .data
+ *
+ * Revision 3.100  2001/07/02 19:18:27  eokerson
+ * Changed driver to make dynamic allocation possible.  We now pass IXJ * between functions instead of array indexes.
+ * Fixed the way the POTS and PSTN ports interact during a PSTN call to allow local answering.
+ * Fixed speaker mode on Internet LineJACK.
+ *
+ * Revision 3.99  2001/05/09 14:11:16  eokerson
+ * Fixed kmalloc error in ixj_build_filter_cadence.  Thanks David Chan <cat@waulogy.stanford.edu>.
+ *
+ * Revision 3.98  2001/05/08 19:55:33  eokerson
+ * Fixed POTS hookstate detection while it is connected to PSTN port.
+ *
+ * Revision 3.97  2001/05/08 00:01:04  eokerson
+ * Fixed kernel oops when sending caller ID data.
+ *
+ * Revision 3.96  2001/05/04 23:09:30  eokerson
+ * Now uses one kernel timer for each card, instead of one for the entire driver.
+ *
+ * Revision 3.95  2001/04/25 22:06:47  eokerson
+ * Fixed squawking at beginning of some G.723.1 calls.
+ *
+ * Revision 3.94  2001/04/03 23:42:00  eokerson
+ * Added linear volume ioctls
+ * Added raw filter load ioctl
+ *
+ * Revision 3.93  2001/02/27 01:00:06  eokerson
+ * Fixed blocking in CallerID.
+ * Reduced size of ixj structure for smaller driver footprint.
+ *
+ * Revision 3.92  2001/02/20 22:02:59  eokerson
+ * Fixed isapnp and pcmcia module compatibility for 2.4.x kernels.
+ * Improved PSTN ring detection.
+ * Fixed wink generation on POTS ports.
+ *
+ * Revision 3.91  2001/02/13 00:55:44  eokerson
+ * Turn AEC back on after changing frame sizes.
+ *
+ * Revision 3.90  2001/02/12 16:42:00  eokerson
+ * Added ALAW codec, thanks to Fabio Ferrari for the table based converters to make ALAW from ULAW.
+ *
+ * Revision 3.89  2001/02/12 15:41:16  eokerson
+ * Fix from Artis Kugevics - Tone gains were not being set correctly.
+ *
+ * Revision 3.88  2001/02/05 23:25:42  eokerson
+ * Fixed lockup bugs with deregister.
+ *
+ * Revision 3.87  2001/01/29 21:00:39  eokerson
+ * Fix from Fabio Ferrari <fabio.ferrari@digitro.com.br> to properly handle EAGAIN and EINTR during non-blocking write.
+ * Updated copyright date.
+ *
+ * Revision 3.86  2001/01/23 23:53:46  eokerson
+ * Fixes to G.729 compatibility.
+ *
+ * Revision 3.85  2001/01/23 21:30:36  eokerson
+ * Added verbage about cards supported.
+ * Removed commands that put the card in low power mode at some times that it should not be in low power mode.
+ *
+ * Revision 3.84  2001/01/22 23:32:10  eokerson
+ * Some bugfixes from David Huggins-Daines, <dhd@cepstral.com> and other cleanups.
+ *
+ * Revision 3.83  2001/01/19 14:51:41  eokerson
+ * Fixed ixj_WriteDSPCommand to decrement usage counter when command fails.
+ *
+ * Revision 3.82  2001/01/19 00:34:49  eokerson
+ * Added verbosity to write overlap errors.
+ *
+ * Revision 3.81  2001/01/18 23:56:54  eokerson
+ * Fixed PSTN line test functions.
+ *
+ * Revision 3.80  2001/01/18 22:29:27  eokerson
+ * Updated AEC/AGC values for different cards.
+ *
+ * Revision 3.79  2001/01/17 02:58:54  eokerson
+ * Fixed AEC reset after Caller ID.
+ * Fixed Codec lockup after Caller ID on Call Waiting when not using 30ms frames.
+ *
+ * Revision 3.78  2001/01/16 19:43:09  eokerson
+ * Added support for Linux 2.4.x kernels.
+ *
+ * Revision 3.77  2001/01/09 04:00:52  eokerson
+ * Linetest will now test the line, even if it has previously succeded.
+ *
+ * Revision 3.76  2001/01/08 19:27:00  eokerson
+ * Fixed problem with standard cable on Internet PhoneCARD.
+ *
+ * Revision 3.75  2000/12/22 16:52:14  eokerson
+ * Modified to allow hookstate detection on the POTS port when the PSTN port is selected.
+ *
+ * Revision 3.74  2000/12/08 22:41:50  eokerson
+ * Added capability for G729B.
+ *
+ * Revision 3.73  2000/12/07 23:35:16  eokerson
+ * Added capability to have different ring pattern before CallerID data.
+ * Added hookstate checks in CallerID routines to stop FSK.
+ *
+ * Revision 3.72  2000/12/06 19:31:31  eokerson
+ * Modified signal behavior to only send one signal per event.
+ *
+ * Revision 3.71  2000/12/06 03:23:08  eokerson
+ * Fixed CallerID on Call Waiting.
+ *
+ * Revision 3.70  2000/12/04 21:29:37  eokerson
+ * Added checking to Smart Cable gain functions.
+ *
+ * Revision 3.69  2000/12/04 21:05:20  eokerson
+ * Changed ixjdebug levels.
+ * Added ioctls to change gains in Internet Phone CARD Smart Cable.
+ *
+ * Revision 3.68  2000/12/04 00:17:21  craigs
+ * Changed mixer voice gain to +6dB rather than 0dB
+ *
+ * Revision 3.67  2000/11/30 21:25:51  eokerson
+ * Fixed write signal errors.
+ *
+ * Revision 3.66  2000/11/29 22:42:44  eokerson
+ * Fixed PSTN ring detect problems.
+ *
+ * Revision 3.65  2000/11/29 07:31:55  craigs
+ * Added new 425Hz filter co-efficients
+ * Added card-specific DTMF prescaler initialisation
+ *
+ * Revision 3.64  2000/11/28 14:03:32  craigs
+ * Changed certain mixer initialisations to be 0dB rather than 12dB
+ * Added additional information to /proc/ixj
+ *
+ * Revision 3.63  2000/11/28 11:38:41  craigs
+ * Added display of AEC modes in AUTO and AGC mode
+ *
+ * Revision 3.62  2000/11/28 04:05:44  eokerson
+ * Improved PSTN ring detection routine.
+ *
+ * Revision 3.61  2000/11/27 21:53:12  eokerson
+ * Fixed flash detection.
+ *
+ * Revision 3.60  2000/11/27 15:57:29  eokerson
+ * More work on G.729 load routines.
+ *
+ * Revision 3.59  2000/11/25 21:55:12  eokerson
+ * Fixed errors in G.729 load routine.
+ *
+ * Revision 3.58  2000/11/25 04:08:29  eokerson
+ * Added board locks around G.729 and TS85 load routines.
+ *
+ * Revision 3.57  2000/11/24 05:35:17  craigs
+ * Added ability to retrieve mixer values on LineJACK
+ * Added complete initialisation of all mixer values at startup
+ * Fixed spelling mistake
+ *
+ * Revision 3.56  2000/11/23 02:52:11  robertj
+ * Added cvs change log keyword.
+ * Fixed bug in capabilities list when using G.729 module.
+ *
+ */
+
+#include "ixj-ver.h"
 
-//#define PERFMON_STATS
+#define PERFMON_STATS
 #define IXJDEBUG 0
 #define MAXRINGS 5
 
-#include <linux/config.h>
 #include <linux/module.h>
 
 #include <linux/init.h>
@@ -68,34 +271,128 @@ static char ixj_c_revision[] = "$Revision: 3.31 $";
 #include <asm/segment.h>
 #include <asm/uaccess.h>
 
-#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
-#include <pcmcia/version.h>
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ds.h>
-#endif
-
-#ifdef CONFIG_ISAPNP
 #include <linux/isapnp.h>
-#endif
 
 #include "ixj.h"
 
 #define TYPE(dev) (MINOR(dev) >> 4)
 #define NUM(dev) (MINOR(dev) & 0xf)
 
-static int ixjdebug = 0;
+static int ixjdebug;
 static int hertz = HZ;
 static int samplerate = 100;
 
 MODULE_PARM(ixjdebug, "i");
 
-static IXJ* ixj[IXJMAX];
+/************************************************************************
+*
+* ixjdebug meanings are now bit mapped instead of level based
+* Values can be or'ed together to turn on multiple messages
+*
+* bit  0 (0x0001) = any failure
+* bit  1 (0x0002) = general messages
+* bit  2 (0x0004) = POTS ringing related
+* bit  3 (0x0008) = PSTN events
+* bit  4 (0x0010) = PSTN Cadence state details
+* bit  5 (0x0020) = Tone detection triggers
+* bit  6 (0x0040) = Tone detection cadence details
+* bit  7 (0x0080) = ioctl tracking
+* bit  8 (0x0100) = signal tracking
+* bit  9 (0x0200) = CallerID generation details
+*
+************************************************************************/
+
+#ifdef IXJ_DYN_ALLOC
+
+static IXJ *ixj[IXJMAX];
+#define        get_ixj(b)      ixj[(b)]
+
+/*
+ *     Allocate a free IXJ device
+ */
+static IXJ *ixj_alloc()
+{
+       for(cnt=0; cnt<IXJMAX; cnt++)
+       {
+               if(ixj[cnt] == NULL || !ixj[cnt]->DSPbase)
+               {
+                       j = kmalloc(sizeof(IXJ), GFP_KERNEL);
+                       if (j == NULL)
+                               return NULL;
+                       ixj[cnt] = j;
+                       return j;
+               }
+       }
+       return NULL;
+}
 
-static struct timer_list ixj_timer;
+static void ixj_fsk_free(IXJ *j)
+{
+       if(j->fskdata != NULL) {
+               kfree(j->fskdata);
+               j->fskdata = NULL;
+       }
+}
 
-int ixj_convert_loaded = 0;
+static void ixj_fsk_alloc(IXJ *j)
+{
+       if(!j->fskdata) {
+               j->fskdata = kmalloc(8000, GFP_KERNEL);
+               if (!j->fskdata) {
+                       if(ixjdebug & 0x0200) {
+                               printk("IXJ phone%d - allocate failed\n", j->board);
+                       }
+                       return;
+               } else {
+                       j->fsksize = 8000;
+                       if(ixjdebug & 0x0200) {
+                               printk("IXJ phone%d - allocate succeded\n", j->board);
+                       }
+               }
+       }
+}
+
+#else
+
+static IXJ ixj[IXJMAX];
+#define        get_ixj(b)      (&ixj[(b)])
+
+/*
+ *     Allocate a free IXJ device
+ */
+static IXJ *ixj_alloc(void)
+{
+       int cnt;
+       for(cnt=0; cnt<IXJMAX; cnt++)
+       {
+               if(!ixj[cnt].DSPbase)
+               {
+                       return &ixj[cnt];
+               }
+       }
+       return NULL;
+}
+
+static inline void ixj_fsk_free(IXJ *j) {;}
+
+static inline void ixj_fsk_alloc(IXJ *j)
+{
+       j->fsksize = 8000;
+}
+
+#endif
+
+#ifdef PERFMON_STATS
+#define ixj_perfmon(x) ((x)++)
+#else
+#deifne ixj_perfmon(x) do {} while(0);
+#endif
+
+static int ixj_convert_loaded;
+
+static int ixj_WriteDSPCommand(unsigned short, IXJ *j);
 
 /************************************************************************
 *
@@ -104,7 +401,7 @@ int ixj_convert_loaded = 0;
 *
 ************************************************************************/
 
-static int Stub(IXJ * j, unsigned long arg)
+static int Stub(IXJ * J, unsigned long arg)
 {
        return 0;
 }
@@ -120,8 +417,8 @@ static IXJ_REGFUNC ixj_PostIoctl = &Stub;
 
 static void ixj_read_frame(IXJ *j);
 static void ixj_write_frame(IXJ *j);
-static void ixj_init_timer(void);
-static void ixj_add_timer(void);
+static void ixj_init_timer(IXJ *j);
+static void ixj_add_timer(IXJ *        j);
 static void ixj_timeout(unsigned long ptr);
 static int read_filters(IXJ *j);
 static int LineMonitor(IXJ *j);
@@ -132,12 +429,15 @@ static int ixj_hookstate(IXJ *j);
 static int ixj_record_start(IXJ *j);
 static void ixj_record_stop(IXJ *j);
 static void set_rec_volume(IXJ *j, int volume);
+static int get_rec_volume(IXJ *j);
+static int set_rec_codec(IXJ *j, int rate);
 static void ixj_vad(IXJ *j, int arg);
 static int ixj_play_start(IXJ *j);
 static void ixj_play_stop(IXJ *j);
 static int ixj_set_tone_on(unsigned short arg, IXJ *j);
 static int ixj_set_tone_off(unsigned short, IXJ *j);
 static int ixj_play_tone(IXJ *j, char tone);
+static void ixj_aec_start(IXJ *j, int level);
 static int idle(IXJ *j);
 static void ixj_ring_on(IXJ *j);
 static void ixj_ring_off(IXJ *j);
@@ -147,6 +447,7 @@ static void ixj_busytone(IXJ *j);
 static void ixj_dialtone(IXJ *j);
 static void ixj_cpt_stop(IXJ *j);
 static char daa_int_read(IXJ *j);
+static char daa_CR_read(IXJ *j, int cr);
 static int daa_set_mode(IXJ *j, int mode);
 static int ixj_linetest(IXJ *j);
 static int ixj_daa_write(IXJ *j);
@@ -158,22 +459,24 @@ static void DAA_Coeff_Germany(IXJ *j);
 static void DAA_Coeff_Australia(IXJ *j);
 static void DAA_Coeff_Japan(IXJ *j);
 static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf);
+static int ixj_init_filter_raw(IXJ *j, IXJ_FILTER_RAW * jfr);
 static int ixj_init_tone(IXJ *j, IXJ_TONE * ti);
 static int ixj_build_cadence(IXJ *j, IXJ_CADENCE * cp);
 static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE * cp);
-// Serial Control Interface funtions
+/* Serial Control Interface funtions */
 static int SCI_Control(IXJ *j, int control);
 static int SCI_Prepare(IXJ *j);
 static int SCI_WaitHighSCI(IXJ *j);
 static int SCI_WaitLowSCI(IXJ *j);
 static DWORD PCIEE_GetSerialNumber(WORD wAddress);
 static int ixj_PCcontrol_wait(IXJ *j);
+static void ixj_pre_cid(IXJ *j);
 static void ixj_write_cid(IXJ *j);
 static void ixj_write_cid_bit(IXJ *j, int bit);
 static int set_base_frame(IXJ *j, int size);
 static int set_play_codec(IXJ *j, int rate);
 static void set_rec_depth(IXJ *j, int depth);
-static void set_play_depth(IXJ *j, int depth);
+static int ixj_mixer(long val, IXJ *j);
 
 /************************************************************************
 CT8020/CT8021 Host Programmers Model
@@ -186,58 +489,95 @@ DSPbase +
 8-9            Hardware Status Register                        Read Only
 A-B            Hardware Control Register                       Read Write
 C-D Host Transmit (Write) Data Buffer Access Port (buffer input)Write Only
-E-F Host Receive (Read) Data Buffer Access Port (buffer input) Read Only
+E-F Host Recieve (Read) Data Buffer Access Port (buffer input) Read Only
 ************************************************************************/
 
-extern __inline__ void ixj_read_HSR(IXJ *j)
+static inline void ixj_read_HSR(IXJ *j)
 {
        j->hsr.bytes.low = inb_p(j->DSPbase + 8);
        j->hsr.bytes.high = inb_p(j->DSPbase + 9);
 }
 
-extern __inline__ int IsControlReady(IXJ *j)
+static inline int IsControlReady(IXJ *j)
 {
        ixj_read_HSR(j);
        return j->hsr.bits.controlrdy ? 1 : 0;
 }
 
-extern __inline__ int IsPCControlReady(IXJ *j)
+static inline int IsPCControlReady(IXJ *j)
 {
        j->pccr1.byte = inb_p(j->XILINXbase + 3);
        return j->pccr1.bits.crr ? 1 : 0;
 }
 
-extern __inline__ int IsStatusReady(IXJ *j)
+static inline int IsStatusReady(IXJ *j)
 {
        ixj_read_HSR(j);
        return j->hsr.bits.statusrdy ? 1 : 0;
 }
 
-extern __inline__ int IsRxReady(IXJ *j)
+static inline int IsRxReady(IXJ *j)
 {
        ixj_read_HSR(j);
-#ifdef PERFMON_STATS
-       ++j->rxreadycheck;
-#endif
+       ixj_perfmon(j->rxreadycheck);
        return j->hsr.bits.rxrdy ? 1 : 0;
 }
 
-extern __inline__ int IsTxReady(IXJ *j)
+static inline int IsTxReady(IXJ *j)
 {
        ixj_read_HSR(j);
-#ifdef PERFMON_STATS
-       ++j->txreadycheck;
-#endif
+       ixj_perfmon(j->txreadycheck);
        return j->hsr.bits.txrdy ? 1 : 0;
 }
 
-extern __inline__ void set_play_volume(IXJ *j, int volume)
+static inline void set_play_volume(IXJ *j, int volume)
 {
+       if (ixjdebug & 0x0002)
+               printk(KERN_INFO "IXJ: /dev/phone%d Setting Play Volume to 0x%4.4x\n", j->board, volume);
        ixj_WriteDSPCommand(0xCF02, j);
        ixj_WriteDSPCommand(volume, j);
 }
 
-extern __inline__ void set_play_depth(IXJ *j, int depth)
+static int set_play_volume_linear(IXJ *j, int volume)
+{
+       int newvolume, dspplaymax;
+
+       if (ixjdebug & 0x0002)
+               printk(KERN_INFO "IXJ: /dev/phone %d Setting Linear Play Volume to 0x%4.4x\n", j->board, volume);
+       if(volume > 100 || volume < 0) {
+               return -1;
+       }
+
+       /* This should normalize the perceived volumes between the different cards caused by differences in the hardware */
+       switch (j->cardtype) {
+       case QTI_PHONEJACK:
+               dspplaymax = 0x380;
+               break;
+       case QTI_LINEJACK:
+               if(j->port == PORT_PSTN) {
+                       dspplaymax = 0x48;
+               } else {
+                       dspplaymax = 0x100;
+               }
+               break;
+       case QTI_PHONEJACK_LITE:
+               dspplaymax = 0x380;
+               break;
+       case QTI_PHONEJACK_PCI:
+               dspplaymax = 0x6C;
+               break;
+       case QTI_PHONECARD:
+               dspplaymax = 0x50;
+               break;
+       default:
+               return -1;
+       }
+       newvolume = (dspplaymax * volume) / 100;
+       set_play_volume(j, newvolume);
+       return 0;
+}
+
+static inline void set_play_depth(IXJ *j, int depth)
 {
        if (depth > 60)
                depth = 60;
@@ -246,13 +586,48 @@ extern __inline__ void set_play_depth(IXJ *j, int depth)
        ixj_WriteDSPCommand(0x5280 + depth, j);
 }
 
-extern __inline__ int get_play_volume(IXJ *j)
+static inline int get_play_volume(IXJ *j)
 {
        ixj_WriteDSPCommand(0xCF00, j);
        return j->ssr.high << 8 | j->ssr.low;
 }
 
-extern __inline__ BYTE SLIC_GetState(IXJ *j)
+static int get_play_volume_linear(IXJ *j)
+{
+       int volume, newvolume, dspplaymax;
+
+       /* This should normalize the perceived volumes between the different cards caused by differences in the hardware */
+       switch (j->cardtype) {
+       case QTI_PHONEJACK:
+               dspplaymax = 0x380;
+               break;
+       case QTI_LINEJACK:
+               if(j->port == PORT_PSTN) {
+                       dspplaymax = 0x48;
+               } else {
+                       dspplaymax = 0x100;
+               }
+               break;
+       case QTI_PHONEJACK_LITE:
+               dspplaymax = 0x380;
+               break;
+       case QTI_PHONEJACK_PCI:
+               dspplaymax = 0x6C;
+               break;
+       case QTI_PHONECARD:
+               dspplaymax = 100;
+               break;
+       default:
+               return -1;
+       }
+       volume = get_play_volume(j);
+       newvolume = (volume * 100) / dspplaymax;
+       if(newvolume > 100)
+               newvolume = 100;
+       return newvolume;
+}
+
+static inline BYTE SLIC_GetState(IXJ *j)
 {
        if (j->cardtype == QTI_PHONECARD) {
                j->pccr1.byte = 0;
@@ -295,7 +670,7 @@ static BOOL SLIC_SetState(BYTE byState, IXJ *j)
                                        fRetVal = TRUE;
                                }
                                break;
-                       case PLD_SLIC_STATE_OHT:        // On-hook transmit
+                       case PLD_SLIC_STATE_OHT:        /* On-hook transmit */
 
                        case PLD_SLIC_STATE_STANDBY:
                        case PLD_SLIC_STATE_ACTIVE:
@@ -307,9 +682,9 @@ static BOOL SLIC_SetState(BYTE byState, IXJ *j)
                                j->pslic.bits.ring0 = j->pslic.bits.ring1 = 0;
                                fRetVal = TRUE;
                                break;
-                       case PLD_SLIC_STATE_APR:        // Active polarity reversal
+                       case PLD_SLIC_STATE_APR:        /* Active polarity reversal */
 
-                       case PLD_SLIC_STATE_OHTPR:      // OHT polarity reversal
+                       case PLD_SLIC_STATE_OHTPR:      /* OHT polarity reversal */
 
                        default:
                                fRetVal = FALSE;
@@ -321,7 +696,7 @@ static BOOL SLIC_SetState(BYTE byState, IXJ *j)
                        ixj_PCcontrol_wait(j);
                }
        } else {
-               // Set the C1, C2, C3 & B2EN signals.
+               /* Set the C1, C2, C3 & B2EN signals. */
                switch (byState) {
                case PLD_SLIC_STATE_OC:
                        j->pld_slicw.bits.c1 = 0;
@@ -347,7 +722,7 @@ static BOOL SLIC_SetState(BYTE byState, IXJ *j)
                        outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
                        fRetVal = TRUE;
                        break;
-               case PLD_SLIC_STATE_OHT:        // On-hook transmit
+               case PLD_SLIC_STATE_OHT:        /* On-hook transmit */
 
                        j->pld_slicw.bits.c1 = 1;
                        j->pld_slicw.bits.c2 = 1;
@@ -372,7 +747,7 @@ static BOOL SLIC_SetState(BYTE byState, IXJ *j)
                        outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
                        fRetVal = TRUE;
                        break;
-               case PLD_SLIC_STATE_APR:        // Active polarity reversal
+               case PLD_SLIC_STATE_APR:        /* Active polarity reversal */
 
                        j->pld_slicw.bits.c1 = 0;
                        j->pld_slicw.bits.c2 = 1;
@@ -381,7 +756,7 @@ static BOOL SLIC_SetState(BYTE byState, IXJ *j)
                        outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
                        fRetVal = TRUE;
                        break;
-               case PLD_SLIC_STATE_OHTPR:      // OHT polarity reversal
+               case PLD_SLIC_STATE_OHTPR:      /* OHT polarity reversal */
 
                        j->pld_slicw.bits.c1 = 1;
                        j->pld_slicw.bits.c2 = 1;
@@ -399,22 +774,52 @@ static BOOL SLIC_SetState(BYTE byState, IXJ *j)
        return fRetVal;
 }
 
-int ixj_register(int index, IXJ_REGFUNC regfunc)
+static int ixj_wink(IXJ *j)
+{
+       BYTE slicnow;
+
+       slicnow = SLIC_GetState(j);
+
+       j->pots_winkstart = jiffies;
+       SLIC_SetState(PLD_SLIC_STATE_OC, j);
+
+       while (time_before(jiffies, j->pots_winkstart + j->winktime)) {
+               set_current_state(TASK_INTERRUPTIBLE);
+               schedule_timeout(1);
+       }
+
+       SLIC_SetState(slicnow, j);
+       return 0;
+}
+
+static int ixj_register(int index, IXJ_REGFUNC regfunc)
 {
        int cnt;
        int retval = 0;
        switch (index) {
        case G729LOADER:
                ixj_DownloadG729 = regfunc;
-               for (cnt = 0; cnt < IXJMAX; cnt++)
-                       if (ixj[cnt] != NULL)
-                               ixj_DownloadG729(ixj[cnt], 0L);
+               for (cnt = 0; cnt < IXJMAX; cnt++) {
+                       IXJ *j = get_ixj(cnt);
+                       while(test_and_set_bit(cnt, (void *)&j->busyflags) != 0) {
+                               set_current_state(TASK_INTERRUPTIBLE);
+                               schedule_timeout(1);
+                       }
+                       ixj_DownloadG729(j, 0L);
+                       clear_bit(cnt, &j->busyflags);
+               }
                break;
        case TS85LOADER:
                ixj_DownloadTS85 = regfunc;
-               for (cnt = 0; cnt < IXJMAX; cnt++)
-                       if (ixj[cnt] != NULL)
-                               ixj_DownloadTS85(ixj[cnt], 0L);
+               for (cnt = 0; cnt < IXJMAX; cnt++) {
+                       IXJ *j = get_ixj(cnt);
+                       while(test_and_set_bit(cnt, (void *)&j->busyflags) != 0) {
+                               set_current_state(TASK_INTERRUPTIBLE);
+                               schedule_timeout(1);
+                       }
+                       ixj_DownloadTS85(j, 0L);
+                       clear_bit(cnt, &j->busyflags);
+               }
                break;
        case PRE_READ:
                ixj_PreRead = regfunc;
@@ -440,7 +845,9 @@ int ixj_register(int index, IXJ_REGFUNC regfunc)
        return retval;
 }
 
-int ixj_unregister(int index)
+EXPORT_SYMBOL(ixj_register);
+
+static int ixj_unregister(int index)
 {
        int retval = 0;
        switch (index) {
@@ -474,17 +881,19 @@ int ixj_unregister(int index)
        return retval;
 }
 
-static void ixj_init_timer(void)
+EXPORT_SYMBOL(ixj_unregister);
+
+static void ixj_init_timer(IXJ *j)
 {
-       init_timer(&ixj_timer);
-       ixj_timer.function = ixj_timeout;
-       ixj_timer.data = (int) NULL;
+       init_timer(&j->timer);
+       j->timer.function = ixj_timeout;
+       j->timer.data = (unsigned long)j;
 }
 
-static void ixj_add_timer(void)
+static void ixj_add_timer(IXJ *j)
 {
-       ixj_timer.expires = jiffies + (hertz / samplerate);
-       add_timer(&ixj_timer);
+       j->timer.expires = jiffies + (hertz / samplerate);
+       add_timer(&j->timer);
 }
 
 static void ixj_tone_timeout(IXJ *j)
@@ -537,268 +946,573 @@ static void ixj_tone_timeout(IXJ *j)
        }
 }
 
-extern __inline__ void ixj_kill_fasync(IXJ *j, int band)
+static inline void ixj_kill_fasync(IXJ *j, IXJ_SIGEVENT event, int dir)
 {
-       kill_fasync(&j->async_queue, SIGIO, band);
+       if(j->ixj_signals[event]) {
+               if(ixjdebug & 0x0100)
+                       printk("Sending signal for event %d\n", event);
+                       /* Send apps notice of change */
+               /* see config.h for macro definition */
+               kill_fasync(&(j->async_queue), j->ixj_signals[event], dir);
+       }
 }
 
-static void ixj_timeout(unsigned long ptr)
+static void ixj_pstn_state(IXJ *j)
 {
-       int board;
-       unsigned long jifon;
+       int var;
+       union XOPXR0 XR0, daaint;
 
-       for (board = 0; board < IXJMAX; board++) {
-               IXJ *j = ixj[board];
+       var = 10;
 
-               if (j == NULL)
-                       continue;
+       XR0.reg = j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg;
+       daaint.reg = 0;
+       XR0.bitreg.RMR = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR;
 
-               if (j->DSPbase) {
-#ifdef PERFMON_STATS
-                       j->timerchecks++;
-#endif
-                       if (j->tone_state) {
-                               if (!ixj_hookstate(j)) {
-                                       ixj_cpt_stop(j);
-                                       if (j->m_hook) {
-                                               j->m_hook = 0;
-                                               j->ex.bits.hookstate = 1;
-                                               ixj_kill_fasync(j, POLL_PRI);
+       j->pld_scrr.byte = inb_p(j->XILINXbase);
+       if (j->pld_scrr.bits.daaflag) {
+               daa_int_read(j);
+               if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.RING) {
+                       if(time_after(jiffies, j->pstn_sleeptil) && !(j->flags.pots_pstn && j->hookstate)) {
+                               daaint.bitreg.RING = 1;
+                               if(ixjdebug & 0x0008) {
+                                       printk(KERN_INFO "IXJ DAA Ring Interrupt /dev/phone%d at %ld\n", j->board, jiffies);
+                               }
+                       } else {
+                               daa_set_mode(j, SOP_PU_RESET);
+                       }
+               }
+               if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Caller_ID) {
+                       daaint.bitreg.Caller_ID = 1;
+                       j->pstn_cid_intr = 1;
+                       j->pstn_cid_received = jiffies;
+                       if(ixjdebug & 0x0008) {
+                               printk(KERN_INFO "IXJ DAA Caller_ID Interrupt /dev/phone%d at %ld\n", j->board, jiffies);
+                       }
+               }
+               if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Cadence) {
+                       daaint.bitreg.Cadence = 1;
+                       if(ixjdebug & 0x0008) {
+                               printk(KERN_INFO "IXJ DAA Cadence Interrupt /dev/phone%d at %ld\n", j->board, jiffies);
+                       }
+               }
+               if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK != XR0.bitreg.VDD_OK) {
+                       daaint.bitreg.VDD_OK = 1;
+                       daaint.bitreg.SI_0 = j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK;
+               }
+       }
+       daa_CR_read(j, 1);
+       if(j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR != XR0.bitreg.RMR && time_after(jiffies, j->pstn_sleeptil) && !(j->flags.pots_pstn && j->hookstate)) {
+               daaint.bitreg.RMR = 1;
+               daaint.bitreg.SI_1 = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR;
+               if(ixjdebug & 0x0008) {
+                        printk(KERN_INFO "IXJ DAA RMR /dev/phone%d was %s for %ld\n", j->board, XR0.bitreg.RMR?"on":"off", jiffies - j->pstn_last_rmr);
+               }
+               j->pstn_prev_rmr = j->pstn_last_rmr;
+               j->pstn_last_rmr = jiffies;
+       }
+       switch(j->daa_mode) {
+               case SOP_PU_SLEEP:
+                       if (daaint.bitreg.RING) {
+                               if (!j->flags.pstn_ringing) {
+                                       if (j->daa_mode != SOP_PU_RINGING) {
+                                               j->pstn_ring_int = jiffies;
+                                               daa_set_mode(j, SOP_PU_RINGING);
                                        }
-                                       continue;
                                }
-                               if (j->tone_state == 1)
-                                       jifon = (hertz * j->tone_on_time * 25 / 100000);
-                               else
-                                       jifon = (hertz * j->tone_on_time * 25 / 100000) +
-                                           (hertz * j->tone_off_time * 25 / 100000);
-                               if (time_before(jiffies, j->tone_start_jif + jifon)) {
-                                       if (j->tone_state == 1) {
-                                               ixj_play_tone(j, j->tone_index);
-                                               if (j->dsp.low == 0x20) {
-                                                       continue;
+                       }
+                       break;
+               case SOP_PU_RINGING:
+                       if (daaint.bitreg.RMR) {
+                               if (ixjdebug & 0x0008) {
+                                       printk(KERN_INFO "IXJ Ring Cadence a state = %d /dev/phone%d at %ld\n", j->cadence_f[4].state, j->board, jiffies);
+                               }
+                               if (daaint.bitreg.SI_1) {                /* Rising edge of RMR */
+                                       j->flags.pstn_rmr = 1;
+                                       j->pstn_ring_start = jiffies;
+                                       j->pstn_ring_stop = 0;
+                                       j->ex.bits.pstn_ring = 0;
+                                       if (j->cadence_f[4].state == 0) {
+                                               j->cadence_f[4].state = 1;
+                                               j->cadence_f[4].on1min = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100 - var)) / 10000);
+                                               j->cadence_f[4].on1dot = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100)) / 10000);
+                                               j->cadence_f[4].on1max = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100 + var)) / 10000);
+                                       } else if (j->cadence_f[4].state == 2) {
+                                               if((time_after(jiffies, j->cadence_f[4].off1min) &&
+                                                   time_before(jiffies, j->cadence_f[4].off1max))) {
+                                                       if (j->cadence_f[4].on2) {
+                                                               j->cadence_f[4].state = 3;
+                                                               j->cadence_f[4].on2min = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100 - var)) / 10000));
+                                                               j->cadence_f[4].on2dot = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100)) / 10000));
+                                                               j->cadence_f[4].on2max = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100 + var)) / 10000));
+                                                       } else {
+                                                               j->cadence_f[4].state = 7;
+                                                       }
+                                               } else {
+                                                       if (ixjdebug & 0x0008) {
+                                                               printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
+                                                                               j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
+                                                                               j->cadence_f[4].off1);
+                                                       }
+                                                       j->cadence_f[4].state = 0;
                                                }
-                                       } else {
-                                               ixj_play_tone(j, 0);
-                                               if (j->dsp.low == 0x20) {
-                                                       continue;
+                                       } else if (j->cadence_f[4].state == 4) {
+                                               if((time_after(jiffies, j->cadence_f[4].off2min) &&
+                                                   time_before(jiffies, j->cadence_f[4].off2max))) {
+                                                       if (j->cadence_f[4].on3) {
+                                                               j->cadence_f[4].state = 5;
+                                                               j->cadence_f[4].on3min = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100 - var)) / 10000));
+                                                               j->cadence_f[4].on3dot = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100)) / 10000));
+                                                               j->cadence_f[4].on3max = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100 + var)) / 10000));
+                                                       } else {
+                                                               j->cadence_f[4].state = 7;
+                                                       }
+                                               } else {
+                                                       if (ixjdebug & 0x0008) {
+                                                               printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
+                                                                               j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
+                                                                               j->cadence_f[4].off2);
+                                                       }
+                                                       j->cadence_f[4].state = 0;
                                                }
-                                       }
-                               } else {
-                                       ixj_tone_timeout(j);
-                                       if (j->flags.dialtone) {
-                                               ixj_dialtone(j);
-                                       }
-                                       if (j->flags.busytone) {
-                                               ixj_busytone(j);
-                                               if (j->dsp.low == 0x20) {
-                                                       continue;
+                                       } else if (j->cadence_f[4].state == 6) {
+                                               if((time_after(jiffies, j->cadence_f[4].off3min) &&
+                                                   time_before(jiffies, j->cadence_f[4].off3max))) {
+                                                       j->cadence_f[4].state = 7;
+                                               } else {
+                                                       if (ixjdebug & 0x0008) {
+                                                               printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
+                                                                               j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
+                                                                               j->cadence_f[4].off3);
+                                                       }
+                                                       j->cadence_f[4].state = 0;
                                                }
+                                       } else {
+                                               j->cadence_f[4].state = 0;
                                        }
-                                       if (j->flags.ringback) {
-                                               ixj_ringback(j);
-                                               if (j->dsp.low == 0x20) {
-                                                       continue;
+                               } else {                                /* Falling edge of RMR */
+                                       j->pstn_ring_start = 0;
+                                       j->pstn_ring_stop = jiffies;
+                                       if (j->cadence_f[4].state == 1) {
+                                               if(!j->cadence_f[4].on1) {
+                                                       j->cadence_f[4].state = 7;
+                                               } else if((time_after(jiffies, j->cadence_f[4].on1min) &&
+                                                 time_before(jiffies, j->cadence_f[4].on1max))) {
+                                                       if (j->cadence_f[4].off1) {
+                                                               j->cadence_f[4].state = 2;
+                                                               j->cadence_f[4].off1min = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100 - var)) / 10000));
+                                                               j->cadence_f[4].off1dot = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100)) / 10000));
+                                                               j->cadence_f[4].off1max = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100 + var)) / 10000));
+                                                       } else {
+                                                               j->cadence_f[4].state = 7;
+                                                       }
+                                               } else {
+                                                       if (ixjdebug & 0x0008) {
+                                                               printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
+                                                                               j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
+                                                                               j->cadence_f[4].on1);
+                                                       }
+                                                       j->cadence_f[4].state = 0;
+                                               }
+                                       } else if (j->cadence_f[4].state == 3) {
+                                               if((time_after(jiffies, j->cadence_f[4].on2min) &&
+                                                   time_before(jiffies, j->cadence_f[4].on2max))) {
+                                                       if (j->cadence_f[4].off2) {
+                                                               j->cadence_f[4].state = 4;
+                                                               j->cadence_f[4].off2min = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100 - var)) / 10000));
+                                                               j->cadence_f[4].off2dot = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100)) / 10000));
+                                                               j->cadence_f[4].off2max = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100 + var)) / 10000));
+                                                       } else {
+                                                               j->cadence_f[4].state = 7;
+                                                       }
+                                               } else {
+                                                       if (ixjdebug & 0x0008) {
+                                                               printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
+                                                                               j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
+                                                                               j->cadence_f[4].on2);
+                                                       }
+                                                       j->cadence_f[4].state = 0;
+                                               }
+                                       } else if (j->cadence_f[4].state == 5) {
+                                               if((time_after(jiffies, j->cadence_f[4].on3min) &&
+                                                   time_before(jiffies, j->cadence_f[4].on3max))) {
+                                                       if (j->cadence_f[4].off3) {
+                                                               j->cadence_f[4].state = 6;
+                                                               j->cadence_f[4].off3min = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100 - var)) / 10000));
+                                                               j->cadence_f[4].off3dot = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100)) / 10000));
+                                                               j->cadence_f[4].off3max = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100 + var)) / 10000));
+                                                       } else {
+                                                               j->cadence_f[4].state = 7;
+                                                       }
+                                               } else {
+                                                       j->cadence_f[4].state = 0;
                                                }
+                                       } else {
+                                               if (ixjdebug & 0x0008) {
+                                                       printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
+                                                                       j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
+                                                                       j->cadence_f[4].on3);
+                                               }
+                                               j->cadence_f[4].state = 0;
                                        }
-                                       if (!j->tone_state) {
-                                               if (j->dsp.low == 0x20 || (j->play_mode == -1 && j->rec_mode == -1))
-                                                       idle(j);
-                                               if (j->dsp.low == 0x20 && j->play_mode != -1)
-                                                       ixj_play_start(j);
-                                               if (j->dsp.low == 0x20 && j->rec_mode != -1)
-                                                       ixj_record_start(j);
+                               }
+                               if (ixjdebug & 0x0010) {
+                                       printk(KERN_INFO "IXJ Ring Cadence b state = %d /dev/phone%d at %ld\n", j->cadence_f[4].state, j->board, jiffies);
+                               }
+                               if (ixjdebug & 0x0010) {
+                                       switch(j->cadence_f[4].state) {
+                                               case 1:
+                                                       printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
+                                               j->cadence_f[4].on1, j->cadence_f[4].on1min, j->cadence_f[4].on1dot, j->cadence_f[4].on1max);
+                                                       break;
+                                               case 2:
+                                                       printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
+                                               j->cadence_f[4].off1, j->cadence_f[4].off1min, j->cadence_f[4].off1dot, j->cadence_f[4].off1max);
+                                                       break;
+                                               case 3:
+                                                       printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
+                                               j->cadence_f[4].on2, j->cadence_f[4].on2min, j->cadence_f[4].on2dot, j->cadence_f[4].on2max);
+                                                       break;
+                                               case 4:
+                                                       printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
+                                               j->cadence_f[4].off2, j->cadence_f[4].off2min, j->cadence_f[4].off2dot, j->cadence_f[4].off2max);
+                                                       break;
+                                               case 5:
+                                                       printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
+                                               j->cadence_f[4].on3, j->cadence_f[4].on3min, j->cadence_f[4].on3dot, j->cadence_f[4].on3max);
+                                                       break;
+                                               case 6: 
+                                                       printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
+                                               j->cadence_f[4].off3, j->cadence_f[4].off3min, j->cadence_f[4].off3dot, j->cadence_f[4].off3max);
+                                                       break;
                                        }
                                }
                        }
-                       if (!(j->tone_state && j->dsp.low == 0x20)) {
-                               if (IsRxReady(j)) {
-                                       ixj_read_frame(j);
+                       if (j->cadence_f[4].state == 7) {
+                               j->cadence_f[4].state = 0;
+                               j->pstn_ring_stop = jiffies;
+                               j->ex.bits.pstn_ring = 1;
+                               ixj_kill_fasync(j, SIG_PSTN_RING, POLL_IN);
+                               if(ixjdebug & 0x0008) {
+                                       printk(KERN_INFO "IXJ Ring int set /dev/phone%d at %ld\n", j->board, jiffies);
                                }
-                               if (IsTxReady(j) && !j->flags.cidplay) {
-                                       ixj_write_frame(j);
+                       }
+                       if((j->pstn_ring_int != 0 && time_after(jiffies, j->pstn_ring_int + (hertz * 5)) && !j->flags.pstn_rmr) ||
+                          (j->pstn_ring_stop != 0 && time_after(jiffies, j->pstn_ring_stop + (hertz * 5)))) {
+                               if(ixjdebug & 0x0008) {
+                                       printk("IXJ DAA no ring in 5 seconds /dev/phone%d at %ld\n", j->board, jiffies);
+                                       printk("IXJ DAA pstn ring int /dev/phone%d at %ld\n", j->board, j->pstn_ring_int);
+                                       printk("IXJ DAA pstn ring stop /dev/phone%d at %ld\n", j->board, j->pstn_ring_stop);
                                }
+                               j->pstn_ring_stop = j->pstn_ring_int = 0;
+                               daa_set_mode(j, SOP_PU_SLEEP);
+                       } 
+                       outb_p(j->pld_scrw.byte, j->XILINXbase);
+                       if (j->pstn_cid_intr && time_after(jiffies, j->pstn_cid_received + hertz)) {
+                               ixj_daa_cid_read(j);
+                               j->ex.bits.caller_id = 1;
+                               ixj_kill_fasync(j, SIG_CALLER_ID, POLL_IN);
+                               j->pstn_cid_intr = 0;
                        }
-                       if (j->flags.cringing) {
-                               if (ixj_hookstate(j) & 1) {
-                                       j->flags.cringing = 0;
-                                       ixj_ring_off(j);
+                       if (daaint.bitreg.Cadence) {
+                               if(ixjdebug & 0x0008) {
+                                       printk("IXJ DAA Cadence interrupt going to sleep /dev/phone%d\n", j->board);
+                               }
+                               daa_set_mode(j, SOP_PU_SLEEP);
+                               j->ex.bits.pstn_ring = 0;
+                       }
+                       break;
+               case SOP_PU_CONVERSATION:
+                       if (daaint.bitreg.VDD_OK) {
+                               if(!daaint.bitreg.SI_0) {
+                                       if (!j->pstn_winkstart) {
+                                               if(ixjdebug & 0x0008) {
+                                                       printk("IXJ DAA possible wink /dev/phone%d %ld\n", j->board, jiffies);
+                                               }
+                                               j->pstn_winkstart = jiffies;
+                                       } 
                                } else {
-                                       if (jiffies - j->ring_cadence_jif >= (hertz/2)) {
-                                               if (j->flags.cidring && !j->flags.cidsent) {
-                                                       j->flags.cidsent = 1;
-                                                       ixj_write_cid(j);
-                                                       j->flags.cidring = 0;
+                                       if (j->pstn_winkstart) {
+                                               if(ixjdebug & 0x0008) {
+                                                       printk("IXJ DAA possible wink end /dev/phone%d %ld\n", j->board, jiffies);
                                                }
-                                               j->ring_cadence_t--;
-                                               if (j->ring_cadence_t == -1)
-                                                       j->ring_cadence_t = 15;
-                                               j->ring_cadence_jif = jiffies;
-                                       }
-                                       if (j->ring_cadence & 1 << j->ring_cadence_t) {
-                                               ixj_ring_on(j);
-                                       } else {
-                                               ixj_ring_off(j);
-                                               j->flags.cidring = 1;
+                                               j->pstn_winkstart = 0;
                                        }
-                                       continue;
                                }
                        }
-                       if (!j->flags.ringing) {
-                               if (ixj_hookstate(j)) {
-                                       if (j->dsp.low != 0x20 &&
-                                           SLIC_GetState(j) != PLD_SLIC_STATE_ACTIVE) {
-                                               SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j);
-                                       }
-                                       LineMonitor(j);
-                                       read_filters(j);
-                                       ixj_WriteDSPCommand(0x511B, j);
-                                       j->proc_load = j->ssr.high << 8 | j->ssr.low;
-                                       if (!j->m_hook) {
-                                               j->m_hook = j->ex.bits.hookstate = 1;
-                                               ixj_kill_fasync(j, POLL_PRI);
+                       if (j->pstn_winkstart && time_after(jiffies, j->pstn_winkstart + ((hertz * j->winktime) / 1000))) {
+                               if(ixjdebug & 0x0008) {
+                                       printk("IXJ DAA wink detected going to sleep /dev/phone%d %ld\n", j->board, jiffies);
+                               }
+                               daa_set_mode(j, SOP_PU_SLEEP);
+                               j->pstn_winkstart = 0;
+                               j->ex.bits.pstn_wink = 1;
+                               ixj_kill_fasync(j, SIG_PSTN_WINK, POLL_IN);
+                       }
+                       break;
+       }
+}
+
+static void ixj_timeout(unsigned long ptr)
+{
+       int board;
+       unsigned long jifon;
+       IXJ *j = (IXJ *)ptr;
+       board = j->board;
+
+       if (j->DSPbase && atomic_read(&j->DSPWrite) == 0 && test_and_set_bit(board, (void *)&j->busyflags) == 0) {
+               ixj_perfmon(j->timerchecks);
+               j->hookstate = ixj_hookstate(j);
+               if (j->tone_state) {
+                       if (!(j->hookstate)) {
+                               ixj_cpt_stop(j);
+                               if (j->m_hook) {
+                                       j->m_hook = 0;
+                                       j->ex.bits.hookstate = 1;
+                                       ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN);
+                               }
+                               clear_bit(board, &j->busyflags);
+                               ixj_add_timer(j);
+                               return;
+                       }
+                       if (j->tone_state == 1)
+                               jifon = ((hertz * j->tone_on_time) * 25 / 100000);
+                       else
+                               jifon = ((hertz * j->tone_on_time) * 25 / 100000) + ((hertz * j->tone_off_time) * 25 / 100000);
+                       if (time_before(jiffies, j->tone_start_jif + jifon)) {
+                               if (j->tone_state == 1) {
+                                       ixj_play_tone(j, j->tone_index);
+                                       if (j->dsp.low == 0x20) {
+                                               clear_bit(board, &j->busyflags);
+                                               ixj_add_timer(j);
+                                               return;
                                        }
                                } else {
-                                       if (j->dsp.low != 0x20 &&
-                                           SLIC_GetState(j) == PLD_SLIC_STATE_ACTIVE)
-                                               // Internet LineJACK
-                                       {
-                                               SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
+                                       ixj_play_tone(j, 0);
+                                       if (j->dsp.low == 0x20) {
+                                               clear_bit(board, &j->busyflags);
+                                               ixj_add_timer(j);
+                                               return;
                                        }
-                                       if (j->ex.bits.dtmf_ready) {
-                                               j->dtmf_wp = j->dtmf_rp = j->ex.bits.dtmf_ready = 0;
+                               }
+                       } else {
+                               ixj_tone_timeout(j);
+                               if (j->flags.dialtone) {
+                                       ixj_dialtone(j);
+                               }
+                               if (j->flags.busytone) {
+                                       ixj_busytone(j);
+                                       if (j->dsp.low == 0x20) {
+                                               clear_bit(board, &j->busyflags);
+                                               ixj_add_timer(j);
+                                               return;
                                        }
-                                       if (j->m_hook) {
-                                               j->m_hook = 0;
-                                               j->ex.bits.hookstate = 1;
-                                               ixj_kill_fasync(j, POLL_PRI);
+                               }
+                               if (j->flags.ringback) {
+                                       ixj_ringback(j);
+                                       if (j->dsp.low == 0x20) {
+                                               clear_bit(board, &j->busyflags);
+                                               ixj_add_timer(j);
+                                               return;
                                        }
                                }
+                               if (!j->tone_state) {
+                                       ixj_cpt_stop(j);
+                               }
                        }
-                       if (j->cardtype == 300 && !j->flags.incheck) {
-                               if (j->flags.pstn_present) {
-                                       j->pld_scrr.byte = inb_p(j->XILINXbase);
-                                       if (j->pld_scrr.bits.daaflag) {
-                                               daa_int_read(j);
-                                               if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.RING) {
-                                                       if (!j->flags.pstn_ringing) {
-                                                               j->flags.pstn_ringing = 1;
-                                                               if (j->daa_mode != SOP_PU_RINGING)
-                                                                       daa_set_mode(j, SOP_PU_RINGING);
+               }
+               if (!(j->tone_state && j->dsp.low == 0x20)) {
+                       if (IsRxReady(j)) {
+                               ixj_read_frame(j);
+                       }
+                       if (IsTxReady(j)) {
+                               ixj_write_frame(j);
+                       }
+               }
+               if (j->flags.cringing) {
+                       if (j->hookstate & 1) {
+                               j->flags.cringing = 0;
+                               ixj_ring_off(j);
+                       } else if(j->cadence_f[5].enable && ((!j->cadence_f[5].en_filter) || (j->cadence_f[5].en_filter && j->flags.firstring))) {
+                               switch(j->cadence_f[5].state) {
+                                       case 0:
+                                               j->cadence_f[5].on1dot = jiffies + (long)((j->cadence_f[5].on1 * (hertz * 100) / 10000));
+                                               if (time_before(jiffies, j->cadence_f[5].on1dot)) {
+                                                       if(ixjdebug & 0x0004) {
+                                                               printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
+                                                       }
+                                                       ixj_ring_on(j);
+                                               }
+                                               j->cadence_f[5].state = 1;
+                                               break;
+                                       case 1:
+                                               if (time_after(jiffies, j->cadence_f[5].on1dot)) {
+                                                       j->cadence_f[5].off1dot = jiffies + (long)((j->cadence_f[5].off1 * (hertz * 100) / 10000));
+                                                       if(ixjdebug & 0x0004) {
+                                                               printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
                                                        }
+                                                       ixj_ring_off(j);
+                                                       j->cadence_f[5].state = 2;
                                                }
-                                               if (time_after(jiffies, j->pstn_sleeptil) && j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
-                                                       j->pstn_winkstart = 0;
-                                                       j->pstn_ring_stop = 0;
-                                                       j->pld_scrw.bits.led1 = 1;
-                                                       if (j->flags.pstn_ringing && !j->pstn_envelope) {
-                                                               if (j->daa_mode != SOP_PU_RINGING) {
-                                                                       j->flags.pstn_ringing = 0;
-                                                               } else {
-                                                                       j->pld_scrw.bits.led2 = 0;
-                                                                       j->pstn_envelope = 1;
-                                                                       j->pstn_ring_start = jiffies;
-                                                                       j->pstn_ring_stop = 0;
-                                                               }
-                                                               j->ex.bits.pstn_ring = 0;
+                                               break;
+                                       case 2:
+                                               if (time_after(jiffies, j->cadence_f[5].off1dot)) {
+                                                       if(ixjdebug & 0x0004) {
+                                                               printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
                                                        }
-                                                       outb_p(j->pld_scrw.byte, j->XILINXbase);
-                                               } else {
-                                                       j->pld_scrw.bits.led1 = 0;
-                                                       j->pld_scrw.bits.led2 = 1;
-                                                       outb_p(j->pld_scrw.byte, j->XILINXbase);
-                                                       if (j->flags.pstn_ringing && j->pstn_envelope) {
-                                                               if(!j->pstn_ring_stop) {
-                                                                       j->pstn_ring_stop = jiffies;
-                                                               } else if (time_after(jiffies, j->pstn_ring_stop + ((hertz * 5) / 100))){
-                                                                       j->pstn_ring_stop = 0;
-                                                                       j->ex.bits.pstn_ring = 1;
-                                                                       j->pstn_envelope = 0;
-                                                               }
-                                                       } else if (j->daa_mode == SOP_PU_CONVERSATION) {
-                                                               if (!j->pstn_winkstart) {
-                                                                       j->pstn_winkstart = jiffies;
-                                                               } else if (time_after(jiffies, j->pstn_winkstart + (hertz * j->winktime / 1000))) {
-                                                                       daa_set_mode(j, SOP_PU_SLEEP);
-                                                                       j->pstn_winkstart = 0;
-                                                                       j->ex.bits.pstn_wink = 1;
-                                                               }
+                                                       ixj_ring_on(j);
+                                                       if (j->cadence_f[5].on2) {
+                                                               j->cadence_f[5].on2dot = jiffies + (long)((j->cadence_f[5].on2 * (hertz * 100) / 10000));
+                                                               j->cadence_f[5].state = 3;
                                                        } else {
-                                                               j->ex.bits.pstn_ring = 0;
+                                                               j->cadence_f[5].state = 7;
                                                        }
                                                }
-                                               if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Cadence) {
-                                                       if (j->daa_mode == SOP_PU_RINGING) {
-                                                               daa_set_mode(j, SOP_PU_SLEEP);
-                                                               j->flags.pstn_ringing = 0;
-                                                               j->ex.bits.pstn_ring = 0;
+                                               break;
+                                       case 3:
+                                               if (time_after(jiffies, j->cadence_f[5].on2dot)) {
+                                                       if(ixjdebug & 0x0004) {
+                                                               printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
                                                        }
-                                               }
-                                               if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Caller_ID) {
-                                                       if (j->daa_mode == SOP_PU_RINGING && j->flags.pstn_ringing) {
-                                                               j->pstn_cid_intr = 1;
-                                                               j->pstn_cid_received = jiffies;
+                                                       ixj_ring_off(j);
+                                                       if (j->cadence_f[5].off2) {
+                                                               j->cadence_f[5].off2dot = jiffies + (long)((j->cadence_f[5].off2 * (hertz * 100) / 10000));
+                                                               j->cadence_f[5].state = 4;
+                                                       } else {
+                                                               j->cadence_f[5].state = 7;
                                                        }
                                                }
-                                       } else {
-                                               if (j->pld_scrr.bits.daaflag) {
-                                                       daa_int_read(j);
+                                               break;
+                                       case 4:
+                                               if (time_after(jiffies, j->cadence_f[5].off2dot)) {
+                                                       if(ixjdebug & 0x0004) {
+                                                               printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
+                                                       }
+                                                       ixj_ring_on(j);
+                                                       if (j->cadence_f[5].on3) {
+                                                               j->cadence_f[5].on3dot = jiffies + (long)((j->cadence_f[5].on3 * (hertz * 100) / 10000));
+                                                               j->cadence_f[5].state = 5;
+                                                       } else {
+                                                               j->cadence_f[5].state = 7;
+                                                       }
                                                }
-                                               j->ex.bits.pstn_ring = 0;
-                                               if (j->pstn_cid_intr && jiffies > j->pstn_cid_received + (hertz * 3)) {
-                                                       if (j->daa_mode == SOP_PU_RINGING) {
-                                                               ixj_daa_cid_read(j);
-                                                               j->ex.bits.caller_id = 1;
+                                               break;
+                                       case 5:
+                                               if (time_after(jiffies, j->cadence_f[5].on3dot)) {
+                                                       if(ixjdebug & 0x0004) {
+                                                               printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
+                                                       }
+                                                       ixj_ring_off(j);
+                                                       if (j->cadence_f[5].off3) {
+                                                               j->cadence_f[5].off3dot = jiffies + (long)((j->cadence_f[5].off3 * (hertz * 100) / 10000));
+                                                               j->cadence_f[5].state = 6;
+                                                       } else {
+                                                               j->cadence_f[5].state = 7;
                                                        }
-                                                       j->pstn_cid_intr = 0;
-                                               } else {
-                                                       j->ex.bits.caller_id = 0;
                                                }
-                                               if (!j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
-                                                       j->pld_scrw.bits.led1 = 0;
-                                                       j->pld_scrw.bits.led2 = 1;
-                                                       outb_p(j->pld_scrw.byte, j->XILINXbase);
-                                                       if (j->flags.pstn_ringing && j->pstn_envelope) {
-                                                               if(!j->pstn_ring_stop) {
-                                                                       j->pstn_ring_stop = jiffies;
-                                                               } else if (time_after(jiffies, j->pstn_ring_stop + ((hertz * 5) / 100))){
-                                                                       j->pstn_ring_stop = 0;
-                                                                       j->ex.bits.pstn_ring = 1;
-                                                                       j->pstn_envelope = 0;
-                                                               }
-                                                               j->pld_scrw.bits.led1 = 0;
-                                                               outb_p(j->pld_scrw.byte, j->XILINXbase);
-                                                       } else if (j->daa_mode == SOP_PU_CONVERSATION) {
-                                                               if (!j->pstn_winkstart) {
-                                                                       j->pstn_winkstart = jiffies;
-                                                               } else if (time_after(jiffies, j->pstn_winkstart + (hertz * j->winktime / 1000))) {
-                                                                       daa_set_mode(j, SOP_PU_SLEEP);
-                                                                       j->pstn_winkstart = 0;
-                                                                       j->ex.bits.pstn_wink = 1;
-                                                               }
+                                               break;
+                                       case 6:
+                                               if (time_after(jiffies, j->cadence_f[5].off3dot)) {
+                                                       if(ixjdebug & 0x0004) {
+                                                               printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
                                                        }
+                                                       j->cadence_f[5].state = 7;
                                                }
+                                               break;
+                                       case 7:
+                                               if(ixjdebug & 0x0004) {
+                                                       printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
+                                               }
+                                               j->flags.cidring = 1;
+                                               j->cadence_f[5].state = 0;
+                                               break;
+                               }
+                               if (j->flags.cidring && !j->flags.cidsent) {
+                                       j->flags.cidsent = 1;
+                                       if(j->fskdcnt) {
+                                               SLIC_SetState(PLD_SLIC_STATE_OHT, j);
+                                               ixj_pre_cid(j);
+                                       }
+                                       j->flags.cidring = 0;
+                               }
+                               clear_bit(board, &j->busyflags);
+                               ixj_add_timer(j);
+                               return;
+                       } else {
+                               if (time_after(jiffies, j->ring_cadence_jif + (hertz / 2))) {
+                                       if (j->flags.cidring && !j->flags.cidsent) {
+                                               j->flags.cidsent = 1;
+                                               if(j->fskdcnt) {
+                                                       SLIC_SetState(PLD_SLIC_STATE_OHT, j);
+                                                       ixj_pre_cid(j);
+                                               }
+                                               j->flags.cidring = 0;
+                                       }
+                                       j->ring_cadence_t--;
+                                       if (j->ring_cadence_t == -1)
+                                               j->ring_cadence_t = 15;
+                                       j->ring_cadence_jif = jiffies;
+
+                                       if (j->ring_cadence & 1 << j->ring_cadence_t) {
+                                               if(j->flags.cidsent && j->cadence_f[5].en_filter)
+                                                       j->flags.firstring = 1;
+                                               else
+                                                       ixj_ring_on(j);
+                                       } else {
+                                               ixj_ring_off(j);
+                                               if(!j->flags.cidsent)
+                                                       j->flags.cidring = 1;
                                        }
                                }
+                               clear_bit(board, &j->busyflags);
+                               ixj_add_timer(j);
+                               return;
                        }
-                       if (j->ex.bytes) {
-                               wake_up_interruptible(&j->poll_q);      // Wake any blocked selects
-                               ixj_kill_fasync(j, POLL_PRI);
+               }
+               if (!j->flags.ringing) {
+                       if (j->hookstate) { /* & 1) { */
+                               if (j->dsp.low != 0x20 &&
+                                   SLIC_GetState(j) != PLD_SLIC_STATE_ACTIVE) {
+                                       SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j);
+                               }
+                               LineMonitor(j);
+                               read_filters(j);
+                               ixj_WriteDSPCommand(0x511B, j);
+                               j->proc_load = j->ssr.high << 8 | j->ssr.low;
+                               if (!j->m_hook && (j->hookstate & 1)) {
+                                       j->m_hook = j->ex.bits.hookstate = 1;
+                                       ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN);
+                               }
+                       } else {
+                               if (j->ex.bits.dtmf_ready) {
+                                       j->dtmf_wp = j->dtmf_rp = j->ex.bits.dtmf_ready = 0;
+                               }
+                               if (j->m_hook) {
+                                       j->m_hook = 0;
+                                       j->ex.bits.hookstate = 1;
+                                       ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN);
+                               }
                        }
-               } else {
-                       break;
                }
+               if (j->cardtype == QTI_LINEJACK && !j->flags.pstncheck && j->flags.pstn_present) {
+                       ixj_pstn_state(j);
+               }
+               if (j->ex.bytes) {
+                       wake_up_interruptible(&j->poll_q);      /* Wake any blocked selects */
+               }
+               clear_bit(board, &j->busyflags);
        }
-       ixj_add_timer();
+       ixj_add_timer(j);
 }
 
 static int ixj_status_wait(IXJ *j)
 {
        unsigned long jif;
 
-       jif = jiffies;
+       jif = jiffies + ((60 * hertz) / 100);
        while (!IsStatusReady(j)) {
-               if (jiffies - jif > (60 * (hertz / 100))) {
+               ixj_perfmon(j->statuswait);
+               if (time_after(jiffies, jif)) {
+                       ixj_perfmon(j->statuswaitfail);
                        return -1;
                }
        }
@@ -809,39 +1523,69 @@ static int ixj_PCcontrol_wait(IXJ *j)
 {
        unsigned long jif;
 
-       jif = jiffies;
+       jif = jiffies + ((60 * hertz) / 100);
        while (!IsPCControlReady(j)) {
-               if (jiffies - jif > (60 * (hertz / 100))) {
+               ixj_perfmon(j->pcontrolwait);
+               if (time_after(jiffies, jif)) {
+                       ixj_perfmon(j->pcontrolwaitfail);
                        return -1;
                }
        }
        return 0;
 }
 
-int ixj_WriteDSPCommand(unsigned short cmd, IXJ *j)
+static int ixj_WriteDSPCommand(unsigned short cmd, IXJ *j)
 {
        BYTES bytes;
        unsigned long jif;
 
+       atomic_inc(&j->DSPWrite);
+       if(atomic_read(&j->DSPWrite) > 1) {
+               printk("IXJ %d DSP write overlap attempting command 0x%4.4x\n", j->board, cmd);
+               return -1;
+       }
        bytes.high = (cmd & 0xFF00) >> 8;
        bytes.low = cmd & 0x00FF;
-       jif = jiffies;
+       jif = jiffies + ((60 * hertz) / 100);
        while (!IsControlReady(j)) {
-               if (jiffies - jif > (60 * (hertz / 100))) {
+               ixj_perfmon(j->iscontrolready);
+               if (time_after(jiffies, jif)) {
+                       ixj_perfmon(j->iscontrolreadyfail);
+                       atomic_dec(&j->DSPWrite);
+                       if(atomic_read(&j->DSPWrite) > 0) {
+                               printk("IXJ %d DSP overlaped command 0x%4.4x during control ready failure.\n", j->board, cmd);
+                               while(atomic_read(&j->DSPWrite) > 0) {
+                                       atomic_dec(&j->DSPWrite);
+                               }
+                       }
                        return -1;
                }
        }
-       outb_p(bytes.low, j->DSPbase + 6);
-       outb_p(bytes.high, j->DSPbase + 7);
+       outb(bytes.low, j->DSPbase + 6);
+       outb(bytes.high, j->DSPbase + 7);
 
        if (ixj_status_wait(j)) {
                j->ssr.low = 0xFF;
                j->ssr.high = 0xFF;
+               atomic_dec(&j->DSPWrite);
+               if(atomic_read(&j->DSPWrite) > 0) {
+                       printk("IXJ %d DSP overlaped command 0x%4.4x during status wait failure.\n", j->board, cmd);
+                       while(atomic_read(&j->DSPWrite) > 0) {
+                               atomic_dec(&j->DSPWrite);
+                       }
+               }
                return -1;
        }
 /* Read Software Status Register */
        j->ssr.low = inb_p(j->DSPbase + 2);
        j->ssr.high = inb_p(j->DSPbase + 3);
+       atomic_dec(&j->DSPWrite);
+       if(atomic_read(&j->DSPWrite) > 0) {
+               printk("IXJ %d DSP overlaped command 0x%4.4x\n", j->board, cmd);
+               while(atomic_read(&j->DSPWrite) > 0) {
+                       atomic_dec(&j->DSPWrite);
+               }
+       }
        return 0;
 }
 
@@ -850,7 +1594,7 @@ int ixj_WriteDSPCommand(unsigned short cmd, IXJ *j)
 *  General Purpose IO Register read routine
 *
 ***************************************************************************/
-extern __inline__ int ixj_gpio_read(IXJ *j)
+static inline int ixj_gpio_read(IXJ *j)
 {
        if (ixj_WriteDSPCommand(0x5143, j))
                return -1;
@@ -861,7 +1605,7 @@ extern __inline__ int ixj_gpio_read(IXJ *j)
        return 0;
 }
 
-extern __inline__ void LED_SetState(int state, IXJ *j)
+static inline void LED_SetState(int state, IXJ *j)
 {
        if (j->cardtype == QTI_LINEJACK) {
                j->pld_scrw.bits.led1 = state & 0x1 ? 1 : 0;
@@ -869,7 +1613,7 @@ extern __inline__ void LED_SetState(int state, IXJ *j)
                j->pld_scrw.bits.led3 = state & 0x4 ? 1 : 0;
                j->pld_scrw.bits.led4 = state & 0x8 ? 1 : 0;
 
-               outb_p(j->pld_scrw.byte, j->XILINXbase);
+               outb(j->pld_scrw.byte, j->XILINXbase);
        }
 }
 
@@ -908,22 +1652,31 @@ static int ixj_set_port(IXJ *j, int arg)
                case QTI_PHONEJACK_PCI:
                        j->pld_slicw.pcib.mic = 0;
                        j->pld_slicw.pcib.spk = 0;
-                       outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+                       outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
                        break;
                case QTI_LINEJACK:
-                       ixj_set_pots(j, 0);
+                       ixj_set_pots(j, 0);                     /* Disconnect POTS/PSTN relay */
                        if (ixj_WriteDSPCommand(0xC528, j))             /* Write CODEC config to
                                                                           Software Control Register */
                                return 2;
-                       j->pld_scrw.bits.daafsyncen = 0;        // Turn off DAA Frame Sync
+                       j->pld_scrw.bits.daafsyncen = 0;        /* Turn off DAA Frame Sync */
 
-                       outb_p(j->pld_scrw.byte, j->XILINXbase);
+                       outb(j->pld_scrw.byte, j->XILINXbase);
                        j->pld_clock.byte = 0;
-                       outb_p(j->pld_clock.byte, j->XILINXbase + 0x04);
+                       outb(j->pld_clock.byte, j->XILINXbase + 0x04);
                        j->pld_slicw.bits.rly1 = 1;
                        j->pld_slicw.bits.spken = 0;
-                       outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+                       outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
+                       ixj_mixer(0x1200, j);   /* Turn Off MIC switch on mixer left */
+                       ixj_mixer(0x1401, j);   /* Turn On Mono1 switch on mixer left */
+                       ixj_mixer(0x1300, j);       /* Turn Off MIC switch on mixer right */
+                       ixj_mixer(0x1501, j);       /* Turn On Mono1 switch on mixer right */
+                       ixj_mixer(0x0E80, j);   /*Mic mute */
+                       ixj_mixer(0x0F00, j);   /* Set mono out (SLIC) to 0dB */
+                       ixj_mixer(0x0080, j);   /* Mute Master Left volume */
+                       ixj_mixer(0x0180, j);   /* Mute Master Right volume */
                        SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
+/*                     SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */
                        break;
                case QTI_PHONEJACK:
                        j->gpio.bytes.high = 0x0B;
@@ -940,7 +1693,7 @@ static int ixj_set_port(IXJ *j, int arg)
                        j->pld_slicw.bits.rly3 = 0;
                        j->pld_slicw.bits.rly1 = 1;
                        j->pld_slicw.bits.spken = 0;
-                       outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+                       outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
                        j->port = PORT_PSTN;
                } else {
                        return 4;
@@ -957,10 +1710,29 @@ static int ixj_set_port(IXJ *j, int arg)
                case QTI_PHONEJACK_PCI:
                        j->pld_slicw.pcib.mic = 1;
                        j->pld_slicw.pcib.spk = 1;
-                       outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+                       outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
                        break;
                case QTI_LINEJACK:
-                       ixj_set_pots(j, 0);
+                       ixj_set_pots(j, 0);                     /* Disconnect POTS/PSTN relay */
+                       if (ixj_WriteDSPCommand(0xC528, j))             /* Write CODEC config to
+                                                                          Software Control Register */
+                               return 2;
+                       j->pld_scrw.bits.daafsyncen = 0;        /* Turn off DAA Frame Sync */
+
+                       outb(j->pld_scrw.byte, j->XILINXbase);
+                       j->pld_clock.byte = 0;
+                       outb(j->pld_clock.byte, j->XILINXbase + 0x04);
+                       j->pld_slicw.bits.rly1 = 1;
+                       j->pld_slicw.bits.spken = 1;
+                       outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
+                       ixj_mixer(0x1201, j);   /* Turn On MIC switch on mixer left */
+                       ixj_mixer(0x1400, j);   /* Turn Off Mono1 switch on mixer left */
+                       ixj_mixer(0x1301, j);       /* Turn On MIC switch on mixer right */
+                       ixj_mixer(0x1500, j);       /* Turn Off Mono1 switch on mixer right */
+                       ixj_mixer(0x0E06, j);   /*Mic un-mute 0dB */
+                       ixj_mixer(0x0F80, j);   /* Mute mono out (SLIC) */
+                       ixj_mixer(0x0000, j);   /* Set Master Left volume to 0dB */
+                       ixj_mixer(0x0100, j);   /* Set Master Right volume to 0dB */
                        break;
                case QTI_PHONEJACK:
                        j->gpio.bytes.high = 0x0B;
@@ -971,7 +1743,7 @@ static int ixj_set_port(IXJ *j, int arg)
                }
                break;
        case PORT_HANDSET:
-               if (j->cardtype == QTI_LINEJACK || j->cardtype == QTI_PHONEJACK_PCI) {
+               if (j->cardtype != QTI_PHONEJACK) {
                        return 5;
                } else {
                        j->gpio.bytes.high = 0x0B;
@@ -994,14 +1766,17 @@ static int ixj_set_pots(IXJ *j, int arg)
                if (arg) {
                        if (j->port == PORT_PSTN) {
                                j->pld_slicw.bits.rly1 = 0;
-                               outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+                               outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
+                               j->flags.pots_pstn = 1;
                                return 1;
                        } else {
+                               j->flags.pots_pstn = 0;
                                return 0;
                        }
                } else {
                        j->pld_slicw.bits.rly1 = 1;
-                       outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+                       outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
+                       j->flags.pots_pstn = 0;
                        return 1;
                }
        } else {
@@ -1011,18 +1786,76 @@ static int ixj_set_pots(IXJ *j, int arg)
 
 static void ixj_ring_on(IXJ *j)
 {
-       if (j->dsp.low == 0x20) { // Internet PhoneJACK
+       if (j->dsp.low == 0x20) /* Internet PhoneJACK */
+        {
+               if (ixjdebug & 0x0004)
+                       printk(KERN_INFO "IXJ Ring On /dev/phone%d\n",  j->board);
+
                j->gpio.bytes.high = 0x0B;
                j->gpio.bytes.low = 0x00;
                j->gpio.bits.gpio1 = 1;
                j->gpio.bits.gpio2 = 1;
                j->gpio.bits.gpio5 = 0;
                ixj_WriteDSPCommand(j->gpio.word, j);   /* send the ring signal */
-       } else {                        // Internet LineJACK, Internet PhoneJACK Lite or Internet PhoneJACK PCI
+       } else                  /* Internet LineJACK, Internet PhoneJACK Lite or Internet PhoneJACK PCI */
+       {
+               if (ixjdebug & 0x0004)
+                       printk(KERN_INFO "IXJ Ring On /dev/phone%d\n", j->board);
+
                SLIC_SetState(PLD_SLIC_STATE_RINGING, j);
        }
 }
 
+static int ixj_siadc(IXJ *j, int val)
+{
+       if(j->cardtype == QTI_PHONECARD){
+               if(j->flags.pcmciascp){
+                       if(val == -1)
+                               return j->siadc.bits.rxg;
+
+                       if(val < 0 || val > 0x1F)
+                               return -1;
+
+                       j->siadc.bits.hom = 0;                          /* Handset Out Mute */
+                       j->siadc.bits.lom = 0;                          /* Line Out Mute */
+                       j->siadc.bits.rxg = val;                        /*(0xC000 - 0x41C8) / 0x4EF;    RX PGA Gain */
+                       j->psccr.bits.addr = 6;                         /* R/W Smart Cable Register Address */
+                       j->psccr.bits.rw = 0;                           /* Read / Write flag */
+                       j->psccr.bits.dev = 0;
+                       outb(j->siadc.byte, j->XILINXbase + 0x00);
+                       outb(j->psccr.byte, j->XILINXbase + 0x01);
+                       ixj_PCcontrol_wait(j);
+                       return j->siadc.bits.rxg;
+               }
+       }
+       return -1;
+}
+
+static int ixj_sidac(IXJ *j, int val)
+{
+       if(j->cardtype == QTI_PHONECARD){
+               if(j->flags.pcmciascp){
+                       if(val == -1)
+                               return j->sidac.bits.txg;
+
+                       if(val < 0 || val > 0x1F)
+                               return -1;
+
+                       j->sidac.bits.srm = 1;                          /* Speaker Right Mute */
+                       j->sidac.bits.slm = 1;                          /* Speaker Left Mute */
+                       j->sidac.bits.txg = val;                        /* (0xC000 - 0x45E4) / 0x5D3;    TX PGA Gain */
+                       j->psccr.bits.addr = 7;                         /* R/W Smart Cable Register Address */
+                       j->psccr.bits.rw = 0;                           /* Read / Write flag */
+                       j->psccr.bits.dev = 0;
+                       outb(j->sidac.byte, j->XILINXbase + 0x00);
+                       outb(j->psccr.byte, j->XILINXbase + 0x01);
+                       ixj_PCcontrol_wait(j);
+                       return j->sidac.bits.txg;
+               }
+       }
+       return -1;
+}
+
 static int ixj_pcmcia_cable_check(IXJ *j)
 {
        j->pccr1.byte = inb_p(j->XILINXbase + 0x03);
@@ -1058,8 +1891,8 @@ static int ixj_pcmcia_cable_check(IXJ *j)
        } else if (j->flags.pcmciastate == 3) {
                j->pccr2.bits.pwr = 0;
                j->pccr2.bits.rstc = 1;
-               outb_p(j->pccr2.byte, j->XILINXbase + 0x02);
-               j->checkwait = jiffies + hertz * 2;
+               outb(j->pccr2.byte, j->XILINXbase + 0x02);
+               j->checkwait = jiffies + (hertz * 2);
                j->flags.incheck = 1;
                j->flags.pcmciastate = 2;
                return 0;
@@ -1083,9 +1916,9 @@ static int ixj_pcmcia_cable_check(IXJ *j)
                        j->psccr.bits.rw = 1;
                        outb_p(j->psccr.byte, j->XILINXbase + 0x01);
                        ixj_PCcontrol_wait(j);
-                       j->flags.pcmciascp = 1;         // Set Cable Present Flag
+                       j->flags.pcmciascp = 1;         /* Set Cable Present Flag */
 
-                       j->flags.pcmciasct = (inw_p(j->XILINXbase + 0x00) >> 8) & 0x03;         // Get Cable Type
+                       j->flags.pcmciasct = (inw_p(j->XILINXbase + 0x00) >> 8) & 0x03;         /* Get Cable Type */
 
                        if (j->flags.pcmciasct == 3) {
                                j->flags.pcmciastate = 4;
@@ -1098,113 +1931,63 @@ static int ixj_pcmcia_cable_check(IXJ *j)
                        } else {
                                j->port = PORT_POTS;
                        }
-                       j->sic1.bits.cpd = 0;   // Chip Power Down
-
-                       j->sic1.bits.mpd = 0;   // MIC Bias Power Down
-
-                       j->sic1.bits.hpd = 0;   // Handset Bias Power Down
-
-                       j->sic1.bits.lpd = 0;   // Line Bias Power Down
-
-                       j->sic1.bits.spd = 1;   // Speaker Drive Power Down
-
-                       j->psccr.bits.addr = 1;         // R/W Smart Cable Register Address
-
-                       j->psccr.bits.rw = 0;   // Read / Write flag
-
+                       j->sic1.bits.cpd = 0;                           /* Chip Power Down */
+                       j->sic1.bits.mpd = 0;                           /* MIC Bias Power Down */
+                       j->sic1.bits.hpd = 0;                           /* Handset Bias Power Down */
+                       j->sic1.bits.lpd = 0;                           /* Line Bias Power Down */
+                       j->sic1.bits.spd = 1;                           /* Speaker Drive Power Down */
+                       j->psccr.bits.addr = 1;                         /* R/W Smart Cable Register Address */
+                       j->psccr.bits.rw = 0;                           /* Read / Write flag */
                        j->psccr.bits.dev = 0;
                        outb(j->sic1.byte, j->XILINXbase + 0x00);
                        outb(j->psccr.byte, j->XILINXbase + 0x01);
                        ixj_PCcontrol_wait(j);
-                       j->sic2.bits.al = 0;    // Analog Loopback DAC analog -> ADC analog
-
-                       j->sic2.bits.dl2 = 0;   // Digital Loopback DAC -> ADC one bit
-
-                       j->sic2.bits.dl1 = 0;   // Digital Loopback ADC -> DAC one bit
-
-                       j->sic2.bits.pll = 0;   // 1 = div 10, 0 = div 5
-
-                       j->sic2.bits.hpd = 0;   // HPF disable
-
-                       j->psccr.bits.addr = 2;         // R/W Smart Cable Register Address
-
-                       j->psccr.bits.rw = 0;   // Read / Write flag
 
+                       j->sic2.bits.al = 0;                            /* Analog Loopback DAC analog -> ADC analog */
+                       j->sic2.bits.dl2 = 0;                           /* Digital Loopback DAC -> ADC one bit */
+                       j->sic2.bits.dl1 = 0;                           /* Digital Loopback ADC -> DAC one bit */
+                       j->sic2.bits.pll = 0;                           /* 1 = div 10, 0 = div 5 */
+                       j->sic2.bits.hpd = 0;                           /* HPF disable */
+                       j->psccr.bits.addr = 2;                         /* R/W Smart Cable Register Address */
+                       j->psccr.bits.rw = 0;                           /* Read / Write flag */
                        j->psccr.bits.dev = 0;
                        outb(j->sic2.byte, j->XILINXbase + 0x00);
                        outb(j->psccr.byte, j->XILINXbase + 0x01);
                        ixj_PCcontrol_wait(j);
-                       j->psccr.bits.addr = 3;         // R/W Smart Cable Register Address
-
-                       j->psccr.bits.rw = 0;   // Read / Write flag
 
+                       j->psccr.bits.addr = 3;                         /* R/W Smart Cable Register Address */
+                       j->psccr.bits.rw = 0;                           /* Read / Write flag */
                        j->psccr.bits.dev = 0;
-                       outb(0x00, j->XILINXbase + 0x00);       // PLL Divide N1
-
+                       outb(0x00, j->XILINXbase + 0x00);               /* PLL Divide N1 */
                        outb(j->psccr.byte, j->XILINXbase + 0x01);
                        ixj_PCcontrol_wait(j);
-                       j->psccr.bits.addr = 4;         // R/W Smart Cable Register Address
-
-                       j->psccr.bits.rw = 0;   // Read / Write flag
 
+                       j->psccr.bits.addr = 4;                         /* R/W Smart Cable Register Address */
+                       j->psccr.bits.rw = 0;                           /* Read / Write flag */
                        j->psccr.bits.dev = 0;
-                       outb(0x09, j->XILINXbase + 0x00);       // PLL Multiply M1
-
+                       outb(0x09, j->XILINXbase + 0x00);               /* PLL Multiply M1 */
                        outb(j->psccr.byte, j->XILINXbase + 0x01);
                        ixj_PCcontrol_wait(j);
-                       j->sirxg.bits.lig = 1;  // Line In Gain
-
-                       j->sirxg.bits.lim = 1;  // Line In Mute
-
-                       j->sirxg.bits.mcg = 0;  // MIC In Gain // was 3
-
-                       j->sirxg.bits.mcm = 0;  // MIC In Mute
-
-                       j->sirxg.bits.him = 0;  // Handset In Mute
-
-                       j->sirxg.bits.iir = 1;  // IIR
-
-                       j->psccr.bits.addr = 5;         // R/W Smart Cable Register Address
-
-                       j->psccr.bits.rw = 0;   // Read / Write flag
 
+                       j->sirxg.bits.lig = 1;                          /* Line In Gain */
+                       j->sirxg.bits.lim = 1;                          /* Line In Mute */
+                       j->sirxg.bits.mcg = 0;                          /* MIC In Gain was 3 */
+                       j->sirxg.bits.mcm = 0;                          /* MIC In Mute */
+                       j->sirxg.bits.him = 0;                          /* Handset In Mute */
+                       j->sirxg.bits.iir = 1;                          /* IIR */
+                       j->psccr.bits.addr = 5;                         /* R/W Smart Cable Register Address */
+                       j->psccr.bits.rw = 0;                           /* Read / Write flag */
                        j->psccr.bits.dev = 0;
                        outb(j->sirxg.byte, j->XILINXbase + 0x00);
                        outb(j->psccr.byte, j->XILINXbase + 0x01);
                        ixj_PCcontrol_wait(j);
-                       j->siadc.bits.hom = 0;  // Handset Out Mute
-
-                       j->siadc.bits.lom = 0;  // Line Out Mute
-
-                       j->siadc.bits.rxg = 23;         //(0xC000 - 0x41C8) / 0x4EF;    // RX PGA Gain
 
-                       j->psccr.bits.addr = 6;         // R/W Smart Cable Register Address
+                       ixj_siadc(j, 0x17);
+                       ixj_sidac(j, 0x1D);
 
-                       j->psccr.bits.rw = 0;   // Read / Write flag
-
-                       j->psccr.bits.dev = 0;
-                       outb(j->siadc.byte, j->XILINXbase + 0x00);
-                       outb(j->psccr.byte, j->XILINXbase + 0x01);
-                       ixj_PCcontrol_wait(j);
-                       j->sidac.bits.srm = 1;  // Speaker Right Mute
-
-                       j->sidac.bits.slm = 1;  // Speaker Left Mute
-
-                       j->sidac.bits.txg = (0xC000 - 0x45E4) / 0x5D3;  // TX PGA Gain
-
-                       j->psccr.bits.addr = 7;         // R/W Smart Cable Register Address
-
-                       j->psccr.bits.rw = 0;   // Read / Write flag
-
-                       j->psccr.bits.dev = 0;
-                       outb(j->sidac.byte, j->XILINXbase + 0x00);
-                       outb(j->psccr.byte, j->XILINXbase + 0x01);
-                       ixj_PCcontrol_wait(j);
                        j->siaatt.bits.sot = 0;
-                       j->psccr.bits.addr = 9;         // R/W Smart Cable Register Address
-
-                       j->psccr.bits.rw = 0;   // Read / Write flag
-
+                       j->psccr.bits.addr = 9;                         /* R/W Smart Cable Register Address */
+                       j->psccr.bits.rw = 0;                           /* Read / Write flag */
                        j->psccr.bits.dev = 0;
                        outb(j->siaatt.byte, j->XILINXbase + 0x00);
                        outb(j->psccr.byte, j->XILINXbase + 0x01);
@@ -1241,26 +2024,42 @@ static int ixj_hookstate(IXJ *j)
        case QTI_PHONEJACK_LITE:
        case QTI_PHONEJACK_PCI:
                SLIC_GetState(j);
-               if (j->pld_slicr.bits.state == PLD_SLIC_STATE_ACTIVE ||
-                   j->pld_slicr.bits.state == PLD_SLIC_STATE_STANDBY) {
-                       if (j->flags.ringing) {
-                               if (!in_interrupt()) {
-                                       det = jiffies + (hertz / 50);
-                                       while (time_before(jiffies, det)) {
-                                               set_current_state(TASK_INTERRUPTIBLE);
-                                               schedule_timeout(1);
-                                       }
+               if(j->cardtype == QTI_LINEJACK && j->flags.pots_pstn == 1 && (j->readers || j->writers)) {
+                       fOffHook = j->pld_slicr.bits.potspstn ? 1 : 0;
+                       if(fOffHook != j->p_hook) {
+                               if(!j->checkwait) {
+                                       j->checkwait = jiffies;
+                               } 
+                               if(time_before(jiffies, j->checkwait + 2)) {
+                                       fOffHook ^= 1;
+                               } else {
+                                       j->checkwait = 0;
                                }
-                               SLIC_GetState(j);
-                               if (j->pld_slicr.bits.state == PLD_SLIC_STATE_RINGING) {
-                                       ixj_ring_on(j);
+                               j->p_hook = fOffHook;
+                               printk("IXJ : /dev/phone%d pots-pstn hookstate check %d at %ld\n", j->board, fOffHook, jiffies);
+                       }
+               } else {
+                       if (j->pld_slicr.bits.state == PLD_SLIC_STATE_ACTIVE ||
+                           j->pld_slicr.bits.state == PLD_SLIC_STATE_STANDBY) {
+                               if (j->flags.ringing || j->flags.cringing) {
+                                       if (!in_interrupt()) {
+                                               det = jiffies + (hertz / 50);
+                                               while (time_before(jiffies, det)) {
+                                                       set_current_state(TASK_INTERRUPTIBLE);
+                                                       schedule_timeout(1);
+                                               }
+                                       }
+                                       SLIC_GetState(j);
+                                       if (j->pld_slicr.bits.state == PLD_SLIC_STATE_RINGING) {
+                                               ixj_ring_on(j);
+                                       }
                                }
+                               if (j->cardtype == QTI_PHONEJACK_PCI) {
+                                       j->pld_scrr.byte = inb_p(j->XILINXbase);
+                                       fOffHook = j->pld_scrr.pcib.det ? 1 : 0;
+                               } else
+                                       fOffHook = j->pld_slicr.bits.det ? 1 : 0;
                        }
-                       if (j->cardtype == QTI_PHONEJACK_PCI) {
-                               j->pld_scrr.byte = inb_p(j->XILINXbase);
-                               fOffHook = j->pld_scrr.pcib.det ? 1 : 0;
-                       } else
-                               fOffHook = j->pld_slicr.bits.det ? 1 : 0;
                }
                break;
        case QTI_PHONECARD:
@@ -1269,34 +2068,49 @@ static int ixj_hookstate(IXJ *j)
        }
        if (j->r_hook != fOffHook) {
                j->r_hook = fOffHook;
-               if (j->port != PORT_POTS) {
+               if (j->port == PORT_SPEAKER || j->port == PORT_HANDSET) { // || (j->port == PORT_PSTN && j->flags.pots_pstn == 0)) {
                        j->ex.bits.hookstate = 1;
-                       ixj_kill_fasync(j, POLL_PRI);
+                       ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN);
                } else if (!fOffHook) {
-                       j->flash_end = jiffies + (hertz / 10 * 6);
+                       j->flash_end = jiffies + ((60 * hertz) / 100);
+               }
+       }
+       if (fOffHook) {
+               if(time_before(jiffies, j->flash_end)) {
+                       j->ex.bits.flash = 1;
+                       j->flash_end = 0;
+                       ixj_kill_fasync(j, SIG_FLASH, POLL_IN);
+               }
+       } else {
+               if(time_before(jiffies, j->flash_end)) {
+                       fOffHook = 1;
                }
        }
+
        if (j->port == PORT_PSTN && j->daa_mode == SOP_PU_CONVERSATION)
                fOffHook |= 2;
 
-       if (j->port == PORT_SPEAKER)
-               fOffHook |= 2;
+       if (j->port == PORT_SPEAKER) {
+               if(j->cardtype == QTI_PHONECARD) {
+                       if(j->flags.pcmciascp && j->flags.pcmciasct) {
+                               fOffHook |= 2;
+                       }
+               } else {
+                       fOffHook |= 2;
+               }
+       }
 
        if (j->port == PORT_HANDSET)
                fOffHook |= 2;
 
-       if (fOffHook && time_before(jiffies, j->flash_end))
-               return 0;
-       else
-               return fOffHook;
+       return fOffHook;
 }
 
 static void ixj_ring_off(IXJ *j)
 {
-
-       if (j->dsp.low == 0x20) // Internet PhoneJACK
+       if (j->dsp.low == 0x20) /* Internet PhoneJACK */
         {
-               if (ixjdebug > 0)
+               if (ixjdebug & 0x0004)
                        printk(KERN_INFO "IXJ Ring Off\n");
                j->gpio.bytes.high = 0x0B;
                j->gpio.bytes.low = 0x00;
@@ -1304,12 +2118,13 @@ static void ixj_ring_off(IXJ *j)
                j->gpio.bits.gpio2 = 1;
                j->gpio.bits.gpio5 = 0;
                ixj_WriteDSPCommand(j->gpio.word, j);
-       } else                  // Internet LineJACK
-        {
-               if (ixjdebug > 0)
+       } else                  /* Internet LineJACK */
+       {
+               if (ixjdebug & 0x0004)
                        printk(KERN_INFO "IXJ Ring Off\n");
 
-               SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
+               if(!j->flags.cidplay)
+                       SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
 
                SLIC_GetState(j);
        }
@@ -1318,10 +2133,20 @@ static void ixj_ring_off(IXJ *j)
 static void ixj_ring_start(IXJ *j)
 {
        j->flags.cringing = 1;
+       if (ixjdebug & 0x0004)
+               printk(KERN_INFO "IXJ Cadence Ringing Start /dev/phone%d\n", j->board);
        if (ixj_hookstate(j) & 1) {
                if (j->port == PORT_POTS)
                        ixj_ring_off(j);
                j->flags.cringing = 0;
+               if (ixjdebug & 0x0004)
+                       printk(KERN_INFO "IXJ Cadence Ringing Stopped /dev/phone%d off hook\n", j->board);
+       } else if(j->cadence_f[5].enable && (!j->cadence_f[5].en_filter)) {
+               j->ring_cadence_jif = jiffies;
+               j->flags.cidsent = j->flags.cidring = 0;
+               j->cadence_f[5].state = 0;
+               if(j->cadence_f[5].on1)
+                       ixj_ring_on(j);
        } else {
                j->ring_cadence_jif = jiffies;
                j->ring_cadence_t = 15;
@@ -1330,6 +2155,7 @@ static void ixj_ring_start(IXJ *j)
                } else {
                        ixj_ring_off(j);
                }
+               j->flags.cidsent = j->flags.cidring = j->flags.firstring = 0;
        }
 }
 
@@ -1386,12 +2212,10 @@ static int ixj_ring(IXJ *j)
        return 0;
 }
 
-int ixj_open(struct phone_device *p, struct file *file_p)
+static int ixj_open(struct phone_device *p, struct file *file_p)
 {
-       IXJ *j = file_p->private_data = ixj[p->board];
-
-       if (j == NULL)
-               return -ENODEV;
+       IXJ *j = get_ixj(p->board);
+       file_p->private_data = j;
 
        if (!j->DSPbase)
                return -ENODEV;
@@ -1423,7 +2247,12 @@ int ixj_open(struct phone_device *p, struct file *file_p)
                ixj_PCcontrol_wait(j);
        }
 
-       if (ixjdebug > 0)
+       j->flags.cidplay = 0;
+       j->flags.cidcw_ack = 0;
+
+       MOD_INC_USE_COUNT;
+
+       if (ixjdebug & 0x0002)
                printk(KERN_INFO "Opening board %d\n", p->board);
 
        j->framesread = j->frameswritten = 0;
@@ -1435,14 +2264,24 @@ int ixj_release(struct inode *inode, struct file *file_p)
        IXJ_TONE ti;
        int cnt;
        IXJ *j = file_p->private_data;
+       int board = j->p.board;
 
-       if (ixjdebug > 0)
+       /*
+        *    Set up locks to ensure that only one process is talking to the DSP at a time.
+        *    This is necessary to keep the DSP from locking up.
+        */
+       while(test_and_set_bit(board, (void *)&j->busyflags) != 0) {
+               set_current_state(TASK_INTERRUPTIBLE);
+               schedule_timeout(1);
+       }
+       if (ixjdebug & 0x0002)
                printk(KERN_INFO "Closing board %d\n", NUM(inode->i_rdev));
 
        if (j->cardtype == QTI_PHONECARD)
                ixj_set_port(j, PORT_SPEAKER);
        else
                ixj_set_port(j, PORT_POTS);
+
        aec_stop(j);
        ixj_play_stop(j);
        ixj_record_stop(j);
@@ -1450,22 +2289,25 @@ int ixj_release(struct inode *inode, struct file *file_p)
        set_rec_volume(j, 0x100);
        ixj_ring_off(j);
 
-       // Restore the tone table to default settings.
+       /* Restore the tone table to default settings. */
        ti.tone_index = 10;
        ti.gain0 = 1;
        ti.freq0 = hz941;
        ti.gain1 = 0;
        ti.freq1 = hz1209;
+       ixj_init_tone(j, &ti);
        ti.tone_index = 11;
        ti.gain0 = 1;
        ti.freq0 = hz941;
        ti.gain1 = 0;
        ti.freq1 = hz1336;
+       ixj_init_tone(j, &ti);
        ti.tone_index = 12;
        ti.gain0 = 1;
        ti.freq0 = hz941;
        ti.gain1 = 0;
        ti.freq1 = hz1477;
+       ixj_init_tone(j, &ti);
        ti.tone_index = 13;
        ti.gain0 = 1;
        ti.freq0 = hz800;
@@ -1557,9 +2399,9 @@ int ixj_release(struct inode *inode, struct file *file_p)
        ti.freq1 = hz620;
        ixj_init_tone(j, &ti);
 
-       set_rec_depth(j, 2);    // Set Record Channel Limit to 2 frames
+       set_rec_depth(j, 2);    /* Set Record Channel Limit to 2 frames */
 
-       set_play_depth(j, 2);   // Set Playback Channel Limit to 2 frames
+       set_play_depth(j, 2);   /* Set Playback Channel Limit to 2 frames */
 
        j->ex.bits.dtmf_ready = 0;
        j->dtmf_state = 0;
@@ -1568,6 +2410,9 @@ int ixj_release(struct inode *inode, struct file *file_p)
        j->flags.ringing = 0;
        j->maxrings = MAXRINGS;
        j->ring_cadence = USA_RING_CADENCE;
+       if(j->cadence_f[5].enable) {
+               j->cadence_f[5].enable = j->cadence_f[5].en_filter = j->cadence_f[5].state = 0;
+       }
        j->drybuffer = 0;
        j->winktime = 320;
        j->flags.dtmf_oob = 0;
@@ -1598,27 +2443,42 @@ int ixj_release(struct inode *inode, struct file *file_p)
        j->rec_codec = j->play_codec = 0;
        j->rec_frame_size = j->play_frame_size = 0;
        j->flags.cidsent = j->flags.cidring = 0;
-       ixj_fasync(-1, file_p, 0);      // remove from list of async notification
+       ixj_fasync(-1, file_p, 0);      /* remove from list of async notification */
 
        if(j->cardtype == QTI_LINEJACK && !j->readers && !j->writers) {
                ixj_set_port(j, PORT_PSTN);
                daa_set_mode(j, SOP_PU_SLEEP);
                ixj_set_pots(j, 1);
        }
-       ixj_WriteDSPCommand(0x0FE3, j); // Put the DSP in 1/5 power mode.
+       ixj_WriteDSPCommand(0x0FE3, j); /* Put the DSP in 1/5 power mode. */
+
+       /* Set up the default signals for events */
+       for (cnt = 0; cnt < 35; cnt++)
+               j->ixj_signals[cnt] = SIGIO;
+
+       /* Set the excetion signal enable flags */
+       j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring = 
+       j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 = 
+       j->ex_sig.bits.f3 = j->ex_sig.bits.fc0 = j->ex_sig.bits.fc1 = j->ex_sig.bits.fc2 = j->ex_sig.bits.fc3 = 1;
 
        file_p->private_data = NULL;
+       clear_bit(board, &j->busyflags);
+       MOD_DEC_USE_COUNT;
        return 0;
 }
 
 static int read_filters(IXJ *j)
 {
-       unsigned short fc, cnt;
+       unsigned short fc, cnt, trg;
        int var;
 
-       if (ixj_WriteDSPCommand(0x5144, j))
+       trg = 0;
+       if (ixj_WriteDSPCommand(0x5144, j)) {
+               if(ixjdebug & 0x0001) {
+                       printk(KERN_INFO "Read Frame Counter failed!\n");
+               }
                return -1;
-
+       }
        fc = j->ssr.high << 8 | j->ssr.low;
        if (fc == j->frame_count)
                return 1;
@@ -1631,65 +2491,97 @@ static int read_filters(IXJ *j)
        var = 10;
 
        for (cnt = 0; cnt < 4; cnt++) {
-               if (ixj_WriteDSPCommand(0x5154 + cnt, j))
+               if (ixj_WriteDSPCommand(0x5154 + cnt, j)) {
+                       if(ixjdebug & 0x0001) {
+                               printk(KERN_INFO "Select Filter %d failed!\n", cnt);
+                       }
                        return -1;
-
-               if (ixj_WriteDSPCommand(0x515C, j))
+               }
+               if (ixj_WriteDSPCommand(0x515C, j)) {
+                       if(ixjdebug & 0x0001) {
+                               printk(KERN_INFO "Read Filter History %d failed!\n", cnt);
+                       }
                        return -1;
-
+               }
                j->filter_hist[cnt] = j->ssr.high << 8 | j->ssr.low;
 
                if (j->cadence_f[cnt].enable) {
                        if (j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12)) {
                                if (j->cadence_f[cnt].state == 0) {
                                        j->cadence_f[cnt].state = 1;
-                                       j->cadence_f[cnt].on1min = jiffies + (j->cadence_f[cnt].on1 * hertz * (100 - var) / 10000);
-                                       j->cadence_f[cnt].on1dot = jiffies + (j->cadence_f[cnt].on1 * hertz * (100) / 10000);
-                                       j->cadence_f[cnt].on1max = jiffies + (j->cadence_f[cnt].on1 * hertz * (100 + var) / 10000);
+                                       j->cadence_f[cnt].on1min = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100 - var)) / 10000));
+                                       j->cadence_f[cnt].on1dot = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100)) / 10000));
+                                       j->cadence_f[cnt].on1max = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100 + var)) / 10000));
                                } else if (j->cadence_f[cnt].state == 2 &&
                                           (time_after(jiffies, j->cadence_f[cnt].off1min) &&
                                            time_before(jiffies, j->cadence_f[cnt].off1max))) {
                                        if (j->cadence_f[cnt].on2) {
                                                j->cadence_f[cnt].state = 3;
-                                               j->cadence_f[cnt].on2min = jiffies + (j->cadence_f[cnt].on2 * hertz * (100 - var) / 10000);
-                                               j->cadence_f[cnt].on2dot = jiffies + (j->cadence_f[cnt].on2 * hertz * (100) / 10000);
-                                               j->cadence_f[cnt].on2max = jiffies + (j->cadence_f[cnt].on2 * hertz * (100 + var) / 10000);
+                                               j->cadence_f[cnt].on2min = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100 - var)) / 10000));
+                                               j->cadence_f[cnt].on2dot = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100)) / 10000));
+                                               j->cadence_f[cnt].on2max = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100 + var)) / 10000));
                                        } else {
-                                               j->cadence_f[cnt].state = 6;
+                                               j->cadence_f[cnt].state = 7;
                                        }
                                } else if (j->cadence_f[cnt].state == 4 &&
                                           (time_after(jiffies, j->cadence_f[cnt].off2min) &&
                                            time_before(jiffies, j->cadence_f[cnt].off2max))) {
-                                       if (j->cadence_f[cnt].on2) {
+                                       if (j->cadence_f[cnt].on3) {
                                                j->cadence_f[cnt].state = 5;
-                                               j->cadence_f[cnt].on3min = jiffies + (j->cadence_f[cnt].on3 * hertz * (100 - var) / 10000);
-                                               j->cadence_f[cnt].on3dot = jiffies + (j->cadence_f[cnt].on3 * hertz * (100) / 10000);
-                                               j->cadence_f[cnt].on3max = jiffies + (j->cadence_f[cnt].on3 * hertz * (100 + var) / 10000);
+                                               j->cadence_f[cnt].on3min = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100 - var)) / 10000));
+                                               j->cadence_f[cnt].on3dot = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100)) / 10000));
+                                               j->cadence_f[cnt].on3max = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100 + var)) / 10000));
                                        } else {
-                                               j->cadence_f[cnt].state = 6;
+                                               j->cadence_f[cnt].state = 7;
                                        }
                                } else {
                                        j->cadence_f[cnt].state = 0;
                                }
                        } else if (j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3)) {
-                               if (j->cadence_f[cnt].state == 1 &&
-                                   (time_after(jiffies, j->cadence_f[cnt].on1min) &&
-                                    time_before(jiffies, j->cadence_f[cnt].on1max))) {
-                                       j->cadence_f[cnt].state = 2;
-                                       j->cadence_f[cnt].off1min = jiffies + (j->cadence_f[cnt].off1 * hertz * (100 - var) / 10000);
-                                       j->cadence_f[cnt].off1max = jiffies + (j->cadence_f[cnt].off1 * hertz * (100 + var) / 10000);
-                               } else if (j->cadence_f[cnt].state == 3 &&
-                                          (time_after(jiffies, j->cadence_f[cnt].on2min) &&
+                               if (j->cadence_f[cnt].state == 1) {
+                                       if(!j->cadence_f[cnt].on1) {
+                                               j->cadence_f[cnt].state = 7;
+                                       } else if((time_after(jiffies, j->cadence_f[cnt].on1min) &&
+                                         time_before(jiffies, j->cadence_f[cnt].on1max))) {
+                                               if(j->cadence_f[cnt].off1) {
+                                                       j->cadence_f[cnt].state = 2;
+                                                       j->cadence_f[cnt].off1min = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100 - var)) / 10000));
+                                                       j->cadence_f[cnt].off1dot = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100)) / 10000));
+                                                       j->cadence_f[cnt].off1max = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100 + var)) / 10000));
+                                               } else {
+                                                       j->cadence_f[cnt].state = 7;
+                                               }
+                                       } else {
+                                               j->cadence_f[cnt].state = 0;
+                                       }
+                               } else if (j->cadence_f[cnt].state == 3) {
+                                       if((time_after(jiffies, j->cadence_f[cnt].on2min) &&
                                            time_before(jiffies, j->cadence_f[cnt].on2max))) {
-                                       j->cadence_f[cnt].state = 4;
-                                       j->cadence_f[cnt].off2min = jiffies + (j->cadence_f[cnt].off2 * hertz * (100 - var) / 10000);
-                                       j->cadence_f[cnt].off2max = jiffies + (j->cadence_f[cnt].off2 * hertz * (100 + var) / 10000);
-                               } else if (j->cadence_f[cnt].state == 5 &&
-                                          (time_after(jiffies, j->cadence_f[cnt].on3min) &&
+                                               if(j->cadence_f[cnt].off2) {
+                                                       j->cadence_f[cnt].state = 4;
+                                                       j->cadence_f[cnt].off2min = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100 - var)) / 10000));
+                                                       j->cadence_f[cnt].off2dot = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100)) / 10000));
+                                                       j->cadence_f[cnt].off2max = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100 + var)) / 10000));
+                                               } else {
+                                                       j->cadence_f[cnt].state = 7;
+                                               }
+                                       } else {
+                                               j->cadence_f[cnt].state = 0;
+                                       }
+                               } else if (j->cadence_f[cnt].state == 5) {
+                                       if ((time_after(jiffies, j->cadence_f[cnt].on3min) &&
                                            time_before(jiffies, j->cadence_f[cnt].on3max))) {
-                                       j->cadence_f[cnt].state = 6;
-                                       j->cadence_f[cnt].off3min = jiffies + (j->cadence_f[cnt].off3 * hertz * (100 - var) / 10000);
-                                       j->cadence_f[cnt].off3max = jiffies + (j->cadence_f[cnt].off3 * hertz * (100 + var) / 10000);
+                                               if(j->cadence_f[cnt].off3) {
+                                                       j->cadence_f[cnt].state = 6;
+                                                       j->cadence_f[cnt].off3min = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100 - var)) / 10000));
+                                                       j->cadence_f[cnt].off3dot = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100)) / 10000));
+                                                       j->cadence_f[cnt].off3max = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100 + var)) / 10000));
+                                               } else {
+                                                       j->cadence_f[cnt].state = 7;
+                                               }
+                                       } else {
+                                               j->cadence_f[cnt].state = 0;
+                                       }
                                } else {
                                        j->cadence_f[cnt].state = 0;
                                }
@@ -1700,58 +2592,128 @@ static int read_filters(IXJ *j)
                                                   !j->cadence_f[cnt].off1 &&
                                                   !j->cadence_f[cnt].on2 && !j->cadence_f[cnt].off2 &&
                                                   !j->cadence_f[cnt].on3 && !j->cadence_f[cnt].off3) {
-                                                       j->cadence_f[cnt].state = 6;
+                                                       j->cadence_f[cnt].state = 7;
                                                }
                                                break;
                                        case 3:
                                                if(time_after(jiffies, j->cadence_f[cnt].on2dot) &&
                                                   !j->cadence_f[cnt].off2 &&
                                                   !j->cadence_f[cnt].on3 && !j->cadence_f[cnt].off3) {
-                                                       j->cadence_f[cnt].state = 6;
+                                                       j->cadence_f[cnt].state = 7;
                                                }
                                                break;
                                        case 5:
                                                if(time_after(jiffies, j->cadence_f[cnt].on3dot) &&
                                                   !j->cadence_f[cnt].off3) {
-                                                       j->cadence_f[cnt].state = 6;
+                                                       j->cadence_f[cnt].state = 7;
                                                }
                                                break;
                                }
                        }
+
+                       if (ixjdebug & 0x0040) {
+                               printk(KERN_INFO "IXJ Tone Cadence state = %d /dev/phone%d at %ld\n", j->cadence_f[cnt].state, j->board, jiffies);
+                               switch(j->cadence_f[cnt].state) {
+                                       case 0:
+                                               printk(KERN_INFO "IXJ /dev/phone%d No Tone detected\n", j->board);
+                                               break;
+                                       case 1:
+                                               printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %u %ld - %ld - %ld\n", j->board,
+                                       j->cadence_f[cnt].on1, j->cadence_f[cnt].on1min, j->cadence_f[cnt].on1dot, j->cadence_f[cnt].on1max);
+                                               break;
+                                       case 2:
+                                               printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off1min, 
+                                                                                                                       j->cadence_f[cnt].off1max);
+                                               break;
+                                       case 3:
+                                               printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].on2min,
+                                                                                                                       j->cadence_f[cnt].on2max);
+                                               break;
+                                       case 4:
+                                               printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off2min,
+                                                                                                                       j->cadence_f[cnt].off2max);
+                                               break;
+                                       case 5:
+                                               printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].on3min,
+                                                                                                                       j->cadence_f[cnt].on3max);
+                                               break;
+                                       case 6: 
+                                               printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off3min,
+                                                                                                                       j->cadence_f[cnt].off3max);
+                                               break;
+                               }
+                       } 
                }
-               if (j->cadence_f[cnt].state == 6) {
+               if (j->cadence_f[cnt].state == 7) {
                        j->cadence_f[cnt].state = 0;
                        if (j->cadence_f[cnt].enable == 1)
                                j->cadence_f[cnt].enable = 0;
                        switch (cnt) {
                        case 0:
+                               if(ixjdebug & 0x0020) {
+                                       printk(KERN_INFO "Filter Cadence 0 triggered %ld\n", jiffies);
+                               }
                                j->ex.bits.fc0 = 1;
+                               ixj_kill_fasync(j, SIG_FC0, POLL_IN);
                                break;
                        case 1:
+                               if(ixjdebug & 0x0020) {
+                                       printk(KERN_INFO "Filter Cadence 1 triggered %ld\n", jiffies);
+                               }
                                j->ex.bits.fc1 = 1;
+                               ixj_kill_fasync(j, SIG_FC1, POLL_IN);
                                break;
                        case 2:
+                               if(ixjdebug & 0x0020) {
+                                       printk(KERN_INFO "Filter Cadence 2 triggered %ld\n", jiffies);
+                               }
                                j->ex.bits.fc2 = 1;
+                               ixj_kill_fasync(j, SIG_FC2, POLL_IN);
                                break;
                        case 3:
+                               if(ixjdebug & 0x0020) {
+                                       printk(KERN_INFO "Filter Cadence 3 triggered %ld\n", jiffies);
+                               }
                                j->ex.bits.fc3 = 1;
+                               ixj_kill_fasync(j, SIG_FC3, POLL_IN);
                                break;
                        }
                }
                if (j->filter_en[cnt] && ((j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12)) ||
                                          (j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3)))) {
+                       if((j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12))) {
+                               trg = 1;
+                       } else if((j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3))) {
+                               trg = 0;
+                       }
                        switch (cnt) {
                        case 0:
+                               if(ixjdebug & 0x0020) {
+                                       printk(KERN_INFO "Filter 0 triggered %d at %ld\n", trg, jiffies);
+                               }
                                j->ex.bits.f0 = 1;
+                               ixj_kill_fasync(j, SIG_F0, POLL_IN);
                                break;
                        case 1:
+                               if(ixjdebug & 0x0020) {
+                                       printk(KERN_INFO "Filter 1 triggered %d at %ld\n", trg, jiffies);
+                               }
                                j->ex.bits.f1 = 1;
+                               ixj_kill_fasync(j, SIG_F1, POLL_IN);
                                break;
                        case 2:
+                               if(ixjdebug & 0x0020) {
+                                       printk(KERN_INFO "Filter 2 triggered %d at %ld\n", trg, jiffies);
+                               }
                                j->ex.bits.f2 = 1;
+                               ixj_kill_fasync(j, SIG_F2, POLL_IN);
                                break;
                        case 3:
+                               if(ixjdebug & 0x0020) {
+                                       printk(KERN_INFO "Filter 3 triggered %d at %ld\n", trg, jiffies);
+                               }
                                j->ex.bits.f3 = 1;
+                               ixj_kill_fasync(j, SIG_F3, POLL_IN);
                                break;
                        }
                }
@@ -1766,7 +2728,7 @@ static int LineMonitor(IXJ *j)
        }
        j->dtmf_proc = 1;
 
-       if (ixj_WriteDSPCommand(0x7000, j))             // Line Monitor
+       if (ixj_WriteDSPCommand(0x7000, j))             /* Line Monitor */
                return -1;
 
        j->dtmf.bytes.high = j->ssr.high;
@@ -1775,16 +2737,22 @@ static int LineMonitor(IXJ *j)
                j->dtmf_state = 1;
                j->dtmf_current = j->dtmf.bits.digit;
        }
-       if (j->dtmf_state && !j->dtmf.bits.dtmf_valid)  // && j->dtmf_wp != j->dtmf_rp)
+       if (j->dtmf_state && !j->dtmf.bits.dtmf_valid)  /* && j->dtmf_wp != j->dtmf_rp) */
         {
-               if(!j->flags.cidplay) {
+               if(!j->cidcw_wait) {
                        j->dtmfbuffer[j->dtmf_wp] = j->dtmf_current;
                        j->dtmf_wp++;
                        if (j->dtmf_wp == 79)
                                j->dtmf_wp = 0;
                        j->ex.bits.dtmf_ready = 1;
+                       if(j->ex_sig.bits.dtmf_ready) {
+                               ixj_kill_fasync(j, SIG_DTMF_READY, POLL_IN);
+                       }
                }
-               else if(j->dtmf_current == 25 || j->dtmf_current == 31) {
+               else if(j->dtmf_current == 0x00 || j->dtmf_current == 0x0D) {
+                       if(ixjdebug & 0x0020) {
+                               printk("IXJ phone%d saw CIDCW Ack DTMF %d from display at %ld\n", j->board, j->dtmf_current, jiffies);
+                       }
                        j->flags.cidcw_ack = 1;
                }
                j->dtmf_state = 0;
@@ -1794,14 +2762,102 @@ static int LineMonitor(IXJ *j)
        return 0;
 }
 
-ssize_t ixj_read(struct file * file_p, char *buf, size_t length, loff_t * ppos)
+/************************************************************************
+*
+* Functions to allow alaw <-> ulaw conversions.
+*
+************************************************************************/
+
+static void ulaw2alaw(unsigned char *buff, unsigned long len)
+{
+       static unsigned char table_ulaw2alaw[] =
+       {
+               0x2A, 0x2B, 0x28, 0x29, 0x2E, 0x2F, 0x2C, 0x2D, 
+               0x22, 0x23, 0x20, 0x21, 0x26, 0x27, 0x24, 0x25, 
+               0x3A, 0x3B, 0x38, 0x39, 0x3E, 0x3F, 0x3C, 0x3D, 
+               0x32, 0x33, 0x30, 0x31, 0x36, 0x37, 0x34, 0x35, 
+               0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, 0x02, 
+               0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, 0x1A, 
+               0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, 0x12, 
+               0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, 0x6B, 
+               0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D, 0x62, 0x63, 
+               0x60, 0x61, 0x66, 0x67, 0x64, 0x65, 0x7B, 0x79, 
+               0x7E, 0x7F, 0x7C, 0x7D, 0x72, 0x73, 0x70, 0x71, 
+               0x76, 0x77, 0x74, 0x75, 0x4B, 0x49, 0x4F, 0x4D, 
+               0x42, 0x43, 0x40, 0x41, 0x46, 0x47, 0x44, 0x45, 
+               0x5A, 0x5B, 0x58, 0x59, 0x5E, 0x5F, 0x5C, 0x5D, 
+               0x52, 0x52, 0x53, 0x53, 0x50, 0x50, 0x51, 0x51, 
+               0x56, 0x56, 0x57, 0x57, 0x54, 0x54, 0x55, 0xD5, 
+               0xAA, 0xAB, 0xA8, 0xA9, 0xAE, 0xAF, 0xAC, 0xAD, 
+               0xA2, 0xA3, 0xA0, 0xA1, 0xA6, 0xA7, 0xA4, 0xA5, 
+               0xBA, 0xBB, 0xB8, 0xB9, 0xBE, 0xBF, 0xBC, 0xBD, 
+               0xB2, 0xB3, 0xB0, 0xB1, 0xB6, 0xB7, 0xB4, 0xB5, 
+               0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D, 0x82, 
+               0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, 0x9A, 
+               0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D, 0x92, 
+               0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, 0xEB, 
+               0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED, 0xE2, 0xE3, 
+               0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5, 0xFB, 0xF9, 
+               0xFE, 0xFF, 0xFC, 0xFD, 0xF2, 0xF3, 0xF0, 0xF1, 
+               0xF6, 0xF7, 0xF4, 0xF5, 0xCB, 0xC9, 0xCF, 0xCD, 
+               0xC2, 0xC3, 0xC0, 0xC1, 0xC6, 0xC7, 0xC4, 0xC5, 
+               0xDA, 0xDB, 0xD8, 0xD9, 0xDE, 0xDF, 0xDC, 0xDD, 
+               0xD2, 0xD2, 0xD3, 0xD3, 0xD0, 0xD0, 0xD1, 0xD1, 
+               0xD6, 0xD6, 0xD7, 0xD7, 0xD4, 0xD4, 0xD5, 0xD5
+       };
+
+       while (len--)
+               *buff++ = table_ulaw2alaw[*(unsigned char *)buff];
+}
+
+static void alaw2ulaw(unsigned char *buff, unsigned long len)
+{
+       static unsigned char table_alaw2ulaw[] =
+       {
+               0x29, 0x2A, 0x27, 0x28, 0x2D, 0x2E, 0x2B, 0x2C, 
+               0x21, 0x22, 0x1F, 0x20, 0x25, 0x26, 0x23, 0x24, 
+               0x39, 0x3A, 0x37, 0x38, 0x3D, 0x3E, 0x3B, 0x3C, 
+               0x31, 0x32, 0x2F, 0x30, 0x35, 0x36, 0x33, 0x34, 
+               0x0A, 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, 
+               0x02, 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, 
+               0x1A, 0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, 
+               0x12, 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, 
+               0x62, 0x63, 0x60, 0x61, 0x66, 0x67, 0x64, 0x65, 
+               0x5D, 0x5D, 0x5C, 0x5C, 0x5F, 0x5F, 0x5E, 0x5E, 
+               0x74, 0x76, 0x70, 0x72, 0x7C, 0x7E, 0x78, 0x7A, 
+               0x6A, 0x6B, 0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D, 
+               0x48, 0x49, 0x46, 0x47, 0x4C, 0x4D, 0x4A, 0x4B, 
+               0x40, 0x41, 0x3F, 0x3F, 0x44, 0x45, 0x42, 0x43, 
+               0x56, 0x57, 0x54, 0x55, 0x5A, 0x5B, 0x58, 0x59, 
+               0x4F, 0x4F, 0x4E, 0x4E, 0x52, 0x53, 0x50, 0x51, 
+               0xA9, 0xAA, 0xA7, 0xA8, 0xAD, 0xAE, 0xAB, 0xAC, 
+               0xA1, 0xA2, 0x9F, 0xA0, 0xA5, 0xA6, 0xA3, 0xA4, 
+               0xB9, 0xBA, 0xB7, 0xB8, 0xBD, 0xBE, 0xBB, 0xBC, 
+               0xB1, 0xB2, 0xAF, 0xB0, 0xB5, 0xB6, 0xB3, 0xB4, 
+               0x8A, 0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D, 
+               0x82, 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, 
+               0x9A, 0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D, 
+               0x92, 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, 
+               0xE2, 0xE3, 0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5, 
+               0xDD, 0xDD, 0xDC, 0xDC, 0xDF, 0xDF, 0xDE, 0xDE, 
+               0xF4, 0xF6, 0xF0, 0xF2, 0xFC, 0xFE, 0xF8, 0xFA, 
+               0xEA, 0xEB, 0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED, 
+               0xC8, 0xC9, 0xC6, 0xC7, 0xCC, 0xCD, 0xCA, 0xCB, 
+               0xC0, 0xC1, 0xBF, 0xBF, 0xC4, 0xC5, 0xC2, 0xC3, 
+               0xD6, 0xD7, 0xD4, 0xD5, 0xDA, 0xDB, 0xD8, 0xD9, 
+               0xCF, 0xCF, 0xCE, 0xCE, 0xD2, 0xD3, 0xD0, 0xD1
+       };
+
+        while (len--)
+                *buff++ = table_alaw2ulaw[*(unsigned char *)buff];
+}
+
+static ssize_t ixj_read(struct file * file_p, char *buf, size_t length, loff_t * ppos)
 {
        unsigned long i = *ppos;
-       IXJ *j = ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
-       DECLARE_WAITQUEUE(wait, current);
+       IXJ * j = get_ixj(NUM(file_p->f_dentry->d_inode->i_rdev));
 
-       if (j == NULL) /* shouldn't happen! */
-               return -ENODEV;
+       DECLARE_WAITQUEUE(wait, current);
 
        if (j->flags.inread)
                return -EALREADY;
@@ -1814,12 +2870,6 @@ ssize_t ixj_read(struct file * file_p, char *buf, size_t length, loff_t * ppos)
 
        while (!j->read_buffer_ready || (j->dtmf_state && j->flags.dtmf_oob)) {
                ++j->read_wait;
-               if(j->tone_state) {
-                       set_current_state(TASK_RUNNING);
-                       remove_wait_queue(&j->read_q, &wait);
-                       j->flags.inread = 0;
-                       return -EAGAIN;
-               }
                if (file_p->f_flags & O_NONBLOCK) {
                        set_current_state(TASK_RUNNING);
                        remove_wait_queue(&j->read_q, &wait);
@@ -1844,27 +2894,25 @@ ssize_t ixj_read(struct file * file_p, char *buf, size_t length, loff_t * ppos)
        remove_wait_queue(&j->read_q, &wait);
        set_current_state(TASK_RUNNING);
        /* Don't ever copy more than the user asks */
-       i = copy_to_user(buf, j->read_buffer,
-                        min(unsigned int, length, j->read_buffer_size));
+       if(j->rec_codec == ALAW)
+               ulaw2alaw(j->read_buffer, min(length, j->read_buffer_size));
+       i = copy_to_user(buf, j->read_buffer, min(length, j->read_buffer_size));
        j->read_buffer_ready = 0;
        if (i) {
                j->flags.inread = 0;
                return -EFAULT;
        } else {
                j->flags.inread = 0;
-               return min(unsigned int, length, j->read_buffer_size);
+               return min(length, j->read_buffer_size);
        }
 }
 
-ssize_t ixj_enhanced_read(struct file * file_p, char *buf, size_t length,
+static ssize_t ixj_enhanced_read(struct file * file_p, char *buf, size_t length,
                          loff_t * ppos)
 {
        int pre_retval;
        ssize_t read_retval = 0;
-       IXJ *j = ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
-
-       if (j == NULL) /* shouldn't happen! */
-               return -ENODEV;
+       IXJ *j = get_ixj(NUM(file_p->f_dentry->d_inode->i_rdev));
 
        pre_retval = ixj_PreRead(j, 0L);
        switch (pre_retval) {
@@ -1884,14 +2932,12 @@ ssize_t ixj_enhanced_read(struct file * file_p, char *buf, size_t length,
        return read_retval;
 }
 
-ssize_t ixj_write(struct file *file_p, const char *buf, size_t count, loff_t * ppos)
+static ssize_t ixj_write(struct file *file_p, const char *buf, size_t count, loff_t * ppos)
 {
        unsigned long i = *ppos;
        IXJ *j = file_p->private_data;
-       DECLARE_WAITQUEUE(wait, current);
 
-       if (j == NULL) /* shouldn't happen! */
-               return -ENODEV;
+       DECLARE_WAITQUEUE(wait, current);
 
        if (j->flags.inwrite)
                return -EALREADY;
@@ -1905,12 +2951,6 @@ ssize_t ixj_write(struct file *file_p, const char *buf, size_t count, loff_t * p
 
        while (!j->write_buffers_empty) {
                ++j->write_wait;
-               if(j->tone_state) {
-                       set_current_state(TASK_RUNNING);
-                       remove_wait_queue(&j->write_q, &wait);
-                       j->flags.inwrite = 0;
-                       return -EAGAIN;
-               }
                if (file_p->f_flags & O_NONBLOCK) {
                        set_current_state(TASK_RUNNING);
                        remove_wait_queue(&j->write_q, &wait);
@@ -1935,30 +2975,29 @@ ssize_t ixj_write(struct file *file_p, const char *buf, size_t count, loff_t * p
        remove_wait_queue(&j->write_q, &wait);
        if (j->write_buffer_wp + count >= j->write_buffer_end)
                j->write_buffer_wp = j->write_buffer;
-       i = copy_from_user(j->write_buffer_wp, buf,
-                          min(unsigned int, count, j->write_buffer_size));
+       i = copy_from_user(j->write_buffer_wp, buf, min(count, j->write_buffer_size));
        if (i) {
                j->flags.inwrite = 0;
                return -EFAULT;
        }
+       if(j->play_codec == ALAW)
+               alaw2ulaw(j->write_buffer_wp, min(count, j->write_buffer_size));
        j->flags.inwrite = 0;
-       return min(unsigned int, count, j->write_buffer_size);
+       return min(count, j->write_buffer_size);
 }
 
-ssize_t ixj_enhanced_write(struct file * file_p, const char *buf, size_t count, loff_t * ppos)
+static ssize_t ixj_enhanced_write(struct file * file_p, const char *buf, size_t count, loff_t * ppos)
 {
        int pre_retval;
        ssize_t write_retval = 0;
-       IXJ *j = ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
 
-       if (j == NULL) /* shouldn't happen! */
-               return -ENODEV;
+       IXJ *j = get_ixj(NUM(file_p->f_dentry->d_inode->i_rdev));
 
        pre_retval = ixj_PreWrite(j, 0L);
        switch (pre_retval) {
        case NORMAL:
                write_retval = ixj_write(file_p, buf, count, ppos);
-               if (write_retval != -EFAULT) {
+               if (write_retval > 0) {
                        ixj_PostWrite(j, 0L);
                        j->write_buffer_wp += write_retval;
                        j->write_buffers_empty--;
@@ -1966,7 +3005,7 @@ ssize_t ixj_enhanced_write(struct file * file_p, const char *buf, size_t count,
                break;
        case NOPOST:
                write_retval = ixj_write(file_p, buf, count, ppos);
-               if (write_retval != -EFAULT) {
+               if (write_retval > 0) {
                        j->write_buffer_wp += write_retval;
                        j->write_buffers_empty--;
                }
@@ -1996,8 +3035,8 @@ static void ixj_read_frame(IXJ *j)
                                        udelay(10);
                                }
                        }
-                       // Throw away word 0 of the 8021 compressed format to get standard G.729.
-                       if (j->rec_codec == G729 && (cnt == 0 || cnt == 5 || cnt == 10)) {
+                       /* Throw away word 0 of the 8021 compressed format to get standard G.729. */
+                       if (j->rec_codec == G729 && (cnt == 0 || cnt == 10 || cnt == 20)) {
                                inb_p(j->DSPbase + 0x0E);
                                inb_p(j->DSPbase + 0x0F);
                        }
@@ -2006,15 +3045,7 @@ static void ixj_read_frame(IXJ *j)
                }
                ++j->framesread;
                if (j->intercom != -1) {
-                       IXJ *icom = ixj[j->intercom];
-
-                       if (icom == NULL) { /* shouldn't happen! */
-                               printk(KERN_ERR "ixj_read_frame(): j->intercom = %d = NULL!",
-                                      j->intercom);
-                               return;
-                       }
-
-                       if (IsTxReady(icom)) {
+                       if (IsTxReady(get_ixj(j->intercom))) {
                                for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) {
                                        if (!(cnt % 16) && !IsTxReady(j)) {
                                                dly = 0;
@@ -2026,18 +3057,19 @@ static void ixj_read_frame(IXJ *j)
                                                        udelay(10);
                                                }
                                        }
-                                       outb_p(*(j->read_buffer + cnt), icom->DSPbase + 0x0C);
-                                       outb_p(*(j->read_buffer + cnt + 1), icom->DSPbase + 0x0D);
+                                       outb_p(*(j->read_buffer + cnt), get_ixj(j->intercom)->DSPbase + 0x0C);
+                                       outb_p(*(j->read_buffer + cnt + 1), get_ixj(j->intercom)->DSPbase + 0x0D);
                                }
-                               ++icom->frameswritten;
+                               get_ixj(j->intercom)->frameswritten++;
                        }
                } else {
                        j->read_buffer_ready = 1;
-                       wake_up_interruptible(&j->read_q);      // Wake any blocked readers
+                       wake_up_interruptible(&j->read_q);      /* Wake any blocked readers */
 
-                       wake_up_interruptible(&j->poll_q);      // Wake any blocked selects
+                       wake_up_interruptible(&j->poll_q);      /* Wake any blocked selects */
 
-                       ixj_kill_fasync(j, POLL_IN);
+                       if(j->ixj_signals[SIG_READ_READY])
+                               ixj_kill_fasync(j, SIG_READ_READY, POLL_OUT);
                }
        }
 }
@@ -2101,25 +3133,10 @@ static short fsk[][6][20] =
 
 static void ixj_write_cid_bit(IXJ *j, int bit)
 {
-       int dly;
-       IXJ_WORD dat;
-
        while (j->fskcnt < 20) {
-               if (!IsTxReady(j)) {
-                       dly = 0;
-                       while (!IsTxReady(j)) {
-                               if (dly++ > 5) {
-                                       dly = 0;
-                                       //      break;
-                                       //      printk("CID delay\n");
-                               }
-                               udelay(10);
-                       }
-               }
-               dat.word = j->fskdata[j->fskdcnt++] =
-                   fsk[bit][j->fskz][j->fskcnt];
-               outb_p(dat.bytes.low, j->DSPbase + 0x0C);
-               outb_p(dat.bytes.high, j->DSPbase + 0x0D);
+               if(j->fskdcnt < (j->fsksize - 1))
+                       j->fskdata[j->fskdcnt++] = fsk[bit][j->fskz][j->fskcnt];
+
                j->fskcnt += 3;
        }
        j->fskcnt %= 20;
@@ -2131,52 +3148,51 @@ static void ixj_write_cid_bit(IXJ *j, int bit)
 
 }
 
-static void ixj_write_cid_byte(IXJ *board, char byte)
+static void ixj_write_cid_byte(IXJ *j, char byte)
 {
        IXJ_CBYTE cb;
 
-//  printk("Writing CID data %x - %c\n", byte, byte);
-       cb.cbyte = byte;
-       ixj_write_cid_bit(board, 0);
-       ixj_write_cid_bit(board, cb.cbits.b0 ? 1 : 0);
-       ixj_write_cid_bit(board, cb.cbits.b1 ? 1 : 0);
-       ixj_write_cid_bit(board, cb.cbits.b2 ? 1 : 0);
-       ixj_write_cid_bit(board, cb.cbits.b3 ? 1 : 0);
-       ixj_write_cid_bit(board, cb.cbits.b4 ? 1 : 0);
-       ixj_write_cid_bit(board, cb.cbits.b5 ? 1 : 0);
-       ixj_write_cid_bit(board, cb.cbits.b6 ? 1 : 0);
-       ixj_write_cid_bit(board, cb.cbits.b7 ? 1 : 0);
-       ixj_write_cid_bit(board, 1);
+               cb.cbyte = byte;
+               ixj_write_cid_bit(j, 0);
+               ixj_write_cid_bit(j, cb.cbits.b0 ? 1 : 0);
+               ixj_write_cid_bit(j, cb.cbits.b1 ? 1 : 0);
+               ixj_write_cid_bit(j, cb.cbits.b2 ? 1 : 0);
+               ixj_write_cid_bit(j, cb.cbits.b3 ? 1 : 0);
+               ixj_write_cid_bit(j, cb.cbits.b4 ? 1 : 0);
+               ixj_write_cid_bit(j, cb.cbits.b5 ? 1 : 0);
+               ixj_write_cid_bit(j, cb.cbits.b6 ? 1 : 0);
+               ixj_write_cid_bit(j, cb.cbits.b7 ? 1 : 0);
+               ixj_write_cid_bit(j, 1);
 }
 
-static void ixj_write_cid_seize(IXJ *board)
+static void ixj_write_cid_seize(IXJ *j)
 {
        int cnt;
 
        for (cnt = 0; cnt < 150; cnt++) {
-               ixj_write_cid_bit(board, 0);
-               ixj_write_cid_bit(board, 1);
+               ixj_write_cid_bit(j, 0);
+               ixj_write_cid_bit(j, 1);
        }
        for (cnt = 0; cnt < 180; cnt++) {
-               ixj_write_cid_bit(board, 1);
+               ixj_write_cid_bit(j, 1);
        }
 }
 
-static void ixj_write_cidcw_seize(IXJ *board)
+static void ixj_write_cidcw_seize(IXJ *j)
 {
        int cnt;
 
        for (cnt = 0; cnt < 80; cnt++) {
-               ixj_write_cid_bit(board, 1);
+               ixj_write_cid_bit(j, 1);
        }
 }
 
-static int ixj_write_cid_string(IXJ *board, char *s, int checksum)
+static int ixj_write_cid_string(IXJ *j, char *s, int checksum)
 {
        int cnt;
 
        for (cnt = 0; cnt < strlen(s); cnt++) {
-               ixj_write_cid_byte(board, s[cnt]);
+               ixj_write_cid_byte(j, s[cnt]);
                checksum = (checksum + s[cnt]);
        }
        return checksum;
@@ -2184,33 +3200,85 @@ static int ixj_write_cid_string(IXJ *board, char *s, int checksum)
 
 static void ixj_pad_fsk(IXJ *j, int pad)
 {
-       int cnt, dly;
+       int cnt
 
        for (cnt = 0; cnt < pad; cnt++) {
-               if (!IsTxReady(j)) {
-                       dly = 0;
-                       while (!IsTxReady(j)) {
-                               if (dly++ > 5) {
-                                       dly = 0;
-                               }
-                               udelay(10);
-                       }
-               }
-               outb_p(0x00, j->DSPbase + 0x0C);
-               outb_p(0x00, j->DSPbase + 0x0D);
+               if(j->fskdcnt < (j->fsksize - 1))
+                       j->fskdata[j->fskdcnt++] = 0x0000;
        }
        for (cnt = 0; cnt < 720; cnt++) {
-               if (!IsTxReady(j)) {
-                       dly = 0;
-                       while (!IsTxReady(j)) {
-                               if (dly++ > 5) {
-                                       dly = 0;
-                               }
-                               udelay(10);
-                       }
-               }
-               outb_p(0x00, j->DSPbase + 0x0C);
-               outb_p(0x00, j->DSPbase + 0x0D);
+               if(j->fskdcnt < (j->fsksize - 1))
+                       j->fskdata[j->fskdcnt++] = 0x0000;
+       }
+}
+
+static void ixj_pre_cid(IXJ *j)
+{
+       j->cid_play_codec = j->play_codec;
+       j->cid_play_frame_size = j->play_frame_size;
+       j->cid_play_volume = get_play_volume(j);
+       j->cid_play_flag = j->flags.playing;
+
+       j->cid_rec_codec = j->rec_codec;
+       j->cid_rec_volume = get_rec_volume(j);
+       j->cid_rec_flag = j->flags.recording;
+
+       j->cid_play_aec_level = j->aec_level;
+
+       switch(j->baseframe.low) {
+               case 0xA0:
+                       j->cid_base_frame_size = 20;
+                       break;
+               case 0x50:
+                       j->cid_base_frame_size = 10;
+                       break;
+               case 0xF0:
+                       j->cid_base_frame_size = 30;
+                       break;
+       }
+
+       ixj_play_stop(j);
+       ixj_cpt_stop(j);
+
+       j->flags.cidplay = 1;
+
+       set_base_frame(j, 30);
+       set_play_codec(j, LINEAR16);
+       set_play_volume(j, 0x1B);
+       ixj_play_start(j);
+}
+
+static void ixj_post_cid(IXJ *j)
+{
+       ixj_play_stop(j);
+
+       if(j->cidsize > 5000) {
+               SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
+       }
+       j->flags.cidplay = 0;
+       if(ixjdebug & 0x0200) {
+               printk("IXJ phone%d Finished Playing CallerID data %ld\n", j->board, jiffies);
+       }
+
+       ixj_fsk_free(j);
+
+       j->fskdcnt = 0;
+       set_base_frame(j, j->cid_base_frame_size);
+       set_play_codec(j, j->cid_play_codec);
+       ixj_aec_start(j, j->cid_play_aec_level);
+       set_play_volume(j, j->cid_play_volume);
+
+       set_rec_codec(j, j->cid_rec_codec);
+       set_rec_volume(j, j->cid_rec_volume);
+
+       if(j->cid_rec_flag)
+               ixj_record_start(j);
+
+       if(j->cid_play_flag)
+               ixj_play_start(j);
+
+       if(j->cid_play_flag) {
+               wake_up_interruptible(&j->write_q);     /* Wake any blocked writers */
        }
 }
 
@@ -2224,13 +3292,13 @@ static void ixj_write_cid(IXJ *j)
 
        int checksum = 0;
 
-       if (j->dsp.low == 0x20)
+       if (j->dsp.low == 0x20 || j->flags.cidplay)
                return;
 
-       j->fskz = j->fskphase = j->fskcnt =
-           j->fskdcnt = 0;
+       j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0;
+       j->cidsize = j->cidcnt = 0;
 
-       j->flags.cidplay = 1;
+       ixj_fsk_alloc(j);
 
        strcpy(sdmf1, j->cid_send.month);
        strcat(sdmf1, j->cid_send.day);
@@ -2244,54 +3312,53 @@ static void ixj_write_cid(IXJ *j)
        len3 = strlen(sdmf3);
        mdmflen = len1 + len2 + len3 + 6;
 
-       set_base_frame(j, 30);
-       set_play_codec(j, LINEAR16);
-
-       if (j->port == PORT_POTS)
-               if(!j->r_hook)
-                       SLIC_SetState(PLD_SLIC_STATE_OHT, j);
-
-       set_play_volume(j, 0x1B);
-       ixj_play_start(j);
-       ixj_write_cid_seize(j);
+       while(1){
+               ixj_write_cid_seize(j);
 
-       ixj_write_cid_byte(j, 0x80);
-       checksum = 0x80;
-       ixj_write_cid_byte(j, mdmflen);
-       checksum = checksum + mdmflen;
+               ixj_write_cid_byte(j, 0x80);
+               checksum = 0x80;
+               ixj_write_cid_byte(j, mdmflen);
+               checksum = checksum + mdmflen;
 
-       ixj_write_cid_byte(j, 0x01);
-       checksum = checksum + 0x01;
-       ixj_write_cid_byte(j, len1);
-       checksum = checksum + len1;
-       checksum = ixj_write_cid_string(j, sdmf1, checksum);
+               ixj_write_cid_byte(j, 0x01);
+               checksum = checksum + 0x01;
+               ixj_write_cid_byte(j, len1);
+               checksum = checksum + len1;
+               checksum = ixj_write_cid_string(j, sdmf1, checksum);
+               if(ixj_hookstate(j) & 1)
+                       break;
 
-       ixj_write_cid_byte(j, 0x02);
-       checksum = checksum + 0x02;
-       ixj_write_cid_byte(j, len2);
-       checksum = checksum + len2;
-       checksum = ixj_write_cid_string(j, sdmf2, checksum);
+               ixj_write_cid_byte(j, 0x02);
+               checksum = checksum + 0x02;
+               ixj_write_cid_byte(j, len2);
+               checksum = checksum + len2;
+               checksum = ixj_write_cid_string(j, sdmf2, checksum);
+               if(ixj_hookstate(j) & 1)
+                       break;
 
-       ixj_write_cid_byte(j, 0x07);
-       checksum = checksum + 0x07;
-       ixj_write_cid_byte(j, len3);
-       checksum = checksum + len3;
-       checksum = ixj_write_cid_string(j, sdmf3, checksum);
+               ixj_write_cid_byte(j, 0x07);
+               checksum = checksum + 0x07;
+               ixj_write_cid_byte(j, len3);
+               checksum = checksum + len3;
+               checksum = ixj_write_cid_string(j, sdmf3, checksum);
+               if(ixj_hookstate(j) & 1)
+                       break;
 
-       checksum %= 256;
-       checksum ^= 0xFF;
-       checksum += 1;
+               checksum %= 256;
+               checksum ^= 0xFF;
+               checksum += 1;
 
-       ixj_write_cid_byte(j, (char) checksum);
+               ixj_write_cid_byte(j, (char) checksum);
 
-       pad = j->fskdcnt % 240;
-       if (pad) {
-               pad = 240 - pad;
+               pad = j->fskdcnt % 240;
+               if (pad) {
+                       pad = 240 - pad;
+               }
+               ixj_pad_fsk(j, pad);
+               break;
        }
-       ixj_pad_fsk(j, pad);
-       SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
-       j->flags.cidplay = 0;
-       ixj_play_stop(j);
+
+       ixj_write_frame(j);
 }
 
 static void ixj_write_cidcw(IXJ *j)
@@ -2306,12 +3373,15 @@ static void ixj_write_cidcw(IXJ *j)
 
        int checksum = 0;
 
-       if (j->dsp.low == 0x20)
+       if (j->dsp.low == 0x20 || j->flags.cidplay)
                return;
 
        j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0;
+       j->cidsize = j->cidcnt = 0;
 
-       j->flags.cidplay = 1;
+       ixj_fsk_alloc(j);
+
+       j->flags.cidcw_ack = 0;
 
        ti.tone_index = 23;
        ti.gain0 = 1;
@@ -2320,6 +3390,26 @@ static void ixj_write_cidcw(IXJ *j)
        ti.freq1 = 0;
        ixj_init_tone(j, &ti);
 
+       ixj_set_tone_on(1500, j);
+       ixj_set_tone_off(32, j);
+       if(ixjdebug & 0x0200) {
+               printk("IXJ cidcw phone%d first tone start at %ld\n", j->board, jiffies);
+       }
+       ixj_play_tone(j, 23);
+
+       clear_bit(j->board, &j->busyflags);
+       while(j->tone_state) {
+               set_current_state(TASK_INTERRUPTIBLE);
+               schedule_timeout(1);
+       }
+       while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0) {
+               set_current_state(TASK_INTERRUPTIBLE);
+               schedule_timeout(1);
+       }
+       if(ixjdebug & 0x0200) {
+               printk("IXJ cidcw phone%d first tone end at %ld\n", j->board, jiffies);
+       }
+
        ti.tone_index = 24;
        ti.gain0 = 1;
        ti.freq0 = hz2130;
@@ -2327,64 +3417,63 @@ static void ixj_write_cidcw(IXJ *j)
        ti.freq1 = hz2750;
        ixj_init_tone(j, &ti);
 
-       ixj_set_tone_on(1200, j);
-       ixj_play_tone(j, 23);
+       ixj_set_tone_off(10, j);
+       ixj_set_tone_on(600, j);
+       if(ixjdebug & 0x0200) {
+               printk("IXJ cidcw phone%d second tone start at %ld\n", j->board, jiffies);
+       }
+       ixj_play_tone(j, 24);
 
+       clear_bit(j->board, &j->busyflags);
        while(j->tone_state) {
                set_current_state(TASK_INTERRUPTIBLE);
                schedule_timeout(1);
        }
-
-       ixj_set_tone_on(320, j);
-       ixj_play_tone(j, 24);
-
-       while(j->tone_state) {
+       while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0) {
                set_current_state(TASK_INTERRUPTIBLE);
                schedule_timeout(1);
        }
+       if(ixjdebug & 0x0200) {
+               printk("IXJ cidcw phone%d sent second tone at %ld\n", j->board, jiffies);
+       }
 
-       j->cidcw_wait = jiffies + (200 * hertz / 100000);
+       j->cidcw_wait = jiffies + ((50 * hertz) / 100);
 
+       clear_bit(j->board, &j->busyflags);
        while(!j->flags.cidcw_ack && time_before(jiffies, j->cidcw_wait)) {
                set_current_state(TASK_INTERRUPTIBLE);
                schedule_timeout(1);
        }
-
-       if(!j->flags.cidcw_ack) {
-               return;
+       while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0) {
+               set_current_state(TASK_INTERRUPTIBLE);
+               schedule_timeout(1);
        }
-
-       strcpy(sdmf1, j->cid_send.month);
-       strcat(sdmf1, j->cid_send.day);
-       strcat(sdmf1, j->cid_send.hour);
-       strcat(sdmf1, j->cid_send.min);
-       strcpy(sdmf2, j->cid_send.number);
-       strcpy(sdmf3, j->cid_send.name);
-
-       len1 = strlen(sdmf1);
-       len2 = strlen(sdmf2);
-       len3 = strlen(sdmf3);
-       mdmflen = len1 + len2 + len3 + 6;
-
-       j->cid_play_codec = j->play_codec;
-       ixj_play_stop(j);
-
-       switch(j->baseframe.low) {
-               case 0xA0:
-                       j->cid_base_frame_size = 20;
-                       break;
-               case 0x50:
-                       j->cid_base_frame_size = 10;
-                       break;
-               default:
-                       j->cid_base_frame_size = 30;
-                       break;
+       j->cidcw_wait = 0;
+       if(!j->flags.cidcw_ack) {
+               if(ixjdebug & 0x0200) {
+                       printk("IXJ cidcw phone%d did not recieve ACK from display %ld\n", j->board, jiffies);
+               }
+               ixj_post_cid(j);
+               if(j->cid_play_flag) {
+                       wake_up_interruptible(&j->write_q);     /* Wake any blocked readers */
+               }
+               return;
+       } else {
+               ixj_pre_cid(j);
        }
-       set_base_frame(j, 30);
-       set_play_codec(j, LINEAR16);
+       j->flags.cidcw_ack = 0;
+       strcpy(sdmf1, j->cid_send.month);
+       strcat(sdmf1, j->cid_send.day);
+       strcat(sdmf1, j->cid_send.hour);
+       strcat(sdmf1, j->cid_send.min);
+       strcpy(sdmf2, j->cid_send.number);
+       strcpy(sdmf3, j->cid_send.name);
+
+       len1 = strlen(sdmf1);
+       len2 = strlen(sdmf2);
+       len3 = strlen(sdmf3);
+       mdmflen = len1 + len2 + len3 + 6;
 
-       set_play_volume(j, 0x1B);
-       ixj_play_start(j);
        ixj_write_cidcw_seize(j);
 
        ixj_write_cid_byte(j, 0x80);
@@ -2421,11 +3510,9 @@ static void ixj_write_cidcw(IXJ *j)
                pad = 240 - pad;
        }
        ixj_pad_fsk(j, pad);
-       j->flags.cidplay = 0;
-       ixj_play_stop(j);
-
-       set_base_frame(j, j->cid_base_frame_size);
-       set_play_codec(j, j->cid_play_codec);
+       if(ixjdebug & 0x0200) {
+               printk("IXJ cidcw phone%d sent FSK data at %ld\n", j->board, jiffies);
+       }
 }
 
 static void ixj_write_vmwi(IXJ *j, int msg)
@@ -2435,23 +3522,19 @@ static void ixj_write_vmwi(IXJ *j, int msg)
 
        int checksum = 0;
 
-       if (j->dsp.low == 0x20)
+       if (j->dsp.low == 0x20 || j->flags.cidplay)
                return;
 
        j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0;
+       j->cidsize = j->cidcnt = 0;
 
-       j->flags.cidplay = 1;
+       ixj_fsk_alloc(j);
 
        mdmflen = 3;
 
-       set_base_frame(j, 30);
-       set_play_codec(j, LINEAR16);
-
        if (j->port == PORT_POTS)
                SLIC_SetState(PLD_SLIC_STATE_OHT, j);
 
-       set_play_volume(j, 0x1B);
-       ixj_play_start(j);
        ixj_write_cid_seize(j);
 
        ixj_write_cid_byte(j, 0x82);
@@ -2484,18 +3567,49 @@ static void ixj_write_vmwi(IXJ *j, int msg)
                pad = 240 - pad;
        }
        ixj_pad_fsk(j, pad);
-       SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
-       j->flags.cidplay = 0;
-       ixj_play_stop(j);
 }
 
 static void ixj_write_frame(IXJ *j)
 {
        int cnt, frame_count, dly;
+       IXJ_WORD dat;
        BYTES blankword;
 
        frame_count = 0;
-       if (j->write_buffer && j->write_buffers_empty < 2) {
+       if(j->flags.cidplay) {
+               for(cnt = 0; cnt < 480; cnt++) {
+                       if (!(cnt % 16) && !IsTxReady(j)) {
+                               dly = 0;
+                               while (!IsTxReady(j)) {
+                                       if (dly++ > 5) {
+                                               dly = 0;
+                                               break;
+                                       }
+                                       udelay(10);
+                               }
+                       }
+                       dat.word = j->fskdata[j->cidcnt++];
+                       outb_p(dat.bytes.low, j->DSPbase + 0x0C);
+                       outb_p(dat.bytes.high, j->DSPbase + 0x0D);
+                       cnt++;
+               }
+               if(j->cidcnt >= j->fskdcnt) {
+                       ixj_post_cid(j);
+               }
+               /* This may seem rude, but if we just played one frame of FSK data for CallerID
+                  and there is real audio data in the buffer, we need to throw it away because 
+                  we just used it's time slot */
+               if (j->write_buffer_rp > j->write_buffer_wp) {
+                       j->write_buffer_rp += j->cid_play_frame_size * 2;
+                       if (j->write_buffer_rp >= j->write_buffer_end) {
+                               j->write_buffer_rp = j->write_buffer;
+                       }
+                       j->write_buffers_empty++;
+                       wake_up_interruptible(&j->write_q);     /* Wake any blocked writers */
+
+                       wake_up_interruptible(&j->poll_q);      /* Wake any blocked selects */
+               }
+       } else if (j->write_buffer && j->write_buffers_empty < 1) { 
                if (j->write_buffer_wp > j->write_buffer_rp) {
                        frame_count =
                            (j->write_buffer_wp - j->write_buffer_rp) / (j->play_frame_size * 2);
@@ -2535,6 +3649,29 @@ static void ixj_write_frame(IXJ *j)
                                        outb_p((blankword.high), j->DSPbase + 0x0D);
                                }
                                j->flags.play_first_frame = 0;
+                       } else  if (j->play_codec == G723_63 && j->flags.play_first_frame) {
+                               for (cnt = 0; cnt < 24; cnt++) {
+                                       if(cnt == 12) {
+                                               blankword.low = 0x02;
+                                               blankword.high = 0x00;
+                                       }
+                                       else {
+                                               blankword.low = blankword.high = 0x00;
+                                       }
+                                       if (!(cnt % 16) && !IsTxReady(j)) {
+                                               dly = 0;
+                                               while (!IsTxReady(j)) {
+                                                       if (dly++ > 5) {
+                                                               dly = 0;
+                                                               break;
+                                                       }
+                                                       udelay(10);
+                                               }
+                                       }
+                                       outb_p((blankword.low), j->DSPbase + 0x0C);
+                                       outb_p((blankword.high), j->DSPbase + 0x0D);
+                               }
+                               j->flags.play_first_frame = 0;
                        }
                        for (cnt = 0; cnt < j->play_frame_size * 2; cnt += 2) {
                                if (!(cnt % 16) && !IsTxReady(j)) {
@@ -2547,11 +3684,20 @@ static void ixj_write_frame(IXJ *j)
                                                udelay(10);
                                        }
                                }
-// Add word 0 to G.729 frames for the 8021.  Right now we don't do VAD/CNG 
-                               // so all frames are type 1.
-                               if (j->play_codec == G729 && (cnt == 0 || cnt == 5 || cnt == 10)) {
-                                       outb_p(0x01, j->DSPbase + 0x0C);
-                                       outb_p(0x00, j->DSPbase + 0x0D);
+                       /* Add word 0 to G.729 frames for the 8021.  Right now we don't do VAD/CNG  */
+                               if (j->play_codec == G729 && (cnt == 0 || cnt == 10 || cnt == 20)) {
+                                       if(j->write_buffer_rp + cnt == 0 && j->write_buffer_rp + cnt + 1 == 0 && j->write_buffer_rp + cnt + 2 == 0 &&
+                                          j->write_buffer_rp + cnt + 3 == 0 && j->write_buffer_rp + cnt + 4 == 0 && j->write_buffer_rp + cnt + 5 == 0 &&
+                                          j->write_buffer_rp + cnt + 6 == 0 && j->write_buffer_rp + cnt + 7 == 0 && j->write_buffer_rp + cnt + 8 == 0 &&
+                                          j->write_buffer_rp + cnt + 9 == 0) {
+                                       /* someone is trying to write silence lets make this a type 0 frame. */
+                                               outb_p(0x00, j->DSPbase + 0x0C);
+                                               outb_p(0x00, j->DSPbase + 0x0D);
+                                       } else {
+                                       /* so all other frames are type 1. */
+                                               outb_p(0x01, j->DSPbase + 0x0C);
+                                               outb_p(0x00, j->DSPbase + 0x0D);
+                                       }
                                }
                                outb_p(*(j->write_buffer_rp + cnt), j->DSPbase + 0x0C);
                                outb_p(*(j->write_buffer_rp + cnt + 1), j->DSPbase + 0x0D);
@@ -2563,27 +3709,35 @@ static void ixj_write_frame(IXJ *j)
                                j->write_buffer_rp = j->write_buffer;
                        }
                        j->write_buffers_empty++;
-                       wake_up_interruptible(&j->write_q);     // Wake any blocked writers
+                       wake_up_interruptible(&j->write_q);     /* Wake any blocked writers */
 
-                       wake_up_interruptible(&j->poll_q);      // Wake any blocked selects
+                       wake_up_interruptible(&j->poll_q);      /* Wake any blocked selects */
 
-                       ixj_kill_fasync(j, POLL_OUT);
                        ++j->frameswritten;
                }
        } else {
                j->drybuffer++;
        }
+       if(j->ixj_signals[SIG_WRITE_READY]) {
+               ixj_kill_fasync(j, SIG_WRITE_READY, POLL_OUT);
+       }
 }
 
 static int idle(IXJ *j)
 {
-       if (ixj_WriteDSPCommand(0x0000, j))             // DSP Idle
+       if (ixj_WriteDSPCommand(0x0000, j))             /* DSP Idle */
 
                return 0;
-       if (j->ssr.high || j->ssr.low)
+
+       if (j->ssr.high || j->ssr.low) {
                return 0;
-       else
+       } else {
+               j->play_mode = -1;
+               j->flags.playing = 0;
+               j->rec_mode = -1;
+               j->flags.recording = 0;
                return 1;
+        }
 }
 
 static int set_base_frame(IXJ *j, int size)
@@ -2591,6 +3745,8 @@ static int set_base_frame(IXJ *j, int size)
        unsigned short cmd;
        int cnt;
 
+       idle(j);
+       j->cid_play_aec_level = j->aec_level;
        aec_stop(j);
        for (cnt = 0; cnt < 10; cnt++) {
                if (idle(j))
@@ -2627,7 +3783,12 @@ static int set_base_frame(IXJ *j, int size)
        } else {
                j->baseframe.high = j->ssr.high;
                j->baseframe.low = j->ssr.low;
+               /* If the status returned is 0x0000 (pg9-9 8021) the call failed */
+               if(j->baseframe.high == 0x00 && j->baseframe.low == 0x00) {
+                       return -1;
+               }
        }
+       ixj_aec_start(j, j->cid_play_aec_level);
        return size;
 }
 
@@ -2708,6 +3869,28 @@ static int set_rec_codec(IXJ *j, int rate)
                        retval = 1;
                }
                break;
+       case G729B:
+               if (j->dsp.low != 0x20) {
+                       if (!j->flags.g729_loaded) {
+                               retval = 1;
+                               break;
+                       }
+                       switch (j->baseframe.low) {
+                       case 0xA0:
+                               j->rec_frame_size = 12;
+                               break;
+                       case 0x50:
+                               j->rec_frame_size = 6;
+                               break;
+                       default:
+                               j->rec_frame_size = 18;
+                               break;
+                       }
+                       j->rec_mode = 0;
+               } else {
+                       retval = 1;
+               }
+               break;
        case ULAW:
                switch (j->baseframe.low) {
                case 0xA0:
@@ -2800,7 +3983,10 @@ static int ixj_record_start(IXJ *j)
                ixj_record_stop(j);
        }
        j->flags.recording = 1;
-       ixj_WriteDSPCommand(0x0FE0, j); // Put the DSP in full power mode.
+       ixj_WriteDSPCommand(0x0FE0, j); /* Put the DSP in full power mode. */
+
+       if(ixjdebug & 0x0002)
+               printk("IXJ %d Starting Record Codec %d at %ld\n", j->board, j->rec_codec, jiffies);
 
        if (!j->rec_mode) {
                switch (j->rec_codec) {
@@ -2811,21 +3997,22 @@ static int ixj_record_start(IXJ *j)
                        cmd = 0x5132;
                        break;
                case TS85:
-                       cmd = 0x5130;   // TrueSpeech 8.5
+                       cmd = 0x5130;   /* TrueSpeech 8.5 */
 
                        break;
                case TS48:
-                       cmd = 0x5133;   // TrueSpeech 4.8
+                       cmd = 0x5133;   /* TrueSpeech 4.8 */
 
                        break;
                case TS41:
-                       cmd = 0x5134;   // TrueSpeech 4.1
+                       cmd = 0x5134;   /* TrueSpeech 4.1 */
 
                        break;
                case G728:
                        cmd = 0x5135;
                        break;
                case G729:
+               case G729B:
                        cmd = 0x5136;
                        break;
                default:
@@ -2838,67 +4025,70 @@ static int ixj_record_start(IXJ *j)
                if (!j->read_buffer)
                        j->read_buffer = kmalloc(j->rec_frame_size * 2, GFP_ATOMIC);
                if (!j->read_buffer) {
-                       printk("Read buffer allocation for ixj board %d failed!\n",
-                              j->p.board);
+                       printk("Read buffer allocation for ixj board %d failed!\n", j->board);
                        return -ENOMEM;
                }
        }
        j->read_buffer_size = j->rec_frame_size * 2;
 
-       if (ixj_WriteDSPCommand(0x5102, j))             // Set Poll sync mode
+       if (ixj_WriteDSPCommand(0x5102, j))             /* Set Poll sync mode */
 
                return -1;
 
        switch (j->rec_mode) {
        case 0:
-               cmd = 0x1C03;   // Record C1
+               cmd = 0x1C03;   /* Record C1 */
 
                break;
        case 4:
                if (j->ver.low == 0x12) {
-                       cmd = 0x1E03;   // Record C1
+                       cmd = 0x1E03;   /* Record C1 */
 
                } else {
-                       cmd = 0x1E01;   // Record C1
+                       cmd = 0x1E01;   /* Record C1 */
 
                }
                break;
        case 5:
                if (j->ver.low == 0x12) {
-                       cmd = 0x1E83;   // Record C1
+                       cmd = 0x1E83;   /* Record C1 */
 
                } else {
-                       cmd = 0x1E81;   // Record C1
+                       cmd = 0x1E81;   /* Record C1 */
 
                }
                break;
        case 6:
                if (j->ver.low == 0x12) {
-                       cmd = 0x1F03;   // Record C1
+                       cmd = 0x1F03;   /* Record C1 */
 
                } else {
-                       cmd = 0x1F01;   // Record C1
+                       cmd = 0x1F01;   /* Record C1 */
 
                }
                break;
        case 7:
                if (j->ver.low == 0x12) {
-                       cmd = 0x1F83;   // Record C1
-
+                       cmd = 0x1F83;   /* Record C1 */
                } else {
-                       cmd = 0x1F81;   // Record C1
-
+                       cmd = 0x1F81;   /* Record C1 */
                }
                break;
        }
        if (ixj_WriteDSPCommand(cmd, j))
                return -1;
 
+       if (j->flags.playing) {
+               ixj_aec_start(j, j->aec_level);
+       }
        return 0;
 }
 
 static void ixj_record_stop(IXJ *j)
 {
+       if(ixjdebug & 0x0002)
+               printk("IXJ %d Stopping Record Codec %d at %ld\n", j->board, j->rec_codec, jiffies);
+
        if (j->read_buffer) {
                kfree(j->read_buffer);
                j->read_buffer = NULL;
@@ -2909,9 +4099,6 @@ static void ixj_record_stop(IXJ *j)
                j->rec_mode = -1;
        }
        j->flags.recording = 0;
-       if (!j->flags.playing)
-               ixj_WriteDSPCommand(0x0FE3, j); // Put the DSP in 1/5 power mode.
-
 }
 static void ixj_vad(IXJ *j, int arg)
 {
@@ -2930,18 +4117,118 @@ static void set_rec_depth(IXJ *j, int depth)
        ixj_WriteDSPCommand(0x5180 + depth, j);
 }
 
-static void set_rec_volume(IXJ *j, int volume)
+static void set_dtmf_prescale(IXJ *j, int volume)
 {
-       ixj_WriteDSPCommand(0xCF03, j);
+       ixj_WriteDSPCommand(0xCF07, j);
        ixj_WriteDSPCommand(volume, j);
 }
 
-static int get_rec_volume(IXJ *j)
+static int get_dtmf_prescale(IXJ *j)
 {
-       ixj_WriteDSPCommand(0xCF01, j);
+       ixj_WriteDSPCommand(0xCF05, j);
        return j->ssr.high << 8 | j->ssr.low;
 }
 
+static void set_rec_volume(IXJ *j, int volume)
+{
+       if(j->aec_level == AEC_AGC) {
+               if (ixjdebug & 0x0002)
+                       printk(KERN_INFO "IXJ: /dev/phone%d Setting AGC Threshold to 0x%4.4x\n", j->board, volume);
+               ixj_WriteDSPCommand(0xCF96, j);
+               ixj_WriteDSPCommand(volume, j);
+       } else {
+               if (ixjdebug & 0x0002)
+                       printk(KERN_INFO "IXJ: /dev/phone %d Setting Record Volume to 0x%4.4x\n", j->board, volume);
+               ixj_WriteDSPCommand(0xCF03, j);
+               ixj_WriteDSPCommand(volume, j);
+       }
+}
+
+static int set_rec_volume_linear(IXJ *j, int volume)
+{
+       int newvolume, dsprecmax;
+
+       if (ixjdebug & 0x0002)
+               printk(KERN_INFO "IXJ: /dev/phone %d Setting Linear Record Volume to 0x%4.4x\n", j->board, volume);
+       if(volume > 100 || volume < 0) {
+         return -1;
+       }
+
+       /* This should normalize the perceived volumes between the different cards caused by differences in the hardware */
+       switch (j->cardtype) {
+       case QTI_PHONEJACK:
+               dsprecmax = 0x440;
+               break;
+       case QTI_LINEJACK:
+               dsprecmax = 0x180;
+               ixj_mixer(0x0203, j);   /*Voice Left Volume unmute 6db */
+               ixj_mixer(0x0303, j);   /*Voice Right Volume unmute 6db */
+               ixj_mixer(0x0C00, j);   /*Mono1 unmute 12db */
+               break;
+       case QTI_PHONEJACK_LITE:
+               dsprecmax = 0x4C0;
+               break;
+       case QTI_PHONEJACK_PCI:
+               dsprecmax = 0x100;
+               break;
+       case QTI_PHONECARD:
+               dsprecmax = 0x400;
+               break;
+       default:
+               return -1;
+       }
+       newvolume = (dsprecmax * volume) / 100;
+       set_rec_volume(j, newvolume);
+       return 0;
+}
+
+static int get_rec_volume(IXJ *j)
+{
+       if(j->aec_level == AEC_AGC) {
+               if (ixjdebug & 0x0002)
+                       printk(KERN_INFO "Getting AGC Threshold\n");
+               ixj_WriteDSPCommand(0xCF86, j);
+               if (ixjdebug & 0x0002)
+                       printk(KERN_INFO "AGC Threshold is 0x%2.2x%2.2x\n", j->ssr.high, j->ssr.low);
+               return j->ssr.high << 8 | j->ssr.low;
+       } else {
+               if (ixjdebug & 0x0002)
+                       printk(KERN_INFO "Getting Record Volume\n");
+               ixj_WriteDSPCommand(0xCF01, j);
+               return j->ssr.high << 8 | j->ssr.low;
+       }
+}
+
+static int get_rec_volume_linear(IXJ *j)
+{
+       int volume, newvolume, dsprecmax;
+
+       switch (j->cardtype) {
+       case QTI_PHONEJACK:
+               dsprecmax = 0x440;
+               break;
+       case QTI_LINEJACK:
+               dsprecmax = 0x180;
+               break;
+       case QTI_PHONEJACK_LITE:
+               dsprecmax = 0x4C0;
+               break;
+       case QTI_PHONEJACK_PCI:
+               dsprecmax = 0x100;
+               break;
+       case QTI_PHONECARD:
+               dsprecmax = 0x400;
+               break;
+       default:
+               return -1;
+       }
+       volume = get_rec_volume(j);
+       newvolume = (volume * 100) / dsprecmax;
+       if(newvolume > 100)
+               newvolume = 100;
+       return newvolume;
+}
+
 static int get_rec_level(IXJ *j)
 {
        int retval;
@@ -2956,52 +4243,117 @@ static int get_rec_level(IXJ *j)
 static void ixj_aec_start(IXJ *j, int level)
 {
        j->aec_level = level;
+       if (ixjdebug & 0x0002)
+               printk(KERN_INFO "AGC set = 0x%2.2x\n", j->aec_level);
        if (!level) {
                aec_stop(j);
        } else {
-               if (j->rec_codec == G729 || j->play_codec == G729) {
-                       ixj_WriteDSPCommand(0xE022, j); // Move AEC filter buffer
+               if (j->rec_codec == G729 || j->play_codec == G729 || j->rec_codec == G729B || j->play_codec == G729B) {
+                       ixj_WriteDSPCommand(0xE022, j); /* Move AEC filter buffer */
 
                        ixj_WriteDSPCommand(0x0300, j);
                }
-               ixj_WriteDSPCommand(0xB001, j); // AEC On
+               ixj_WriteDSPCommand(0xB001, j); /* AEC On */
 
-               ixj_WriteDSPCommand(0xE013, j); // Advanced AEC C1
+               ixj_WriteDSPCommand(0xE013, j); /* Advanced AEC C1 */
 
                switch (level) {
                case AEC_LOW:
-                       ixj_WriteDSPCommand(0x0000, j); // Advanced AEC C2 = off
+                       ixj_WriteDSPCommand(0x0000, j); /* Advanced AEC C2 = off */
 
                        ixj_WriteDSPCommand(0xE011, j);
                        ixj_WriteDSPCommand(0xFFFF, j);
+
+                       ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */
+                       ixj_WriteDSPCommand(0x0000, j); /* to off */
+                       
                        break;
 
                case AEC_MED:
-                       ixj_WriteDSPCommand(0x0600, j); // Advanced AEC C2 = on medium
+                       ixj_WriteDSPCommand(0x0600, j); /* Advanced AEC C2 = on medium */
 
                        ixj_WriteDSPCommand(0xE011, j);
                        ixj_WriteDSPCommand(0x0080, j);
+
+                       ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */
+                       ixj_WriteDSPCommand(0x0000, j); /* to off */
+                       
                        break;
 
                case AEC_HIGH:
-                       ixj_WriteDSPCommand(0x0C00, j); // Advanced AEC C2 = on high
+                       ixj_WriteDSPCommand(0x0C00, j); /* Advanced AEC C2 = on high */
 
                        ixj_WriteDSPCommand(0xE011, j);
                        ixj_WriteDSPCommand(0x0080, j);
+
+                       ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */
+                       ixj_WriteDSPCommand(0x0000, j); /* to off */
+                       
+                       break;
+
+               case AEC_AGC:
+                        /* First we have to put the AEC into advance auto mode so that AGC will not conflict with it */
+                       ixj_WriteDSPCommand(0x0002, j); /* Attenuation scaling factor of 2 */
+
+                       ixj_WriteDSPCommand(0xE011, j);
+                       ixj_WriteDSPCommand(0x0100, j); /* Higher Threshold Floor */
+
+                       ixj_WriteDSPCommand(0xE012, j); /* Set Train and Lock */
+
+                       if(j->cardtype == QTI_LINEJACK || j->cardtype == QTI_PHONECARD)
+                               ixj_WriteDSPCommand(0x0224, j);
+                       else
+                               ixj_WriteDSPCommand(0x1224, j);
+
+                       ixj_WriteDSPCommand(0xE014, j);
+                       ixj_WriteDSPCommand(0x0003, j); /* Lock threashold at 3dB */
+
+                       ixj_WriteDSPCommand(0xE338, j); /* Set Echo Suppresser Attenuation to 0dB */
+
+                       /* Now we can set the AGC initial parameters and turn it on */
+                       ixj_WriteDSPCommand(0xCF90, j); /* Set AGC Minumum gain */
+                       ixj_WriteDSPCommand(0x0020, j); /* to 0.125 (-18dB) */
+       
+                       ixj_WriteDSPCommand(0xCF91, j); /* Set AGC Maximum gain */
+                       ixj_WriteDSPCommand(0x1000, j); /* to 16 (24dB) */
+                       
+                       ixj_WriteDSPCommand(0xCF92, j); /* Set AGC start gain */
+                       ixj_WriteDSPCommand(0x0800, j); /* to 8 (+18dB) */
+               
+                       ixj_WriteDSPCommand(0xCF93, j); /* Set AGC hold time */
+                       ixj_WriteDSPCommand(0x1F40, j); /* to 2 seconds (units are 250us) */
+                       
+                       ixj_WriteDSPCommand(0xCF94, j); /* Set AGC Attack Time Constant */
+                       ixj_WriteDSPCommand(0x0005, j); /* to 8ms */
+                       
+                       ixj_WriteDSPCommand(0xCF95, j); /* Set AGC Decay Time Constant */
+                       ixj_WriteDSPCommand(0x000D, j); /* to 4096ms */
+                       
+                       ixj_WriteDSPCommand(0xCF96, j); /* Set AGC Attack Threshold */
+                       ixj_WriteDSPCommand(0x1200, j); /* to 25% */
+                       
+                       ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */
+                       ixj_WriteDSPCommand(0x0001, j); /* to on */
+                       
                        break;
 
                case AEC_AUTO:
-                       ixj_WriteDSPCommand(0x0002, j); // Attenuation scaling factor of 2
+                       ixj_WriteDSPCommand(0x0002, j); /* Attenuation scaling factor of 2 */
 
                        ixj_WriteDSPCommand(0xE011, j);
-                       ixj_WriteDSPCommand(0x0100, j); // Higher Threshold Floor
+                       ixj_WriteDSPCommand(0x0100, j); /* Higher Threshold Floor */
 
-                       ixj_WriteDSPCommand(0xE012, j); // Set Train and Lock
+                       ixj_WriteDSPCommand(0xE012, j); /* Set Train and Lock */
 
-                       ixj_WriteDSPCommand(0x0023, j);
+                       if(j->cardtype == QTI_LINEJACK || j->cardtype == QTI_PHONECARD)
+                               ixj_WriteDSPCommand(0x0224, j);
+                       else
+                               ixj_WriteDSPCommand(0x1224, j);
 
                        ixj_WriteDSPCommand(0xE014, j);
-                       ixj_WriteDSPCommand(0x0003, j); // Lock threashold at 3dB
+                       ixj_WriteDSPCommand(0x0003, j); /* Lock threashold at 3dB */
+
+                       ixj_WriteDSPCommand(0xE338, j); /* Set Echo Suppresser Attenuation to 0dB */
 
                        break;
                }
@@ -3010,15 +4362,15 @@ static void ixj_aec_start(IXJ *j, int level)
 
 static void aec_stop(IXJ *j)
 {
-       if (j->rec_codec == G729 || j->play_codec == G729) {
-               ixj_WriteDSPCommand(0xE022, j); // Move AEC filter buffer back
+       j->aec_level = AEC_OFF;
+       if (j->rec_codec == G729 || j->play_codec == G729 || j->rec_codec == G729B || j->play_codec == G729B) {
+               ixj_WriteDSPCommand(0xE022, j); /* Move AEC filter buffer back */
 
                ixj_WriteDSPCommand(0x0700, j);
        }
        if (j->play_mode != -1 && j->rec_mode != -1)
        {
-               ixj_WriteDSPCommand(0xB002, j); // AEC Stop
-
+               ixj_WriteDSPCommand(0xB002, j); /* AEC Stop */
        }
 }
 
@@ -3099,6 +4451,28 @@ static int set_play_codec(IXJ *j, int rate)
                        retval = 1;
                }
                break;
+       case G729B:
+               if (j->dsp.low != 0x20) {
+                       if (!j->flags.g729_loaded) {
+                               retval = 1;
+                               break;
+                       }
+                       switch (j->baseframe.low) {
+                       case 0xA0:
+                               j->play_frame_size = 12;
+                               break;
+                       case 0x50:
+                               j->play_frame_size = 6;
+                               break;
+                       default:
+                               j->play_frame_size = 18;
+                               break;
+                       }
+                       j->play_mode = 0;
+               } else {
+                       retval = 1;
+               }
+               break;
        case ULAW:
                switch (j->baseframe.low) {
                case 0xA0:
@@ -3190,8 +4564,12 @@ static int ixj_play_start(IXJ *j)
        if (j->write_buffer) {
                ixj_play_stop(j);
        }
+
+       if(ixjdebug & 0x0002)
+               printk("IXJ %d Starting Play Codec %d at %ld\n", j->board, j->play_codec, jiffies);
+
        j->flags.playing = 1;
-       ixj_WriteDSPCommand(0x0FE0, j); // Put the DSP in full power mode.
+       ixj_WriteDSPCommand(0x0FE0, j); /* Put the DSP in full power mode. */
 
        j->flags.play_first_frame = 1;
        j->drybuffer = 0;
@@ -3205,21 +4583,22 @@ static int ixj_play_start(IXJ *j)
                        cmd = 0x5232;
                        break;
                case TS85:
-                       cmd = 0x5230;   // TrueSpeech 8.5
+                       cmd = 0x5230;   /* TrueSpeech 8.5 */
 
                        break;
                case TS48:
-                       cmd = 0x5233;   // TrueSpeech 4.8
+                       cmd = 0x5233;   /* TrueSpeech 4.8 */
 
                        break;
                case TS41:
-                       cmd = 0x5234;   // TrueSpeech 4.1
+                       cmd = 0x5234;   /* TrueSpeech 4.1 */
 
                        break;
                case G728:
                        cmd = 0x5235;
                        break;
                case G729:
+               case G729B:
                        cmd = 0x5236;
                        break;
                default:
@@ -3230,16 +4609,16 @@ static int ixj_play_start(IXJ *j)
        }
        j->write_buffer = kmalloc(j->play_frame_size * 2, GFP_ATOMIC);
        if (!j->write_buffer) {
-               printk("Write buffer allocation for ixj board %d failed!\n",
-                      j->p.board);
+               printk("Write buffer allocation for ixj board %d failed!\n", j->board);
                return -ENOMEM;
        }
-       j->write_buffers_empty = 2;
+/*     j->write_buffers_empty = 2; */
+       j->write_buffers_empty = 1; 
        j->write_buffer_size = j->play_frame_size * 2;
        j->write_buffer_end = j->write_buffer + j->play_frame_size * 2;
        j->write_buffer_rp = j->write_buffer_wp = j->write_buffer;
 
-       if (ixj_WriteDSPCommand(0x5202, j))             // Set Poll sync mode
+       if (ixj_WriteDSPCommand(0x5202, j))             /* Set Poll sync mode */
 
                return -1;
 
@@ -3279,42 +4658,42 @@ static int ixj_play_start(IXJ *j)
        if (ixj_WriteDSPCommand(cmd, j))
                return -1;
 
-       if (ixj_WriteDSPCommand(0x2000, j))             // Playback C2
-
+       if (ixj_WriteDSPCommand(0x2000, j))             /* Playback C2 */
                return -1;
 
-       if (ixj_WriteDSPCommand(0x2000 + j->play_frame_size, j))        // Playback C3
-
+       if (ixj_WriteDSPCommand(0x2000 + j->play_frame_size, j))        /* Playback C3 */
                return -1;
 
+       if (j->flags.recording) {
+               ixj_aec_start(j, j->aec_level);
+       }
 
-       ixj_kill_fasync(j, POLL_OUT);
        return 0;
 }
 
 static void ixj_play_stop(IXJ *j)
 {
+       if(ixjdebug & 0x0002)
+               printk("IXJ %d Stopping Play Codec %d at %ld\n", j->board, j->play_codec, jiffies);
+
        if (j->write_buffer) {
                kfree(j->write_buffer);
                j->write_buffer = NULL;
                j->write_buffer_size = 0;
        }
        if (j->play_mode > -1) {
-               ixj_WriteDSPCommand(0x5221, j); // Stop playback and flush buffers.  8022 reference page 9-40
+               ixj_WriteDSPCommand(0x5221, j); /* Stop playback and flush buffers.  8022 reference page 9-40 */
 
                j->play_mode = -1;
        }
        j->flags.playing = 0;
-       if (!j->flags.recording)
-               ixj_WriteDSPCommand(0x0FE3, j); // Put the DSP in 1/5 power mode.
-
 }
 
-extern __inline__ int get_play_level(IXJ *j)
+static inline int get_play_level(IXJ *j)
 {
        int retval;
 
-       ixj_WriteDSPCommand(0xCF8F, j); // 8022 Reference page 9-38
+       ixj_WriteDSPCommand(0xCF8F, j); /* 8022 Reference page 9-38 */
        return j->ssr.high << 8 | j->ssr.low;
        retval = j->ssr.high << 8 | j->ssr.low;
        retval = (retval * 256) / 240;
@@ -3324,10 +4703,8 @@ extern __inline__ int get_play_level(IXJ *j)
 static unsigned int ixj_poll(struct file *file_p, poll_table * wait)
 {
        unsigned int mask = 0;
-       IXJ *j = ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
 
-       if (j == NULL) /* shouldn't happen! */
-               return -ENODEV;
+       IXJ *j = get_ixj(NUM(file_p->f_dentry->d_inode->i_rdev));
 
        poll_wait(file_p, &(j->poll_q), wait);
        if (j->read_buffer_ready > 0)
@@ -3341,18 +4718,22 @@ static unsigned int ixj_poll(struct file *file_p, poll_table * wait)
 
 static int ixj_play_tone(IXJ *j, char tone)
 {
-       if (!j->tone_state && j->dsp.low == 0x20)
-               idle(j);
-
-       j->tone_index = tone;
-       if (ixj_WriteDSPCommand(0x6000 + j->tone_index, j))
-               return -1;
-
        if (!j->tone_state) {
+               if(ixjdebug & 0x0002) {
+                       printk("IXJ %d starting tone %d at %ld\n", j->board, tone, jiffies);
+               }
+               if (j->dsp.low == 0x20) {
+                       idle(j);
+               }
                j->tone_start_jif = jiffies;
 
                j->tone_state = 1;
        }
+
+       j->tone_index = tone;
+       if (ixj_WriteDSPCommand(0x6000 + j->tone_index, j))
+               return -1;
+
        return 0;
 }
 
@@ -3360,7 +4741,7 @@ static int ixj_set_tone_on(unsigned short arg, IXJ *j)
 {
        j->tone_on_time = arg;
 
-       if (ixj_WriteDSPCommand(0x6E04, j))             // Set Tone On Period
+       if (ixj_WriteDSPCommand(0x6E04, j))             /* Set Tone On Period */
 
                return -1;
 
@@ -3383,7 +4764,7 @@ static int SCI_WaitHighSCI(IXJ *j)
                        if ((j->pld_scrr.bits.sci))
                                return 1;
                }
-               if (ixjdebug 1)
+               if (ixjdebug & 0x0001)
                        printk(KERN_INFO "SCI Wait High failed %x\n", j->pld_scrr.byte);
                return 0;
        } else
@@ -3403,7 +4784,7 @@ static int SCI_WaitLowSCI(IXJ *j)
                        if (!(j->pld_scrr.bits.sci))
                                return 1;
                }
-               if (ixjdebug 1)
+               if (ixjdebug & 0x0001)
                        printk(KERN_INFO "SCI Wait Low failed %x\n", j->pld_scrr.byte);
                return 0;
        } else
@@ -3414,27 +4795,27 @@ static int SCI_Control(IXJ *j, int control)
 {
        switch (control) {
        case SCI_End:
-               j->pld_scrw.bits.c0 = 0;        // Set PLD Serial control interface
+               j->pld_scrw.bits.c0 = 0;        /* Set PLD Serial control interface */
 
-               j->pld_scrw.bits.c1 = 0;        // to no selection 
+               j->pld_scrw.bits.c1 = 0;        /* to no selection */
 
                break;
        case SCI_Enable_DAA:
-               j->pld_scrw.bits.c0 = 1;        // Set PLD Serial control interface
+               j->pld_scrw.bits.c0 = 1;        /* Set PLD Serial control interface */
 
-               j->pld_scrw.bits.c1 = 0;        // to write to DAA
+               j->pld_scrw.bits.c1 = 0;        /* to write to DAA */
 
                break;
        case SCI_Enable_Mixer:
-               j->pld_scrw.bits.c0 = 0;        // Set PLD Serial control interface
+               j->pld_scrw.bits.c0 = 0;        /* Set PLD Serial control interface */
 
-               j->pld_scrw.bits.c1 = 1;        // to write to mixer 
+               j->pld_scrw.bits.c1 = 1;        /* to write to mixer */
 
                break;
        case SCI_Enable_EEPROM:
-               j->pld_scrw.bits.c0 = 1;        // Set PLD Serial control interface
+               j->pld_scrw.bits.c0 = 1;        /* Set PLD Serial control interface */
 
-               j->pld_scrw.bits.c1 = 1;        // to write to EEPROM 
+               j->pld_scrw.bits.c1 = 1;        /* to write to EEPROM */
 
                break;
        default:
@@ -3471,16 +4852,25 @@ static int SCI_Prepare(IXJ *j)
        return 1;
 }
 
+static int ixj_get_mixer(long val, IXJ *j)
+{
+       int reg = (val & 0x1F00) >> 8;
+        return j->mix.vol[reg];
+}
+
 static int ixj_mixer(long val, IXJ *j)
 {
        BYTES bytes;
 
-       bytes.high = (val & 0xFF00) >> 8;
+       bytes.high = (val & 0x1F00) >> 8;
        bytes.low = val & 0x00FF;
 
-       outb_p(bytes.high & 0x1F, j->XILINXbase + 0x03);        // Load Mixer Address
+        /* save mixer value so we can get back later on */
+        j->mix.vol[bytes.high] = bytes.low;
+
+       outb_p(bytes.high & 0x1F, j->XILINXbase + 0x03);        /* Load Mixer Address */
 
-       outb_p(bytes.low, j->XILINXbase + 0x02);        // Load Mixer Data
+       outb_p(bytes.low, j->XILINXbase + 0x02);        /* Load Mixer Data */
 
        SCI_Control(j, SCI_Enable_Mixer);
 
@@ -3539,22 +4929,73 @@ static int ixj_daa_cr4(IXJ *j, char reg)
 
        if (!daa_load(&bytes, j))
                return 0;
-
-       if (!SCI_Prepare(j))
+
+       if (!SCI_Prepare(j))
+               return 0;
+
+       return 1;
+}
+
+static char daa_int_read(IXJ *j)
+{
+       BYTES bytes;
+
+       if (!SCI_Prepare(j))
+               return 0;
+
+       bytes.high = 0x38;
+       bytes.low = 0x00;
+       outb_p(bytes.high, j->XILINXbase + 0x03);
+       outb_p(bytes.low, j->XILINXbase + 0x02);
+
+       if (!SCI_Control(j, SCI_Enable_DAA))
+               return 0;
+
+       bytes.high = inb_p(j->XILINXbase + 0x03);
+       bytes.low = inb_p(j->XILINXbase + 0x02);
+       if (bytes.low != ALISDAA_ID_BYTE) {
+               if (ixjdebug & 0x0001)
+                       printk("Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
+               return 0;
+       }
+       if (!SCI_Control(j, SCI_Enable_DAA))
+               return 0;
+       if (!SCI_Control(j, SCI_End))
                return 0;
 
+       bytes.high = inb_p(j->XILINXbase + 0x03);
+       bytes.low = inb_p(j->XILINXbase + 0x02);
+
+       j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg = bytes.high;
+
        return 1;
 }
 
-static char daa_int_read(IXJ *j)
+static char daa_CR_read(IXJ *j, int cr)
 {
+       IXJ_WORD wdata;
        BYTES bytes;
 
        if (!SCI_Prepare(j))
                return 0;
 
-       bytes.high = 0x38;
+       switch (j->daa_mode) {
+       case SOP_PU_SLEEP:
+               bytes.high = 0x30 + cr;
+               break;
+       case SOP_PU_RINGING:
+               bytes.high = 0x70 + cr;
+               break;
+       case SOP_PU_CONVERSATION:
+               bytes.high = 0xB0 + cr;
+               break;
+       case SOP_PU_PULSEDIALING:
+               bytes.high = 0xF0 + cr;
+               break;
+       }
+
        bytes.low = 0x00;
+
        outb_p(bytes.high, j->XILINXbase + 0x03);
        outb_p(bytes.low, j->XILINXbase + 0x02);
 
@@ -3564,7 +5005,7 @@ static char daa_int_read(IXJ *j)
        bytes.high = inb_p(j->XILINXbase + 0x03);
        bytes.low = inb_p(j->XILINXbase + 0x02);
        if (bytes.low != ALISDAA_ID_BYTE) {
-               if (ixjdebug > 0)
+               if (ixjdebug & 0x0001)
                        printk("Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
                return 0;
        }
@@ -3573,10 +5014,30 @@ static char daa_int_read(IXJ *j)
        if (!SCI_Control(j, SCI_End))
                return 0;
 
-       bytes.high = inb_p(j->XILINXbase + 0x03);
-       bytes.low = inb_p(j->XILINXbase + 0x02);
+       wdata.word = inw_p(j->XILINXbase + 0x02);
 
-       j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg = bytes.high;
+       switch(cr){
+               case 5:
+                       j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg = wdata.bytes.high;
+                       break;
+               case 4:
+                       j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = wdata.bytes.high;
+                       break;
+               case 3:
+                       j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = wdata.bytes.high;
+                       break;
+               case 2:
+                       j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = wdata.bytes.high;
+                       break;
+               case 1:
+                       j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = wdata.bytes.high;
+                       break;
+               case 0:
+                       j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = wdata.bytes.high;
+                       break;
+               default:
+                       return 0;
+       }
        return 1;
 }
 
@@ -3585,6 +5046,9 @@ static int ixj_daa_cid_reset(IXJ *j)
        int i;
        BYTES bytes;
 
+       if (ixjdebug & 0x0002)
+               printk("DAA Clearing CID ram\n");
+
        if (!SCI_Prepare(j))
                return 0;
 
@@ -3617,6 +5081,9 @@ static int ixj_daa_cid_reset(IXJ *j)
        if (!SCI_Control(j, SCI_End))
                return 0;
 
+       if (ixjdebug & 0x0002)
+               printk("DAA CID ram cleared\n");
+
        return 1;
 }
 
@@ -3644,7 +5111,7 @@ static int ixj_daa_cid_read(IXJ *j)
        bytes.high = inb_p(j->XILINXbase + 0x03);
        bytes.low = inb_p(j->XILINXbase + 0x02);
        if (bytes.low != ALISDAA_ID_BYTE) {
-               if (ixjdebug > 0)
+               if (ixjdebug & 0x0001)
                        printk("DAA Get Version Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
                return 0;
        }
@@ -3727,7 +5194,7 @@ static char daa_get_version(IXJ *j)
        bytes.high = inb_p(j->XILINXbase + 0x03);
        bytes.low = inb_p(j->XILINXbase + 0x02);
        if (bytes.low != ALISDAA_ID_BYTE) {
-               if (ixjdebug > 0)
+               if (ixjdebug & 0x0001)
                        printk("DAA Get Version Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
                return 0;
        }
@@ -3739,7 +5206,7 @@ static char daa_get_version(IXJ *j)
 
        bytes.high = inb_p(j->XILINXbase + 0x03);
        bytes.low = inb_p(j->XILINXbase + 0x02);
-       if (ixjdebug > 0)
+       if (ixjdebug & 0x0002)
                printk("DAA CR5 Byte high = 0x%x low = 0x%x\n", bytes.high, bytes.low);
        j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg = bytes.high;
        return bytes.high;
@@ -3747,30 +5214,52 @@ static char daa_get_version(IXJ *j)
 
 static int daa_set_mode(IXJ *j, int mode)
 {
-       // NOTE:
-       //      The DAA *MUST* be in the conversation mode if the
-       //      PSTN line is to be seized (PSTN line off-hook).
-       //      Taking the PSTN line off-hook while the DAA is in
-       //      a mode other than conversation mode will cause a
-       //      hardware failure of the ALIS-A part.
+       /* NOTE:
+             The DAA *MUST* be in the conversation mode if the
+             PSTN line is to be seized (PSTN line off-hook).
+             Taking the PSTN line off-hook while the DAA is in
+             a mode other than conversation mode will cause a
+             hardware failure of the ALIS-A part.
 
-       // NOTE:
-       //      The DAA can only go to SLEEP, RINGING or PULSEDIALING modes
-       //      if the PSTN line is on-hook.  Failure to have the PSTN line
-       //      in the on-hook state WILL CAUSE A HARDWARE FAILURE OF THE
-       //      ALIS-A part.
-       //
+          NOTE:
+             The DAA can only go to SLEEP, RINGING or PULSEDIALING modes
+             if the PSTN line is on-hook.  Failure to have the PSTN line
+             in the on-hook state WILL CAUSE A HARDWARE FAILURE OF THE
+             ALIS-A part.
+       */
 
        BYTES bytes;
 
+       j->flags.pstn_rmr = 0;
+
        if (!SCI_Prepare(j))
                return 0;
 
        switch (mode) {
+       case SOP_PU_RESET:
+               j->pld_scrw.bits.daafsyncen = 0;        /* Turn off DAA Frame Sync */
+
+               outb_p(j->pld_scrw.byte, j->XILINXbase);
+               j->pld_slicw.bits.rly2 = 0;
+               outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+               bytes.high = 0x10;
+               bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
+               daa_load(&bytes, j);
+               if (!SCI_Prepare(j))
+                       return 0;
+
+               j->daa_mode = SOP_PU_SLEEP;
+               break;
        case SOP_PU_SLEEP:
-               if(j->daa_mode == SOP_PU_CONVERSATION)
+               if(j->daa_mode == SOP_PU_SLEEP)
+               {
+                       break;
+               }
+               if (ixjdebug & 0x0008)
+                       printk(KERN_INFO "phone DAA: SOP_PU_SLEEP at %ld\n", jiffies);
+/*             if(j->daa_mode == SOP_PU_CONVERSATION) */
                {
-                       j->pld_scrw.bits.daafsyncen = 0;        // Turn off DAA Frame Sync
+                       j->pld_scrw.bits.daafsyncen = 0;        /* Turn off DAA Frame Sync */
 
                        outb_p(j->pld_scrw.byte, j->XILINXbase);
                        j->pld_slicw.bits.rly2 = 0;
@@ -3781,7 +5270,7 @@ static int daa_set_mode(IXJ *j, int mode)
                        if (!SCI_Prepare(j))
                                return 0;
                }
-               j->pld_scrw.bits.daafsyncen = 0;        // Turn off DAA Frame Sync
+               j->pld_scrw.bits.daafsyncen = 0;        /* Turn off DAA Frame Sync */
 
                outb_p(j->pld_scrw.byte, j->XILINXbase);
                j->pld_slicw.bits.rly2 = 0;
@@ -3795,13 +5284,15 @@ static int daa_set_mode(IXJ *j, int mode)
                j->daa_mode = SOP_PU_SLEEP;
                j->flags.pstn_ringing = 0;
                j->ex.bits.pstn_ring = 0;
-               j->pstn_sleeptil = jiffies + (hertz / 2);
-               wake_up_interruptible(&j->read_q);      // Wake any blocked readers
-               wake_up_interruptible(&j->write_q);     // Wake any blocked writers
-               wake_up_interruptible(&j->poll_q);      // Wake any blocked selects
+               j->pstn_sleeptil = jiffies + (hertz / 4);
+               wake_up_interruptible(&j->read_q);      /* Wake any blocked readers */
+               wake_up_interruptible(&j->write_q);     /* Wake any blocked writers */
+               wake_up_interruptible(&j->poll_q);      /* Wake any blocked selects */
                break;
        case SOP_PU_RINGING:
-               j->pld_scrw.bits.daafsyncen = 0;        // Turn off DAA Frame Sync
+               if (ixjdebug & 0x0008)
+                       printk(KERN_INFO "phone DAA: SOP_PU_RINGING at %ld\n", jiffies);
+               j->pld_scrw.bits.daafsyncen = 0;        /* Turn off DAA Frame Sync */
 
                outb_p(j->pld_scrw.byte, j->XILINXbase);
                j->pld_slicw.bits.rly2 = 0;
@@ -3814,6 +5305,8 @@ static int daa_set_mode(IXJ *j, int mode)
                j->daa_mode = SOP_PU_RINGING;
                break;
        case SOP_PU_CONVERSATION:
+               if (ixjdebug & 0x0008)
+                       printk(KERN_INFO "phone DAA: SOP_PU_CONVERSATION at %ld\n", jiffies);
                bytes.high = 0x90;
                bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
                daa_load(&bytes, j);
@@ -3821,17 +5314,19 @@ static int daa_set_mode(IXJ *j, int mode)
                        return 0;
                j->pld_slicw.bits.rly2 = 1;
                outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-               j->pld_scrw.bits.led1 = 0;
-               j->pld_scrw.bits.led2 = 1;
-               j->pld_scrw.bits.daafsyncen = 1;        // Turn on DAA Frame Sync
+               j->pld_scrw.bits.daafsyncen = 1;        /* Turn on DAA Frame Sync */
 
                outb_p(j->pld_scrw.byte, j->XILINXbase);
                j->daa_mode = SOP_PU_CONVERSATION;
                j->flags.pstn_ringing = 0;
                j->ex.bits.pstn_ring = 0;
+               j->pstn_sleeptil = jiffies;
+               j->pstn_ring_start = j->pstn_ring_stop = j->pstn_ring_int = 0;
                break;
        case SOP_PU_PULSEDIALING:
-               j->pld_scrw.bits.daafsyncen = 0;        // Turn off DAA Frame Sync
+               if (ixjdebug & 0x0008)
+                       printk(KERN_INFO "phone DAA: SOP_PU_PULSEDIALING at %ld\n", jiffies);
+               j->pld_scrw.bits.daafsyncen = 0;        /* Turn off DAA Frame Sync */
 
                outb_p(j->pld_scrw.byte, j->XILINXbase);
                j->pld_slicw.bits.rly2 = 0;
@@ -3853,9 +5348,15 @@ static int ixj_daa_write(IXJ *j)
 {
        BYTES bytes;
 
+       j->flags.pstncheck = 1;
+
+       daa_set_mode(j, SOP_PU_SLEEP);
+
        if (!SCI_Prepare(j))
                return 0;
 
+       outb_p(j->pld_scrw.byte, j->XILINXbase);
+
        bytes.high = 0x14;
        bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg;
        if (!daa_load(&bytes, j))
@@ -4332,13 +5833,19 @@ static int ixj_daa_write(IXJ *j)
        if (!SCI_Control(j, SCI_End))
                return 0;
 
+       outb_p(j->pld_scrw.byte, j->XILINXbase);
+
+       if (ixjdebug & 0x0002)
+               printk("DAA Coefficients Loaded\n");
+
+       j->flags.pstncheck = 0;
        return 1;
 }
 
 int ixj_set_tone_off(unsigned short arg, IXJ *j)
 {
        j->tone_off_time = arg;
-       if (ixj_WriteDSPCommand(0x6E05, j))             // Set Tone Off Period
+       if (ixj_WriteDSPCommand(0x6E05, j))             /* Set Tone Off Period */
 
                return -1;
        if (ixj_WriteDSPCommand(arg, j))
@@ -4348,7 +5855,7 @@ int ixj_set_tone_off(unsigned short arg, IXJ *j)
 
 static int ixj_get_tone_on(IXJ *j)
 {
-       if (ixj_WriteDSPCommand(0x6E06, j))             // Get Tone On Period
+       if (ixj_WriteDSPCommand(0x6E06, j))             /* Get Tone On Period */
 
                return -1;
        return 0;
@@ -4356,7 +5863,8 @@ static int ixj_get_tone_on(IXJ *j)
 
 static int ixj_get_tone_off(IXJ *j)
 {
-       if (ixj_WriteDSPCommand(0x6E07, j))             // Get Tone Off Period
+       if (ixj_WriteDSPCommand(0x6E07, j))             /* Get Tone Off Period */
+
                return -1;
        return 0;
 }
@@ -4387,7 +5895,7 @@ static void ixj_dialtone(IXJ *j)
 
 static void ixj_cpt_stop(IXJ *j)
 {
-       if(j->tone_state)
+       if(j->tone_state || j->tone_cadence_state)
        {
                j->flags.dialtone = 0;
                j->flags.busytone = 0;
@@ -4395,7 +5903,7 @@ static void ixj_cpt_stop(IXJ *j)
                ixj_set_tone_on(0x0001, j);
                ixj_set_tone_off(0x0000, j);
                ixj_play_tone(j, 0);
-               j->tone_state = 0;
+               j->tone_state = j->tone_cadence_state = 0;
                if (j->cadence_t) {
                        if (j->cadence_t->ce) {
                                kfree(j->cadence_t->ce);
@@ -4436,12 +5944,11 @@ static int ixj_build_cadence(IXJ *j, IXJ_CADENCE * cp)
        lcp = kmalloc(sizeof(IXJ_CADENCE), GFP_KERNEL);
        if (lcp == NULL)
                return -ENOMEM;
-       if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_CADENCE)) ||
-           (unsigned)lcp->elements_used >= ~0U/sizeof(IXJ_CADENCE) )
-       {
-               kfree(lcp);
-               return -EFAULT;
-       }
+       if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_CADENCE)) || (unsigned)lcp->elements_used >= ~0U/sizeof(IXJ_CADENCE) )
+        {
+                kfree(lcp);
+                return -EFAULT;
+        }
        lcep = kmalloc(sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used, GFP_KERNEL);
        if (lcep == NULL) {
                kfree(lcp);
@@ -4477,18 +5984,23 @@ static int ixj_build_cadence(IXJ *j, IXJ_CADENCE * cp)
 static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE * cp)
 {
        IXJ_FILTER_CADENCE *lcp;
-
        lcp = kmalloc(sizeof(IXJ_FILTER_CADENCE), GFP_KERNEL);
-       if (lcp == NULL)
+       if (lcp == NULL) {
+               if(ixjdebug & 0x0001) {
+                       printk(KERN_INFO "Could not allocate memory for cadence\n");
+               }
                return -ENOMEM;
-       if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_FILTER_CADENCE)))
-       {
-               kfree(lcp);
+        }
+       if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_FILTER_CADENCE))) {
+               if(ixjdebug & 0x0001) {
+                       printk(KERN_INFO "Could not copy cadence to kernel\n");
+               }
                return -EFAULT;
        }
-       if (lcp->filter >= 4)
-       {
-               kfree(lcp);
+       if (lcp->filter > 5) {
+               if(ixjdebug & 0x0001) {
+                       printk(KERN_INFO "Cadence out of range\n");
+               }
                return -1;
        }
        j->cadence_f[lcp->filter].state = 0;
@@ -4513,6 +6025,9 @@ static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE * cp)
        j->cadence_f[lcp->filter].off3min = 0;
        j->cadence_f[lcp->filter].off3max = 0;
        kfree(lcp);
+       if(ixjdebug & 0x0002) {
+               printk(KERN_INFO "Cadence %d loaded\n", lcp->filter);
+       }
        return 0;
 }
 
@@ -4548,7 +6063,7 @@ static void add_caps(IXJ *j)
        j->caplist[j->caps].cap = pots;
        j->caplist[j->caps].handle = j->caps++;
 
-       // add devices that can do speaker/mic
+       /* add devices that can do speaker/mic */
        switch (j->cardtype) {
        case QTI_PHONEJACK:
        case QTI_LINEJACK:
@@ -4562,7 +6077,7 @@ static void add_caps(IXJ *j)
                break;
        }
 
-       // add devices that can do handset
+       /* add devices that can do handset */
        switch (j->cardtype) {
        case QTI_PHONEJACK:
                strcpy(j->caplist[j->caps].desc, "HANDSET");
@@ -4574,7 +6089,7 @@ static void add_caps(IXJ *j)
                break;
        }
 
-       // add devices that can do PSTN
+       /* add devices that can do PSTN */
        switch (j->cardtype) {
        case QTI_LINEJACK:
                strcpy(j->caplist[j->caps].desc, "PSTN");
@@ -4586,7 +6101,7 @@ static void add_caps(IXJ *j)
                break;
        }
 
-       // add codecs - all cards can do uLaw, linear 8/16, and Windows sound system
+       /* add codecs - all cards can do uLaw, linear 8/16, and Windows sound system */
        strcpy(j->caplist[j->caps].desc, "ULAW");
        j->caplist[j->caps].captype = codec;
        j->caplist[j->caps].cap = ULAW;
@@ -4607,66 +6122,73 @@ static void add_caps(IXJ *j)
        j->caplist[j->caps].cap = WSS;
        j->caplist[j->caps].handle = j->caps++;
 
-       // version 12 of the 8020 does the following codecs in a broken way
+       /* software ALAW codec, made from ULAW */
+       strcpy(j->caplist[j->caps].desc, "ALAW");
+       j->caplist[j->caps].captype = codec;
+       j->caplist[j->caps].cap = ALAW;
+       j->caplist[j->caps].handle = j->caps++;
+
+       /* version 12 of the 8020 does the following codecs in a broken way */
        if (j->dsp.low != 0x20 || j->ver.low != 0x12) {
-               strcpy(j->caplist[j->caps].desc, "G.723.1 6.3Kbps");
+               strcpy(j->caplist[j->caps].desc, "G.723.1 6.3kbps");
                j->caplist[j->caps].captype = codec;
                j->caplist[j->caps].cap = G723_63;
                j->caplist[j->caps].handle = j->caps++;
 
-               strcpy(j->caplist[j->caps].desc, "G.723.1 5.3Kbps");
+               strcpy(j->caplist[j->caps].desc, "G.723.1 5.3kbps");
                j->caplist[j->caps].captype = codec;
                j->caplist[j->caps].cap = G723_53;
                j->caplist[j->caps].handle = j->caps++;
 
-               strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.8Kbps");
+               strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.8kbps");
                j->caplist[j->caps].captype = codec;
                j->caplist[j->caps].cap = TS48;
                j->caplist[j->caps].handle = j->caps++;
 
-               strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.1Kbps");
+               strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.1kbps");
                j->caplist[j->caps].captype = codec;
                j->caplist[j->caps].cap = TS41;
                j->caplist[j->caps].handle = j->caps++;
        }
 
-       // 8020 chips can do TS8.5 native, and 8021/8022 can load it
+       /* 8020 chips can do TS8.5 native, and 8021/8022 can load it */
        if (j->dsp.low == 0x20 || j->flags.ts85_loaded) {
-               strcpy(j->caplist[j->caps].desc, "TrueSpeech 8.5Kbps");
+               strcpy(j->caplist[j->caps].desc, "TrueSpeech 8.5kbps");
                j->caplist[j->caps].captype = codec;
                j->caplist[j->caps].cap = TS85;
                j->caplist[j->caps].handle = j->caps++;
        }
 
-       // 8021 chips can do G728
+       /* 8021 chips can do G728 */
        if (j->dsp.low == 0x21) {
-               strcpy(j->caplist[j->caps].desc, "G.728 16Kbps");
+               strcpy(j->caplist[j->caps].desc, "G.728 16kbps");
                j->caplist[j->caps].captype = codec;
                j->caplist[j->caps].cap = G728;
                j->caplist[j->caps].handle = j->caps++;
        }
 
-       // 8021/8022 chips can do G729 if loaded
+       /* 8021/8022 chips can do G729 if loaded */
        if (j->dsp.low != 0x20 && j->flags.g729_loaded) {
-               strcpy(j->caplist[j->caps].desc, "G.729A/B");
+               strcpy(j->caplist[j->caps].desc, "G.729A 8kbps");
                j->caplist[j->caps].captype = codec;
-               j->caplist[j->caps].cap = G728;
+               j->caplist[j->caps].cap = G729;
+               j->caplist[j->caps].handle = j->caps++;
+       }
+       if (j->dsp.low != 0x20 && j->flags.g729_loaded) {
+               strcpy(j->caplist[j->caps].desc, "G.729B 8kbps");
+               j->caplist[j->caps].captype = codec;
+               j->caplist[j->caps].cap = G729B;
                j->caplist[j->caps].handle = j->caps++;
        }
 }
 
-static int capabilities_check(IXJ *j, struct phone_capability *u_pcreq)
+static int capabilities_check(IXJ *j, struct phone_capability *pcreq)
 {
        int cnt;
        int retval = 0;
-       struct phone_capability pcreq;
-       
-       if(copy_from_user(&pcreq, u_pcreq, sizeof(struct phone_capability)))
-               return -EFAULT;
-               
        for (cnt = 0; cnt < j->caps; cnt++) {
-               if (pcreq.captype == j->caplist[cnt].captype
-                   && pcreq.cap == j->caplist[cnt].cap) {
+               if (pcreq->captype == j->caplist[cnt].captype
+                   && pcreq->cap == j->caplist[cnt].cap) {
                        retval = 1;
                        break;
                }
@@ -4674,23 +6196,34 @@ static int capabilities_check(IXJ *j, struct phone_capability *u_pcreq)
        return retval;
 }
 
-int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsigned long arg)
+static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsigned long arg)
 {
        IXJ_TONE ti;
        IXJ_FILTER jf;
+       IXJ_FILTER_RAW jfr;
+
+       unsigned int raise, mant;
        unsigned int minor = MINOR(inode->i_rdev);
-       unsigned int board = NUM(inode->i_rdev);
-       IXJ *j = ixj[board];
-       int retval = 0;
+       int board = NUM(inode->i_rdev);
 
-       if (ixjdebug > 1)
-               printk(KERN_DEBUG "phone%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);
-       if (minor >= IXJMAX)
-               return -ENODEV;
+       IXJ *j = get_ixj(NUM(inode->i_rdev));
 
-       if (j == NULL) /* shouldn't happen! */
-               return -ENODEV;
+       int retval = 0;
 
+       /*
+        *    Set up locks to ensure that only one process is talking to the DSP at a time.
+        *    This is necessary to keep the DSP from locking up.
+        */
+       while(test_and_set_bit(board, (void *)&j->busyflags) != 0) {
+               set_current_state(TASK_INTERRUPTIBLE);
+               schedule_timeout(1);
+       }
+       if (ixjdebug & 0x0040)
+               printk("phone%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);
+       if (minor >= IXJMAX) {
+               clear_bit(board, &j->busyflags);
+               return -ENODEV;
+       }
        /*
         *    Check ioctls only root can use.
         */
@@ -4698,7 +6231,7 @@ int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsign
                switch (cmd) {
                case IXJCTL_TESTRAM:
                case IXJCTL_HZ:
-                       return -EPERM;
+                       retval = -EPERM;
                }
        }
        switch (cmd) {
@@ -4713,12 +6246,11 @@ int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsign
                retval = j->serial;
                break;
        case IXJCTL_VERSION:
-               if (copy_to_user((char *) arg, ixj_c_revision, strlen(ixj_c_revision)))
-                       return -EFAULT;
+               if (copy_to_user((char *) arg, ixj_c_revision, strlen(ixj_c_revision))) 
+                       retval = -EFAULT;
                break;
        case PHONE_RING_CADENCE:
-               if(get_user(j->ring_cadence, (int *)arg))
-                       return -EFAULT;
+               j->ring_cadence = arg;
                break;
        case IXJCTL_CIDCW:
                if(arg) {
@@ -4729,13 +6261,18 @@ int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsign
                }
                ixj_write_cidcw(j);
                break;
-       /* Binary compatbility */
-       case OLD_PHONE_RING_START:
-               arg = 0;
-               /* Fall through */
-       case PHONE_RING_START:
+        /* Binary compatbility */
+        case OLD_PHONE_RING_START:
+                arg = 0;
+                /* Fall through */
+       case PHONE_RING_START:
                if(arg) {
-                       copy_from_user(&j->cid_send, (char *)arg, sizeof(PHONE_CID));
+                       if(copy_from_user(&j->cid_send, (char *)arg, sizeof(PHONE_CID)))
+                       {
+                               retval = -EFAULT;
+                               break;
+                       }
+                       ixj_write_cid(j);
                }
                else {
                        memset(&j->cid_send, 0, sizeof(PHONE_CID));
@@ -4744,6 +6281,9 @@ int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsign
                break;
        case PHONE_RING_STOP:
                j->flags.cringing = 0;
+               if(j->cadence_f[5].enable) {
+                       j->cadence_f[5].state = 0;
+               }
                ixj_ring_off(j);
                break;
        case PHONE_RING:
@@ -4751,7 +6291,10 @@ int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsign
                break;
        case PHONE_EXCEPTION:
                retval = j->ex.bytes;
-               j->ex.bits.flash = 0;
+               if(j->ex.bits.flash) {
+                       j->flash_end = 0;
+                       j->ex.bits.flash = 0;
+               }
                j->ex.bits.pstn_ring = 0;
                j->ex.bits.caller_id = 0;
                j->ex.bits.pstn_wink = 0;
@@ -4767,7 +6310,7 @@ int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsign
                break;
        case PHONE_HOOKSTATE:
                j->ex.bits.hookstate = 0;
-               retval = j->r_hook;
+               retval = j->hookstate;  //j->r_hook;
                break;
        case IXJCTL_SET_LED:
                LED_SetState(arg, j);
@@ -4799,9 +6342,33 @@ int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsign
                        retval = arg;
                }
                break;
+       case PHONE_REC_VOLUME_LINEAR:
+               if(arg == -1) {
+                       retval = get_rec_volume_linear(j);
+               }
+               else {
+                       set_rec_volume_linear(j, arg);
+                       retval = arg;
+               }
+               break;
+       case IXJCTL_DTMF_PRESCALE:
+               if(arg == -1) {
+                       retval = get_dtmf_prescale(j);
+               }
+               else {
+                       set_dtmf_prescale(j, arg);
+                       retval = arg;
+               }
+               break;
        case PHONE_REC_LEVEL:
                retval = get_rec_level(j);
                break;
+       case IXJCTL_SC_RXG:
+               retval = ixj_siadc(j, arg);
+               break;
+       case IXJCTL_SC_TXG:
+               retval = ixj_sidac(j, arg);
+               break;
        case IXJCTL_AEC_START:
                ixj_aec_start(j, arg);
                break;
@@ -4832,6 +6399,15 @@ int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsign
                        retval = arg;
                }
                break;
+       case PHONE_PLAY_VOLUME_LINEAR:
+               if(arg == -1) {
+                       retval = get_play_volume_linear(j);
+               }
+               else {
+                       set_play_volume_linear(j, arg);
+                       retval = arg;
+               }
+               break;
        case PHONE_PLAY_LEVEL:
                retval = get_play_level(j);
                break;
@@ -4921,31 +6497,31 @@ int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsign
                        if (j->dtmf_rp != j->dtmf_wp) {
                                switch (j->dtmfbuffer[j->dtmf_rp]) {
                                case 10:
-                                       retval = 42;    //'*';
+                                       retval = 42;    /* '*'; */
 
                                        break;
                                case 11:
-                                       retval = 48;    //'0';
+                                       retval = 48;    /*'0'; */
 
                                        break;
                                case 12:
-                                       retval = 35;    //'#';
+                                       retval = 35;    /*'#'; */
 
                                        break;
                                case 28:
-                                       retval = 65;    //'A';
+                                       retval = 65;    /*'A'; */
 
                                        break;
                                case 29:
-                                       retval = 66;    //'B';
+                                       retval = 66;    /*'B'; */
 
                                        break;
                                case 30:
-                                       retval = 67;    //'C';
+                                       retval = 67;    /*'C'; */
 
                                        break;
                                case 31:
-                                       retval = 68;    //'D';
+                                       retval = 68;    /*'D'; */
 
                                        break;
                                default:
@@ -4955,7 +6531,7 @@ int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsign
                                j->dtmf_rp++;
                                if (j->dtmf_rp == 79)
                                        j->dtmf_rp = 0;
-//          if(j->dtmf_rp == j->dtmf_wp)
+                               if(j->dtmf_rp == j->dtmf_wp)
                                {
                                        j->ex.bits.dtmf_ready = j->dtmf_rp = j->dtmf_wp = 0;
                                }
@@ -4974,40 +6550,53 @@ int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsign
        case PHONE_RINGBACK:
                ixj_ringback(j);
                break;
+       case PHONE_WINK:
+               if(j->cardtype == QTI_PHONEJACK) 
+                       retval = -1;
+               else 
+                       retval = ixj_wink(j);
+               break;
        case PHONE_CPT_STOP:
                ixj_cpt_stop(j);
                break;
-       case PHONE_QUERY_CODEC:
-       {
-               struct phone_codec_data pd;
-               int val;
-               int proto_size[] = {
-                       -1, 
-                       12, 10, 16, 9, 8, 48, 5,
-                       40, 40, 80, 40, 40
-               };
-               if(copy_from_user(&pd, (void *)arg, sizeof(pd)))
-                       return -EFAULT;
-               if(pd.type<1 || pd.type>12)
-                       return -EPROTONOSUPPORT;
-               if(pd.type<G729)
-                       val=proto_size[pd.type];
-               else switch(j->baseframe.low)
-               {
-                       case 0xA0:val=2*proto_size[pd.type];break;
-                       case 0x50:val=proto_size[pd.type];break;
-                       default:val=proto_size[pd.type]*3;break;
+        case PHONE_QUERY_CODEC:
+        {
+                struct phone_codec_data pd;
+                int val;
+                int proto_size[] = {
+                        -1,
+                        12, 10, 16, 9, 8, 48, 5,
+                        40, 40, 80, 40, 40, 6
+                };
+                if(copy_from_user(&pd, (void *)arg, sizeof(pd))) {
+                        retval = -EFAULT;
+                       break;
                }
-               pd.buf_min=pd.buf_max=pd.buf_opt=val;
-               if(copy_to_user((void *)arg, &pd, sizeof(pd)))
-                       return -EFAULT;
-               return 0;
-       }
+                if(pd.type<1 || pd.type>13) {
+                        retval = -EPROTONOSUPPORT;
+                       break;
+               }
+                if(pd.type<G729)
+                        val=proto_size[pd.type];
+                else switch(j->baseframe.low)
+                {
+                        case 0xA0:val=2*proto_size[pd.type];break;
+                        case 0x50:val=proto_size[pd.type];break;
+                        default:val=proto_size[pd.type]*3;break;
+                }
+                pd.buf_min=pd.buf_max=pd.buf_opt=val;
+                if(copy_to_user((void *)arg, &pd, sizeof(pd)))
+                        retval = -EFAULT;
+               break;
+        }
        case IXJCTL_DSP_IDLE:
                idle(j);
                break;
        case IXJCTL_MIXER:
-               ixj_mixer(arg, j);
+                if ((arg & 0xff) == 0xff)
+                       retval = ixj_get_mixer(arg, j);
+                else
+                       ixj_mixer(arg, j);
                break;
        case IXJCTL_DAA_COEFF_SET:
                switch (arg) {
@@ -5039,7 +6628,6 @@ int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsign
                        retval = 1;
                        break;
                }
-               j->country = arg;
                break;
        case IXJCTL_DAA_AGAIN:
                ixj_daa_cr4(j, arg | 0x02);
@@ -5051,8 +6639,8 @@ int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsign
                ixj_write_vmwi(j, arg);
                break;
        case IXJCTL_CID:
-               if (copy_to_user((char *) arg, &j->cid, sizeof(PHONE_CID)))
-                       return -EFAULT;
+               if (copy_to_user((char *) arg, &j->cid, sizeof(PHONE_CID))) 
+                       retval = -EFAULT;
                j->ex.bits.caller_id = 0;
                break;
        case IXJCTL_WINK_DURATION:
@@ -5068,14 +6656,24 @@ int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsign
                retval = ixj_set_pots(j, arg);
                break;
        case PHONE_CAPABILITIES:
+               add_caps(j);
                retval = j->caps;
                break;
        case PHONE_CAPABILITIES_LIST:
-               if (copy_to_user((char *) arg, j->caplist, sizeof(struct phone_capability) * j->caps))
-                        return -EFAULT;
+               add_caps(j);
+               if (copy_to_user((char *) arg, j->caplist, sizeof(struct phone_capability) * j->caps)) 
+                       retval = -EFAULT;
                break;
        case PHONE_CAPABILITIES_CHECK:
-               retval = capabilities_check(j, (struct phone_capability *) arg);
+               {
+                       struct phone_capability cap;
+                       if (copy_from_user(&cap, (char *) arg, sizeof(cap))) 
+                               retval = -EFAULT;
+                       else {
+                               add_caps(j);
+                               retval = capabilities_check(j, &cap);
+                       }
+               }
                break;
        case PHONE_PSTN_SET_STATE:
                daa_set_mode(j, arg);
@@ -5085,10 +6683,15 @@ int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsign
                j->ex.bits.pstn_ring = 0;
                break;
        case IXJCTL_SET_FILTER:
-               if (copy_from_user(&jf, (char *) arg, sizeof(jf)))
-                       return -EFAULT;
+               if (copy_from_user(&jf, (char *) arg, sizeof(jf))) 
+                       retval = -EFAULT;
                retval = ixj_init_filter(j, &jf);
                break;
+       case IXJCTL_SET_FILTER_RAW:
+               if (copy_from_user(&jfr, (char *) arg, sizeof(jfr))) 
+                       retval = -EFAULT;
+               retval = ixj_init_filter_raw(j, &jfr);
+               break;
        case IXJCTL_GET_FILTER_HIST:
                retval = j->filter_hist[arg];
                break;
@@ -5102,117 +6705,123 @@ int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsign
        case IXJCTL_FILTER_CADENCE:
                retval = ixj_build_filter_cadence(j, (IXJ_FILTER_CADENCE *) arg);
                break;
+       case IXJCTL_SIGCTL:
+               if (copy_from_user(&j->sigdef, (char *)arg, sizeof(IXJ_SIGDEF)))
+                       retval = -EFAULT;
+               j->ixj_signals[j->sigdef.event] = j->sigdef.signal;
+               if(j->sigdef.event < 33) {
+                       raise = 1;
+                       for(mant = 0; mant < j->sigdef.event; mant++){
+                               raise *= 2;
+                       }
+                       if(j->sigdef.signal)
+                               j->ex_sig.bytes |= raise; 
+                       else
+                               j->ex_sig.bytes &= (raise^0xffff); 
+               }
+               break;
        case IXJCTL_INTERCOM_STOP:
-               if (arg != j->intercom
-                   || ixj[arg]->intercom != board)
+               if(arg < 0 || arg >= IXJMAX)
                        return -EINVAL;
-
                j->intercom = -1;
-               ixj[arg]->intercom = -1;
                ixj_record_stop(j);
-               ixj_record_stop(ixj[arg]);
                ixj_play_stop(j);
-               ixj_play_stop(ixj[arg]);
                idle(j);
-               idle(ixj[arg]);
+               get_ixj(arg)->intercom = -1;
+               ixj_record_stop(get_ixj(arg));
+               ixj_play_stop(get_ixj(arg));
+               idle(get_ixj(arg));
                break;
        case IXJCTL_INTERCOM_START:
-               if (ixj[arg] == NULL)
-                       return -ENODEV;
-
+               if(arg < 0 || arg >= IXJMAX)
+                       return -EINVAL;
                j->intercom = arg;
-               ixj[arg]->intercom = board;
-               ixj_play_start(ixj[arg]);
                ixj_record_start(j);
                ixj_play_start(j);
-               ixj_record_start(ixj[arg]);
-               idle(j);
-               idle(ixj[arg]);
+               get_ixj(arg)->intercom = board;
+               ixj_play_start(get_ixj(arg));
+               ixj_record_start(get_ixj(arg));
                break;
        }
+       if (ixjdebug & 0x0040)
+               printk("phone%d ioctl end, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);
+       clear_bit(board, &j->busyflags);
        return retval;
 }
 
 static int ixj_fasync(int fd, struct file *file_p, int mode)
 {
-       IXJ *j = ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
-
-       if (j == NULL) /* shouldn't happen! */
-               return -ENODEV;
+       IXJ *j = get_ixj(NUM(file_p->f_dentry->d_inode->i_rdev));
 
        return fasync_helper(fd, file_p, mode, &j->async_queue);
 }
 
 struct file_operations ixj_fops =
 {
-       owner:          THIS_MODULE,
-       read:           ixj_enhanced_read,
-       write:          ixj_enhanced_write,
-       poll:           ixj_poll,
-       ioctl:          ixj_ioctl,
-       release:        ixj_release,
-       fasync:         ixj_fasync
+        owner:          THIS_MODULE,
+        read:           ixj_enhanced_read,
+        write:          ixj_enhanced_write,
+        poll:           ixj_poll,
+        ioctl:          ixj_ioctl,
+        release:        ixj_release,
+        fasync:         ixj_fasync
 };
 
 static int ixj_linetest(IXJ *j)
 {
        unsigned long jifwait;
 
-       j->flags.incheck = 1;   // Testing
-       if (!j->flags.pots_correct) {
-               j->flags.pots_correct = 1;
+       j->flags.pstncheck = 1; /* Testing */
+       j->flags.pstn_present = 0; /* Assume the line is not there */
 
-               daa_int_read(j);        //Clear DAA Interrupt flags
-               //
-               // Hold all relays in the normally de-energized position.
-               //
+       daa_int_read(j);        /*Clear DAA Interrupt flags */
+       /* */
+       /* Hold all relays in the normally de-energized position. */
+       /* */
+
+       j->pld_slicw.bits.rly1 = 0;
+       j->pld_slicw.bits.rly2 = 0;
+       j->pld_slicw.bits.rly3 = 0;
+       outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+       j->pld_scrw.bits.daafsyncen = 0;        /* Turn off DAA Frame Sync */
 
+       outb_p(j->pld_scrw.byte, j->XILINXbase);
+       j->pld_slicr.byte = inb_p(j->XILINXbase + 0x01);
+       if (j->pld_slicr.bits.potspstn) {
+               j->flags.pots_pstn = 1;
+               j->flags.pots_correct = 0;
+               LED_SetState(0x4, j);
+       } else {
+               j->flags.pots_pstn = 0;
                j->pld_slicw.bits.rly1 = 0;
                j->pld_slicw.bits.rly2 = 0;
-               j->pld_slicw.bits.rly3 = 0;
+               j->pld_slicw.bits.rly3 = 1;
                outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-               j->pld_scrw.bits.daafsyncen = 0;        // Turn off DAA Frame Sync
+               j->pld_scrw.bits.daafsyncen = 0;        /* Turn off DAA Frame Sync */
 
                outb_p(j->pld_scrw.byte, j->XILINXbase);
-               j->pld_slicr.byte = inb_p(j->XILINXbase + 0x01);
-               if (j->pld_slicr.bits.potspstn) {
-                       j->flags.pots_pstn = 1;
-                       j->flags.pots_correct = 0;
+               daa_set_mode(j, SOP_PU_CONVERSATION);
+               jifwait = jiffies + hertz;
+               while (time_before(jiffies, jifwait)) {
+                       set_current_state(TASK_INTERRUPTIBLE);
+                       schedule_timeout(1);
+               }
+               daa_int_read(j);
+               daa_set_mode(j, SOP_PU_RESET);
+               if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
+                       j->flags.pots_correct = 0;      /* Should not be line voltage on POTS port. */
                        LED_SetState(0x4, j);
+                       j->pld_slicw.bits.rly3 = 0;
+                       outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
                } else {
-                       j->flags.pots_pstn = 0;
-                       j->pld_slicw.bits.rly1 = 0;
+                       j->flags.pots_correct = 1;
+                       LED_SetState(0x8, j);
+                       j->pld_slicw.bits.rly1 = 1;
                        j->pld_slicw.bits.rly2 = 0;
-                       j->pld_slicw.bits.rly3 = 1;
+                       j->pld_slicw.bits.rly3 = 0;
                        outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-                       j->pld_scrw.bits.daafsyncen = 0;        // Turn off DAA Frame Sync
-
-                       outb_p(j->pld_scrw.byte, j->XILINXbase);
-                       daa_set_mode(j, SOP_PU_CONVERSATION);
-                       jifwait = jiffies + hertz;
-                       while (time_before(jiffies, jifwait)) {
-                               set_current_state(TASK_INTERRUPTIBLE);
-                               schedule_timeout(1);
-                       }
-                       daa_int_read(j);
-                       daa_set_mode(j, SOP_PU_SLEEP);
-                       if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
-                               j->flags.pots_correct = 0;      // Should not be line voltage on POTS port.
-
-                               LED_SetState(0x4, j);
-                               j->pld_slicw.bits.rly3 = 0;
-                               outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-                       } else {
-                               j->flags.pots_correct = 1;
-                               LED_SetState(0x8, j);
-                               j->pld_slicw.bits.rly1 = 1;
-                               j->pld_slicw.bits.rly2 = 0;
-                               j->pld_slicw.bits.rly3 = 0;
-                               outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-                       }
                }
        }
-//      if (!j->flags.pstn_present) {
        j->pld_slicw.bits.rly3 = 0;
        outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
        daa_set_mode(j, SOP_PU_CONVERSATION);
@@ -5222,13 +6831,13 @@ static int ixj_linetest(IXJ *j)
                schedule_timeout(1);
        }
        daa_int_read(j);
-       daa_set_mode(j, SOP_PU_SLEEP);
+       daa_set_mode(j, SOP_PU_RESET);
        if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
+               j->pstn_sleeptil = jiffies + (hertz / 4);
                j->flags.pstn_present = 1;
        } else {
                j->flags.pstn_present = 0;
        }
-//      }
        if (j->flags.pstn_present) {
                if (j->flags.pots_correct) {
                        LED_SetState(0xA, j);
@@ -5242,36 +6851,39 @@ static int ixj_linetest(IXJ *j)
                        LED_SetState(0x5, j);
                }
        }
-       j->flags.incheck = 0;   // Testing
+       j->flags.pstncheck = 0; /* Testing */
        return j->flags.pstn_present;
 }
 
-static int ixj_selfprobe(IXJ *j, int cnt)
+static int ixj_selfprobe(IXJ *j)
 {
        unsigned short cmd;
        unsigned long jif;
-       int i;
+       int cnt;
        BYTES bytes;
-       
-       init_waitqueue_head(&j->poll_q);
-       init_waitqueue_head(&j->read_q);
-       init_waitqueue_head(&j->write_q);
-       if (ixjdebug > 0)
+
+        init_waitqueue_head(&j->poll_q);
+        init_waitqueue_head(&j->read_q);
+        init_waitqueue_head(&j->write_q);
+
+       while(atomic_read(&j->DSPWrite) > 0)
+               atomic_dec(&j->DSPWrite);
+       if (ixjdebug & 0x0002)
                printk(KERN_INFO "Write IDLE to Software Control Register\n");
-       ixj_WriteDSPCommand(0x0FE0, j); // Put the DSP in full power mode.
+       ixj_WriteDSPCommand(0x0FE0, j); /* Put the DSP in full power mode. */
 
        if (ixj_WriteDSPCommand(0x0000, j))             /* Write IDLE to Software Control Register */
                return -1;
-// The read values of the SSR should be 0x00 for the IDLE command
+/* The read values of the SSR should be 0x00 for the IDLE command */
        if (j->ssr.low || j->ssr.high)
                return -1;
-       if (ixjdebug > 0)
+       if (ixjdebug & 0x0002)
                printk(KERN_INFO "Get Device ID Code\n");
        if (ixj_WriteDSPCommand(0x3400, j))             /* Get Device ID Code */
                return -1;
        j->dsp.low = j->ssr.low;
        j->dsp.high = j->ssr.high;
-       if (ixjdebug > 0)
+       if (ixjdebug & 0x0002)
                printk(KERN_INFO "Get Device Version Code\n");
        if (ixj_WriteDSPCommand(0x3800, j))             /* Get Device Version Code */
                return -1;
@@ -5279,13 +6891,12 @@ static int ixj_selfprobe(IXJ *j, int cnt)
        j->ver.high = j->ssr.high;
        if (!j->cardtype) {
                if (j->dsp.low == 0x21) {
-//      j->XILINXbase = j->DSPbase + 0x10;
                        bytes.high = bytes.low = inb_p(j->XILINXbase + 0x02);
                        outb_p(bytes.low ^ 0xFF, j->XILINXbase + 0x02);
-// Test for Internet LineJACK or Internet PhoneJACK Lite
+/* Test for Internet LineJACK or Internet PhoneJACK Lite */
                        bytes.low = inb_p(j->XILINXbase + 0x02);
-                       if (bytes.low == bytes.high)    //  Register is read only on
-                               //  Internet PhoneJack Lite
+                       if (bytes.low == bytes.high)    /*  Register is read only on */
+                               /*  Internet PhoneJack Lite */
                         {
                                j->cardtype = QTI_PHONEJACK_LITE;
                                if (check_region(j->XILINXbase, 4)) {
@@ -5343,14 +6954,12 @@ static int ixj_selfprobe(IXJ *j, int cnt)
                        break;
                }
        }
-       if (j->dsp.low == 0x20
-           || j->cardtype == QTI_PHONEJACK_LITE
-           || j->cardtype == QTI_PHONEJACK_PCI) {
-               if (ixjdebug > 0)
+       if (j->dsp.low == 0x20 || j->cardtype == QTI_PHONEJACK_LITE || j->cardtype == QTI_PHONEJACK_PCI) {
+               if (ixjdebug & 0x0002)
                        printk(KERN_INFO "Write CODEC config to Software Control Register\n");
                if (ixj_WriteDSPCommand(0xC462, j))             /* Write CODEC config to Software Control Register */
                        return -1;
-               if (ixjdebug > 0)
+               if (ixjdebug & 0x0002)
                        printk(KERN_INFO "Write CODEC timing to Software Control Register\n");
                if (j->cardtype == QTI_PHONEJACK) {
                        cmd = 0x9FF2;
@@ -5362,7 +6971,7 @@ static int ixj_selfprobe(IXJ *j, int cnt)
        } else {
                if (set_base_frame(j, 30) != 30)
                        return -1;
-               if (ixjdebug > 0)
+               if (ixjdebug & 0x0002)
                        printk(KERN_INFO "Write CODEC config to Software Control Register\n");
                if (j->cardtype == QTI_PHONECARD) {
                        if (ixj_WriteDSPCommand(0xC528, j))             /* Write CODEC config to Software Control Register */
@@ -5371,7 +6980,7 @@ static int ixj_selfprobe(IXJ *j, int cnt)
                if (j->cardtype == QTI_LINEJACK) {
                        if (ixj_WriteDSPCommand(0xC528, j))             /* Write CODEC config to Software Control Register */
                                return -1;
-                       if (ixjdebug > 0)
+                       if (ixjdebug & 0x0002)
                                printk(KERN_INFO "Turn on the PLD Clock at 8Khz\n");
                        j->pld_clock.byte = 0;
                        outb_p(j->pld_clock.byte, j->XILINXbase + 0x04);
@@ -5379,7 +6988,7 @@ static int ixj_selfprobe(IXJ *j, int cnt)
        }
 
        if (j->dsp.low == 0x20) {
-               if (ixjdebug > 0)
+               if (ixjdebug & 0x0002)
                        printk(KERN_INFO "Configure GPIO pins\n");
                j->gpio.bytes.high = 0x09;
 /*  bytes.low = 0xEF;  0xF7 */
@@ -5391,7 +7000,7 @@ static int ixj_selfprobe(IXJ *j, int cnt)
                j->gpio.bits.gpio6 = 1;
                j->gpio.bits.gpio7 = 1;
                ixj_WriteDSPCommand(j->gpio.word, j);   /* Set GPIO pin directions */
-               if (ixjdebug > 0)
+               if (ixjdebug & 0x0002)
                        printk(KERN_INFO "Enable SLIC\n");
                j->gpio.bytes.high = 0x0B;
                j->gpio.bytes.low = 0x00;
@@ -5428,51 +7037,86 @@ static int ixj_selfprobe(IXJ *j, int cnt)
                        }
                        LED_SetState(0x0, j);
                        daa_get_version(j);
-                       if (ixjdebug > 0)
+                       if (ixjdebug & 0x0002)
                                printk("Loading DAA Coefficients\n");
                        DAA_Coeff_US(j);
-                       if (!ixj_daa_write(j))
-                               printk("DAA write failed on board %d\n",
-                                      j->p.board);
-                       ixj_daa_cid_reset(j);
+                       if (!ixj_daa_write(j)) {
+                               printk("DAA write failed on board %d\n", j->board);
+                               return -1;
+                       }
+                       if(!ixj_daa_cid_reset(j)) {
+                               printk("DAA CID reset failed on board %d\n", j->board);
+                               return -1;
+                       }
                        j->flags.pots_correct = 0;
                        j->flags.pstn_present = 0;
                        ixj_linetest(j);
                        if (j->flags.pots_correct) {
-                               j->pld_scrw.bits.daafsyncen = 0;        // Turn off DAA Frame Sync
+                               j->pld_scrw.bits.daafsyncen = 0;        /* Turn off DAA Frame Sync */
 
                                outb_p(j->pld_scrw.byte, j->XILINXbase);
                                j->pld_slicw.bits.rly1 = 1;
                                j->pld_slicw.bits.spken = 1;
                                outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
                                SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
+/*                             SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */
                                j->port = PORT_POTS;
                        }
                        ixj_set_port(j, PORT_PSTN);
                        ixj_set_pots(j, 1);
-                       if (ixjdebug > 0)
+                       if (ixjdebug & 0x0002)
                                printk(KERN_INFO "Enable Mixer\n");
-                       ixj_mixer(0x0000, j);   //Master Volume Left unmute 0db
+                       ixj_mixer(0x0000, j);   /*Master Volume Left unmute 0db */
+                       ixj_mixer(0x0100, j);   /*Master Volume Right unmute 0db */
+
+                       ixj_mixer(0x0203, j);   /*Voice Left Volume unmute 6db */
+                       ixj_mixer(0x0303, j);   /*Voice Right Volume unmute 6db */
+
+                       ixj_mixer(0x0480, j);   /*FM Left mute */
+                       ixj_mixer(0x0580, j);   /*FM Right mute */
 
-                       ixj_mixer(0x0100, j);   //Master Volume Right unmute 0db
+                       ixj_mixer(0x0680, j);   /*CD Left mute */
+                       ixj_mixer(0x0780, j);   /*CD Right mute */
 
-                       ixj_mixer(0x0F00, j);   //Mono Out Volume unmute 0db
+                       ixj_mixer(0x0880, j);   /*Line Left mute */
+                       ixj_mixer(0x0980, j);   /*Line Right mute */
 
-                       ixj_mixer(0x0C00, j);   //Mono1 Volume unmute 0db
+                       ixj_mixer(0x0A80, j);   /*Aux left mute  */
+                       ixj_mixer(0x0B80, j);   /*Aux right mute */
 
-                       ixj_mixer(0x0200, j);   //Voice Left Volume unmute 0db
+                       ixj_mixer(0x0C00, j);   /*Mono1 unmute 12db */
+                       ixj_mixer(0x0D80, j);   /*Mono2 mute */
 
-                       ixj_mixer(0x0300, j);   //Voice Right Volume unmute 0db
+                       ixj_mixer(0x0E80, j);   /*Mic mute */
 
-                       ixj_mixer(0x110C, j);   //Voice Left and Right out
+                       ixj_mixer(0x0F00, j);   /*Mono Out Volume unmute 0db */
 
-                       ixj_mixer(0x1401, j);   //Mono1 switch on mixer left
+                       ixj_mixer(0x1000, j);   /*Voice Left and Right out only */
+                       ixj_mixer(0x110C, j);
 
-                       ixj_mixer(0x1501, j);   //Mono1 switch on mixer right
 
-                       ixj_mixer(0x1700, j);   //Clock select
+                       ixj_mixer(0x1200, j);   /*Mono1 switch on mixer left */
+                       ixj_mixer(0x1401, j);
 
-                       ixj_mixer(0x1800, j);   //ADC Source select
+                       ixj_mixer(0x1300, j);       /*Mono1 switch on mixer right */
+                       ixj_mixer(0x1501, j);
+
+                       ixj_mixer(0x1700, j);   /*Clock select */
+
+                       ixj_mixer(0x1800, j);   /*ADC input from mixer */
+
+                       ixj_mixer(0x1901, j);   /*Mic gain 30db */
+
+                       if (ixjdebug & 0x0002)
+                               printk(KERN_INFO "Setting Default US Ring Cadence Detection\n");
+                       j->cadence_f[4].state = 0;
+                       j->cadence_f[4].on1 = 0;        /*Cadence Filter 4 is used for PSTN ring cadence */
+                       j->cadence_f[4].off1 = 0;
+                       j->cadence_f[4].on2 = 0;
+                       j->cadence_f[4].off2 = 0;
+                       j->cadence_f[4].on3 = 0;
+                       j->cadence_f[4].off3 = 0;       /* These should represent standard US ring pulse. */
+                       j->pstn_last_rmr = jiffies;
 
                } else {
                        if (j->cardtype == QTI_PHONECARD) {
@@ -5482,6 +7126,7 @@ static int ixj_selfprobe(IXJ *j, int cnt)
                        } else {
                                ixj_set_port(j, PORT_POTS);
                                SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
+/*                             SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */
                        }
                }
        }
@@ -5490,31 +7135,43 @@ static int ixj_selfprobe(IXJ *j, int cnt)
        j->framesread = j->frameswritten = 0;
        j->read_wait = j->write_wait = 0;
        j->rxreadycheck = j->txreadycheck = 0;
+
+       /* initialise the DTMF prescale to a sensible value */
+       if (j->cardtype == QTI_LINEJACK) {
+               set_dtmf_prescale(j, 0x10); 
+       } else {
+               set_dtmf_prescale(j, 0x40); 
+       }
        set_play_volume(j, 0x100);
        set_rec_volume(j, 0x100);
+
        if (ixj_WriteDSPCommand(0x0000, j))             /* Write IDLE to Software Control Register */
                return -1;
-// The read values of the SSR should be 0x00 for the IDLE command
+/* The read values of the SSR should be 0x00 for the IDLE command */
        if (j->ssr.low || j->ssr.high)
                return -1;
-       if (ixjdebug > 0)
+
+       if (ixjdebug & 0x0002)
                printk(KERN_INFO "Enable Line Monitor\n");
-       if (ixjdebug > 0)
+
+       if (ixjdebug & 0x0002)
                printk(KERN_INFO "Set Line Monitor to Asyncronous Mode\n");
-       if (ixj_WriteDSPCommand(0x7E01, j))             // Asynchronous Line Monitor
 
+       if (ixj_WriteDSPCommand(0x7E01, j))             /* Asynchronous Line Monitor */
                return -1;
-       if (ixjdebug > 0)
+
+       if (ixjdebug & 0x002)
                printk(KERN_INFO "Enable DTMF Detectors\n");
-       if (ixj_WriteDSPCommand(0x5151, j))             // Enable DTMF detection
 
+       if (ixj_WriteDSPCommand(0x5151, j))             /* Enable DTMF detection */
                return -1;
-       if (ixj_WriteDSPCommand(0x6E01, j))             // Set Asyncronous Tone Generation
 
+       if (ixj_WriteDSPCommand(0x6E01, j))             /* Set Asyncronous Tone Generation */
                return -1;
-       set_rec_depth(j, 2);    // Set Record Channel Limit to 2 frames
 
-       set_play_depth(j, 2);   // Set Playback Channel Limit to 2 frames
+       set_rec_depth(j, 2);    /* Set Record Channel Limit to 2 frames */
+
+       set_play_depth(j, 2);   /* Set Playback Channel Limit to 2 frames */
 
        j->ex.bits.dtmf_ready = 0;
        j->dtmf_state = 0;
@@ -5526,34 +7183,74 @@ static int ixj_selfprobe(IXJ *j, int cnt)
        j->drybuffer = 0;
        j->winktime = 320;
        j->flags.dtmf_oob = 0;
-       for (i = 0; i < 4; i++)
-               j->cadence_f[i].enable = 0;
+       for (cnt = 0; cnt < 4; cnt++)
+               j->cadence_f[cnt].enable = 0;
        /* must be a device on the specified address */
-       ixj_WriteDSPCommand(0x0FE3, j); // Put the DSP in 1/5 power mode.
+       ixj_WriteDSPCommand(0x0FE3, j); /* Put the DSP in 1/5 power mode. */
+
+       /* Set up the default signals for events */
+       for (cnt = 0; cnt < 35; cnt++)
+               j->ixj_signals[cnt] = SIGIO;
+
+       /* Set the excetion signal enable flags */
+       j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring = 
+       j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 = 
+       j->ex_sig.bits.f3 = j->ex_sig.bits.fc0 = j->ex_sig.bits.fc1 = j->ex_sig.bits.fc2 = j->ex_sig.bits.fc3 = 1;
+#ifdef IXJ_DYN_ALLOC
+       j->fskdata = NULL;
+#endif
+       j->fskdcnt = 0;
+       j->cidcw_wait = 0;
        /* Register with the Telephony for Linux subsystem */
        j->p.f_op = &ixj_fops;
        j->p.open = ixj_open;
-       j->p.board = cnt;
+       j->p.board = j->board;
        phone_register_device(&j->p, PHONE_UNIT_ANY);
-       add_caps(j);
+
+       ixj_init_timer(j);
+       ixj_add_timer(j);
        return 0;
 }
 
-int ixj_get_status_proc(char *buf)
+/*
+ *     Exported service for pcmcia card handling
+ */
+IXJ *ixj_pcmcia_probe(unsigned long dsp, unsigned long xilinx)
+{
+       IXJ *j = ixj_alloc();
+
+       j->board = 0;
+
+       j->DSPbase = dsp;
+       j->XILINXbase = xilinx;
+       j->cardtype = QTI_PHONECARD;
+       ixj_selfprobe(j);
+       return j;
+}
+
+EXPORT_SYMBOL(ixj_pcmcia_probe);               /* Fpr PCMCIA */
+
+static int ixj_get_status_proc(char *buf)
 {
        int len;
        int cnt;
        IXJ *j;
        len = 0;
-       len += sprintf(buf + len, "\n%s", ixj_c_rcsid);
+       len += sprintf(buf + len, "%s", ixj_c_rcsid);
        len += sprintf(buf + len, "\n%s", ixj_h_rcsid);
        len += sprintf(buf + len, "\n%s", ixjuser_h_rcsid);
-       for (cnt = 0; cnt < IXJMAX; cnt++) {
-               j = ixj[cnt];
+       len += sprintf(buf + len, "\nDriver version %i.%i.%i", IXJ_VER_MAJOR, IXJ_VER_MINOR, IXJ_BLD_VER);
+       len += sprintf(buf + len, "\nsizeof IXJ struct %d bytes", sizeof(IXJ));
+       len += sprintf(buf + len, "\nsizeof DAA struct %d bytes", sizeof(DAA_REGS));
+       len += sprintf(buf + len, "\nUsing old telephony API");
+       len += sprintf(buf + len, "\nDebug Level %d\n", ixjdebug);
 
-               if (j == NULL)
+       for (cnt = 0; cnt < IXJMAX; cnt++) {
+               j = get_ixj(cnt);
+               if(j==NULL)
                        continue;
-
                if (j->DSPbase) {
                        len += sprintf(buf + len, "\nCard Num %d", cnt);
                        len += sprintf(buf + len, "\nDSP Base Address 0x%4.4x", j->DSPbase);
@@ -5570,7 +7267,7 @@ int ixj_get_status_proc(char *buf)
                                len += sprintf(buf + len, "\nCard Type = Internet LineJACK");
                                if (j->flags.g729_loaded)
                                        len += sprintf(buf + len, " w/G.729 A/B");
-                               len += sprintf(buf + len, " Country = %d", j->country);
+                               len += sprintf(buf + len, " Country = %d", j->daa_country);
                                break;
                        case (QTI_PHONEJACK_LITE):
                                len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK Lite");
@@ -5597,8 +7294,7 @@ int ixj_get_status_proc(char *buf)
                        }
                        len += sprintf(buf + len, "\nReaders %d", j->readers);
                        len += sprintf(buf + len, "\nWriters %d", j->writers);
-                       /* FIXME: This makes no sense! */
-                       len += sprintf(buf + len, "\nFSK words %d", ixj[2] ? ixj[2]->fskdcnt : 0);
+                       add_caps(j);
                        len += sprintf(buf + len, "\nCapabilities %d", j->caps);
                        if (j->dsp.low != 0x20)
                                len += sprintf(buf + len, "\nDSP Processor load %d", j->proc_load);
@@ -5607,11 +7303,6 @@ int ixj_get_status_proc(char *buf)
                        else
                                len += sprintf(buf + len, "\nCaller ID data not sent");
 
-                       len += sprintf(buf + len, "\nCaller ID Date %s%s", j->cid_send.month, j->cid_send.day);
-                       len += sprintf(buf + len, "\nCaller ID Time %s%s", j->cid_send.hour, j->cid_send.min);
-                       len += sprintf(buf + len, "\nCaller ID Name %s", j->cid_send.name);
-                       len += sprintf(buf + len, "\nCaller ID Number %s", j->cid_send.number);
-
                        len += sprintf(buf + len, "\nPlay CODEC ");
                        switch (j->play_codec) {
                        case G723_63:
@@ -5635,6 +7326,9 @@ int ixj_get_status_proc(char *buf)
                        case G729:
                                len += sprintf(buf + len, "G.729");
                                break;
+                       case G729B:
+                               len += sprintf(buf + len, "G.729B");
+                               break;
                        case ULAW:
                                len += sprintf(buf + len, "uLaw");
                                break;
@@ -5677,6 +7371,9 @@ int ixj_get_status_proc(char *buf)
                        case G729:
                                len += sprintf(buf + len, "G.729");
                                break;
+                       case G729B:
+                               len += sprintf(buf + len, "G.729B");
+                               break;
                        case ULAW:
                                len += sprintf(buf + len, "uLaw");
                                break;
@@ -5696,33 +7393,49 @@ int ixj_get_status_proc(char *buf)
                                len += sprintf(buf + len, "NO CODEC CHOSEN");
                                break;
                        }
+                       len += sprintf(buf + len, "\nAEC ");
                        switch (j->aec_level) {
                        case AEC_OFF:
-                               len += sprintf(buf + len, "\n AEC OFF");
+                               len += sprintf(buf + len, "Off");
                                break;
                        case AEC_LOW:
-                               len += sprintf(buf + len, "\n AEC LOW");
+                               len += sprintf(buf + len, "Low");
                                break;
                        case AEC_MED:
-                               len += sprintf(buf + len, "\n AEC MED");
+                               len += sprintf(buf + len, "Med");
                                break;
                        case AEC_HIGH:
-                               len += sprintf(buf + len, "\n AEC HIGH");
+                               len += sprintf(buf + len, "High");
+                               break;
+                       case AEC_AUTO:
+                               len += sprintf(buf + len, "Auto");
+                               break;
+                       case AEC_AGC:
+                               len += sprintf(buf + len, "AEC/AGC");
+                               break;
+                       default:
+                               len += sprintf(buf + len, "unknown(%i)", j->aec_level);
                                break;
                        }
-                       len += sprintf(buf + len, "\nHook state %d", j->r_hook);        // ixj_hookstate(cnt));
+
+                       len += sprintf(buf + len, "\nRec volume 0x%x", get_rec_volume(j));
+                       len += sprintf(buf + len, "\nPlay volume 0x%x", get_play_volume(j));
+                       len += sprintf(buf + len, "\nDTMF prescale 0x%x", get_dtmf_prescale(j));
+                       
+                       len += sprintf(buf + len, "\nHook state %d", j->hookstate); /* j->r_hook);      */
 
                        if (j->cardtype == QTI_LINEJACK) {
                                len += sprintf(buf + len, "\nPOTS Correct %d", j->flags.pots_correct);
                                len += sprintf(buf + len, "\nPSTN Present %d", j->flags.pstn_present);
+                               len += sprintf(buf + len, "\nPSTN Check %d", j->flags.pstncheck);
                                len += sprintf(buf + len, "\nPOTS to PSTN %d", j->flags.pots_pstn);
-                               len += sprintf(buf + len, "\nPSTN sleeptil %ld - jiffies %ld", j->pstn_sleeptil, jiffies);
                                switch (j->daa_mode) {
                                case SOP_PU_SLEEP:
                                        len += sprintf(buf + len, "\nDAA PSTN On Hook");
                                        break;
                                case SOP_PU_RINGING:
                                        len += sprintf(buf + len, "\nDAA PSTN Ringing");
+                                       len += sprintf(buf + len, "\nRinging state = %d", j->cadence_f[4].state);
                                        break;
                                case SOP_PU_CONVERSATION:
                                        len += sprintf(buf + len, "\nDAA PSTN Off Hook");
@@ -5731,6 +7444,16 @@ int ixj_get_status_proc(char *buf)
                                        len += sprintf(buf + len, "\nDAA PSTN Pulse Dialing");
                                        break;
                                }
+                               len += sprintf(buf + len, "\nDAA RMR = %d", j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR);
+                               len += sprintf(buf + len, "\nDAA VDD OK = %d", j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK);
+                               len += sprintf(buf + len, "\nDAA CR0 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg);
+                               len += sprintf(buf + len, "\nDAA CR1 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg);
+                               len += sprintf(buf + len, "\nDAA CR2 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg);
+                               len += sprintf(buf + len, "\nDAA CR3 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg);
+                               len += sprintf(buf + len, "\nDAA CR4 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg);
+                               len += sprintf(buf + len, "\nDAA CR5 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg);
+                               len += sprintf(buf + len, "\nDAA XR0 = 0x%02x", j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg);
+                               len += sprintf(buf + len, "\nDAA ringstop %ld - jiffies %ld", j->pstn_ring_stop, jiffies);
                        }
                        switch (j->port) {
                        case PORT_POTS:
@@ -5758,8 +7481,7 @@ int ixj_get_status_proc(char *buf)
                                case PLD_SLIC_STATE_ACTIVE:
                                        len += sprintf(buf + len, "ACTIVE");
                                        break;
-                               case PLD_SLIC_STATE_OHT:        // On-hook transmit
-
+                               case PLD_SLIC_STATE_OHT:        /* On-hook transmit */
                                        len += sprintf(buf + len, "OHT");
                                        break;
                                case PLD_SLIC_STATE_TIPOPEN:
@@ -5768,12 +7490,10 @@ int ixj_get_status_proc(char *buf)
                                case PLD_SLIC_STATE_STANDBY:
                                        len += sprintf(buf + len, "STANDBY");
                                        break;
-                               case PLD_SLIC_STATE_APR:        // Active polarity reversal
-
+                               case PLD_SLIC_STATE_APR:        /* Active polarity reversal */
                                        len += sprintf(buf + len, "APR");
                                        break;
-                               case PLD_SLIC_STATE_OHTPR:      // OHT polarity reversal
-
+                               case PLD_SLIC_STATE_OHTPR:      /* OHT polarity reversal */
                                        len += sprintf(buf + len, "OHTPR");
                                        break;
                                default:
@@ -5781,52 +7501,35 @@ int ixj_get_status_proc(char *buf)
                                        break;
                                }
                        }
+                       len += sprintf(buf + len, "\nBase Frame %2.2x.%2.2x", j->baseframe.high, j->baseframe.low);
+                       len += sprintf(buf + len, "\nCID Base Frame %2d", j->cid_base_frame_size);
 #ifdef PERFMON_STATS
                        len += sprintf(buf + len, "\nTimer Checks %ld", j->timerchecks);
                        len += sprintf(buf + len, "\nRX Ready Checks %ld", j->rxreadycheck);
                        len += sprintf(buf + len, "\nTX Ready Checks %ld", j->txreadycheck);
-                       len += sprintf(buf + len, "\nBase Frame %2.2x.%2.2x", j->baseframe.high, j->baseframe.low);
                        len += sprintf(buf + len, "\nFrames Read %ld", j->framesread);
                        len += sprintf(buf + len, "\nFrames Written %ld", j->frameswritten);
                        len += sprintf(buf + len, "\nDry Buffer %ld", j->drybuffer);
                        len += sprintf(buf + len, "\nRead Waits %ld", j->read_wait);
                        len += sprintf(buf + len, "\nWrite Waits %ld", j->write_wait);
+                        len += sprintf(buf + len, "\nStatus Waits %ld", j->statuswait);
+                        len += sprintf(buf + len, "\nStatus Wait Fails %ld", j->statuswaitfail);
+                        len += sprintf(buf + len, "\nPControl Waits %ld", j->pcontrolwait);
+                        len += sprintf(buf + len, "\nPControl Wait Fails %ld", j->pcontrolwaitfail);
+                        len += sprintf(buf + len, "\nIs Control Ready Checks %ld", j->iscontrolready);
+                        len += sprintf(buf + len, "\nIs Control Ready Check failures %ld", j->iscontrolreadyfail);
 #endif
                        len += sprintf(buf + len, "\n");
-               }
-       }
-       return len;
-}
-
-int ixj_get_status_proc_fsk(char *buf)
-{
-       int len;
-       len = 0;
-
-       /* This makes no sense - why is ixj[2] special? */
-       if (ixj[2] != NULL && ixj[2]->fskdcnt) {
-               memcpy(buf, &ixj[2]->fskdata, (ixj[2]->fskdcnt) * 2);
-               len += ixj[2]->fskdcnt * 2;
-       }
-       return len;
-}
-
-static int ixj_read_proc(char *page, char **start, off_t off,
-                              int count, int *eof, void *data)
-{
-        int len = ixj_get_status_proc(page);
-        if (len <= off+count) *eof = 1;
-        *start = page + off;
-        len -= off;
-        if (len>count) len = count;
-        if (len<0) len = 0;
-        return len;
+               }
+       }
+       return len;
 }
 
-static int ixj_read_proc_fsk(char *page, char **start, off_t off,
+static int ixj_read_proc(char *page, char **start, off_t off,
                               int count, int *eof, void *data)
 {
-        int len = ixj_get_status_proc_fsk(page);
+        int len = ixj_get_status_proc(page);
         if (len <= off+count) *eof = 1;
         *start = page + off;
         len -= off;
@@ -5835,397 +7538,92 @@ static int ixj_read_proc_fsk(char *page, char **start, off_t off,
         return len;
 }
 
-MODULE_DESCRIPTION("Internet Phone/Internet LineJack module - www.quicknet.net");
-MODULE_AUTHOR("Ed Okerson <eokerson@quicknet.net>");
-
-#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-MODULE_PARM(pc_debug, "i");
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-#else
-#define DEBUG(n, args...)
-#endif /* PCMCIA_DEBUG */
-
-typedef struct ixj_info_t {
-       int ndev;
-       dev_node_t node;
-       struct ixj *port;
-} ixj_info_t;
-static dev_link_t *ixj_attach(void);
-static void ixj_detach(dev_link_t *);
-static void ixj_config(dev_link_t * link);
-static void ixj_cs_release(u_long arg);
-static int ixj_event(event_t event, int priority, event_callback_args_t * args);
-static dev_info_t dev_info = "ixj_cs";
-static dev_link_t *dev_list = NULL;
-static void cs_error(client_handle_t handle, int func, int ret)
-{
-       error_info_t err =
-       {
-               func, ret
-       };
-       CardServices(ReportError, handle, &err);
-}
-
-static dev_link_t *ixj_attach(void)
-{
-       client_reg_t client_reg;
-       dev_link_t *link;
-       int ret;
-       DEBUG(0, "ixj_attach()\n");
-       /* Create new ixj device */
-       link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
-       if (!link)
-               return NULL;
-       memset(link, 0, sizeof(struct dev_link_t));
-       link->release.function = &ixj_cs_release;
-       link->release.data = (u_long) link;
-       link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-       link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
-       link->io.IOAddrLines = 3;
-       link->conf.Vcc = 50;
-       link->conf.IntType = INT_MEMORY_AND_IO;
-       link->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL);
-       if (!link->priv)
-               return NULL;
-       memset(link->priv, 0, sizeof(struct ixj_info_t));
-       /* Register with Card Services */
-       link->next = dev_list;
-       dev_list = link;
-       client_reg.dev_info = &dev_info;
-       client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-       client_reg.EventMask =
-           CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-           CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-           CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-       client_reg.event_handler = &ixj_event;
-       client_reg.Version = 0x0210;
-       client_reg.event_callback_args.client_data = link;
-       ret = CardServices(RegisterClient, &link->handle, &client_reg);
-       if (ret != CS_SUCCESS) {
-               cs_error(link->handle, RegisterClient, ret);
-               ixj_detach(link);
-               return NULL;
-       }
-       return link;
-}
-
-static void ixj_detach(dev_link_t * link)
-{
-       dev_link_t **linkp;
-       long flags;
-       int ret;
-       DEBUG(0, "ixj_detach(0x%p)\n", link);
-       for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-               if (*linkp == link)
-                       break;
-       if (*linkp == NULL)
-               return;
-       save_flags(flags);
-       cli();
-       if (link->state & DEV_RELEASE_PENDING) {
-               del_timer(&link->release);
-               link->state &= ~DEV_RELEASE_PENDING;
-       }
-       restore_flags(flags);
-       if (link->state & DEV_CONFIG)
-               ixj_cs_release((u_long) link);
-       if (link->handle) {
-               ret = CardServices(DeregisterClient, link->handle);
-               if (ret != CS_SUCCESS)
-                       cs_error(link->handle, DeregisterClient, ret);
-       }
-       /* Unlink device structure, free bits */
-       *linkp = link->next;
-       kfree(link->priv);
-       kfree(link);
-}
-
-#define CS_CHECK(fn, args...) \
-while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
-
-#define CFG_CHECK(fn, args...) \
-if (CardServices(fn, args) != 0) goto next_entry
-
-void ixj_get_serial(dev_link_t * link, IXJ * j)
-{
-       client_handle_t handle;
-       tuple_t tuple;
-       u_short buf[128];
-       char *str;
-       int last_ret, last_fn, i, place;
-       handle = link->handle;
-       DEBUG(0, "ixj_get_serial(0x%p)\n", link);
-       tuple.TupleData = (cisdata_t *) buf;
-       tuple.TupleOffset = 0;
-       tuple.TupleDataMax = 80;
-       tuple.Attributes = 0;
-       tuple.DesiredTuple = CISTPL_VERS_1;
-       CS_CHECK(GetFirstTuple, handle, &tuple);
-       CS_CHECK(GetTupleData, handle, &tuple);
-       str = (char *) buf;
-       printk("PCMCIA Version %d.%d\n", str[0], str[1]);
-       str += 2;
-       printk("%s", str);
-       str = str + strlen(str) + 1;
-       printk(" %s", str);
-       str = str + strlen(str) + 1;
-       place = 1;
-       for (i = strlen(str) - 1; i >= 0; i--) {
-               switch (str[i]) {
-               case '0':
-               case '1':
-               case '2':
-               case '3':
-               case '4':
-               case '5':
-               case '6':
-               case '7':
-               case '8':
-               case '9':
-                       j->serial += (str[i] - 48) * place;
-                       break;
-               case 'A':
-               case 'B':
-               case 'C':
-               case 'D':
-               case 'E':
-               case 'F':
-                       j->serial += (str[i] - 55) * place;
-                       break;
-               case 'a':
-               case 'b':
-               case 'c':
-               case 'd':
-               case 'e':
-               case 'f':
-                       j->serial += (str[i] - 87) * place;
-                       break;
-               }
-               place = place * 0x10;
-       }
-       str = str + strlen(str) + 1;
-       printk(" version %s\n", str);
-      cs_failed:
-       return;
-}
-
-void ixj_config(dev_link_t * link)
-{
-       IXJ *j;
-       client_handle_t handle;
-       ixj_info_t *info;
-       tuple_t tuple;
-       u_short buf[128];
-       cisparse_t parse;
-       config_info_t conf;
-       cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
-       cistpl_cftable_entry_t dflt =
-       {
-               0
-       };
-       int last_ret, last_fn;
-       handle = link->handle;
-       info = link->priv;
-       DEBUG(0, "ixj_config(0x%p)\n", link);
-       tuple.TupleData = (cisdata_t *) buf;
-       tuple.TupleOffset = 0;
-       tuple.TupleDataMax = 255;
-       tuple.Attributes = 0;
-       tuple.DesiredTuple = CISTPL_CONFIG;
-       CS_CHECK(GetFirstTuple, handle, &tuple);
-       CS_CHECK(GetTupleData, handle, &tuple);
-       CS_CHECK(ParseTuple, handle, &tuple, &parse);
-       link->conf.ConfigBase = parse.config.base;
-       link->conf.Present = parse.config.rmask[0];
-       link->state |= DEV_CONFIG;
-       CS_CHECK(GetConfigurationInfo, handle, &conf);
-       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-       tuple.Attributes = 0;
-       CS_CHECK(GetFirstTuple, handle, &tuple);
-       while (1) {
-               CFG_CHECK(GetTupleData, handle, &tuple);
-               CFG_CHECK(ParseTuple, handle, &tuple, &parse);
-               if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
-                       cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
-                       link->conf.ConfigIndex = cfg->index;
-                       link->io.BasePort1 = io->win[0].base;
-                       link->io.NumPorts1 = io->win[0].len;
-                       if (io->nwin == 2) {
-                               link->io.BasePort2 = io->win[1].base;
-                               link->io.NumPorts2 = io->win[1].len;
-                       }
-                       CFG_CHECK(RequestIO, link->handle, &link->io);
-                       /* If we've got this far, we're done */
-                       break;
-               }
-             next_entry:
-               if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
-                       dflt = *cfg;
-               CS_CHECK(GetNextTuple, handle, &tuple);
-       }
-
-       CS_CHECK(RequestConfiguration, handle, &link->conf);
-
-       
-       if ((j = kmalloc(sizeof(*j), GFP_KERNEL)) == NULL)
-               goto cs_failed;
-
-       ixj[0] = j;
-
-       j->DSPbase = link->io.BasePort1;
-       j->XILINXbase = link->io.BasePort1 + 0x10;
-       j->cardtype = QTI_PHONECARD;
-       ixj_selfprobe(j, 0);
-
-       info->ndev = 1;
-       info->node.major = PHONE_MAJOR;
-       link->dev = &info->node;
-       ixj_get_serial(link, j);
-       link->state &= ~DEV_CONFIG_PENDING;
-       return;
-
-      cs_failed:
-       cs_error(link->handle, last_fn, last_ret);
-       ixj_cs_release((u_long) link);
-}
-
-void ixj_cs_release(u_long arg)
-{
-       dev_link_t *link = (dev_link_t *) arg;
-       ixj_info_t *info = link->priv;
-       DEBUG(0, "ixj_cs_release(0x%p)\n", link);
-       info->ndev = 0;
-       link->dev = NULL;
-       CardServices(ReleaseConfiguration, link->handle);
-       CardServices(ReleaseIO, link->handle, &link->io);
-       link->state &= ~DEV_CONFIG;
-
-       kfree(ixj[0]);
-       ixj[0] = NULL;
-}
-
-int ixj_event(event_t event, int priority, event_callback_args_t * args)
-{
-       dev_link_t *link = args->client_data;
-       DEBUG(1, "ixj_event(0x%06x)\n", event);
-       switch (event) {
-       case CS_EVENT_CARD_REMOVAL:
-               link->state &= ~DEV_PRESENT;
-               if (link->state & DEV_CONFIG) {
-                       link->release.expires = jiffies + (HZ / 20);
-                       link->state |= DEV_RELEASE_PENDING;
-                       add_timer(&link->release);
-               }
-               break;
-       case CS_EVENT_CARD_INSERTION:
-               link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-               ixj_config(link);
-               break;
-       case CS_EVENT_PM_SUSPEND:
-               link->state |= DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_RESET_PHYSICAL:
-               if (link->state & DEV_CONFIG)
-                       CardServices(ReleaseConfiguration, link->handle);
-               break;
-       case CS_EVENT_PM_RESUME:
-               link->state &= ~DEV_SUSPEND;
-               /* Fall through... */
-       case CS_EVENT_CARD_RESET:
-               if (DEV_OK(link))
-                       CardServices(RequestConfiguration, link->handle, &link->conf);
-               break;
-       }
-       return 0;
-}
-
-#endif /* CONFIG_PCMCIA */
 
 static void cleanup(void)
 {
        int cnt;
-       del_timer(&ixj_timer);
-       for (cnt = 0; cnt < IXJMAX; cnt++) {
-               IXJ *j = ixj[cnt];
-
-               if (j == NULL)
-                       continue;
+       IXJ *j;
 
-               if (j->cardtype == QTI_LINEJACK) {
-                       j->pld_scrw.bits.daafsyncen = 0;        // Turn off DAA Frame Sync
+       for (cnt = 0; cnt < IXJMAX; cnt++) {
+               j = get_ixj(cnt);
+               if(j != NULL && j->DSPbase) {
+                       if (ixjdebug & 0x0002)
+                               printk(KERN_INFO "IXJ: Deleting timer for /dev/phone%d\n", cnt);
+                       del_timer(&j->timer);
+                       if (j->cardtype == QTI_LINEJACK) {
+                               j->pld_scrw.bits.daafsyncen = 0;        /* Turn off DAA Frame Sync */
 
-                       outb_p(j->pld_scrw.byte, j->XILINXbase);
-                       j->pld_slicw.bits.rly1 = 0;
-                       j->pld_slicw.bits.rly2 = 0;
-                       j->pld_slicw.bits.rly3 = 0;
-                       outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-                       LED_SetState(0x0, j);
-                       release_region(j->XILINXbase, 8);
-               }
-               if (j->cardtype == QTI_PHONEJACK_LITE
-                   || j->cardtype == QTI_PHONEJACK_PCI) {
-                       release_region(j->XILINXbase, 4);
-               }
-               if (j->DSPbase) {
-                       release_region(j->DSPbase, 16);
+                               outb_p(j->pld_scrw.byte, j->XILINXbase);
+                               j->pld_slicw.bits.rly1 = 0;
+                               j->pld_slicw.bits.rly2 = 0;
+                               j->pld_slicw.bits.rly3 = 0;
+                               outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+                               LED_SetState(0x0, j);
+                               if (ixjdebug & 0x0002)
+                                       printk(KERN_INFO "IXJ: Releasing XILINX address for /dev/phone%d\n", cnt);
+                               release_region(j->XILINXbase, 8);
+                       } else if (j->cardtype == QTI_PHONEJACK_LITE || j->cardtype == QTI_PHONEJACK_PCI) {
+                               if (ixjdebug & 0x0002)
+                                       printk(KERN_INFO "IXJ: Releasing XILINX address for /dev/phone%d\n", cnt);
+                               release_region(j->XILINXbase, 4);
+                       }
+                       if (j->read_buffer)
+                               kfree(j->read_buffer);
+                       if (j->write_buffer)
+                               kfree(j->write_buffer);
+                       if (j->dev && j->dev->deactivate)
+                               j->dev->deactivate(j->dev);
+                       if (ixjdebug & 0x0002)
+                               printk(KERN_INFO "IXJ: Unregistering /dev/phone%d from LTAPI\n", cnt);
                        phone_unregister_device(&j->p);
-               }
-               if (j->read_buffer)
-                       kfree(j->read_buffer);
-               if (j->write_buffer)
-                       kfree(j->write_buffer);
-#ifdef CONFIG_ISAPNP
-               if (j->dev)
-                       j->dev->deactivate(j->dev);
-#endif
-#ifdef CONFIG_PCMCIA
-               DEBUG(0, "ixj_cs: unloading\n");
-               unregister_pcmcia_driver(&dev_info);
-               while (dev_list != NULL)
-                       ixj_detach(dev_list);
+                       if (ixjdebug & 0x0002)
+                               printk(KERN_INFO "IXJ: Releasing DSP address for /dev/phone%d\n", cnt);
+                       release_region(j->DSPbase, 16);
+#ifdef IXJ_DYN_ALLOC
+                       if (ixjdebug & 0x0002)
+                               printk(KERN_INFO "IXJ: Freeing memory for /dev/phone%d\n", cnt);
+                       kfree(j);
+                       ixj[cnt] = NULL;
 #endif
-
-               kfree(j);
-               ixj[cnt] = NULL;
+               }
        }
+       if (ixjdebug & 0x0002)
+               printk(KERN_INFO "IXJ: Removing /proc/ixj\n");
        remove_proc_entry ("ixj", NULL);
-       remove_proc_entry ("ixjfsk", NULL);
 }
 
-// Typedefs
+/* Typedefs */
 typedef struct {
        BYTE length;
        DWORD bits;
 } DATABLOCK;
+
 static void PCIEE_WriteBit(WORD wEEPROMAddress, BYTE lastLCC, BYTE byData)
 {
        lastLCC = lastLCC & 0xfb;
        lastLCC = lastLCC | (byData ? 4 : 0);
-       outb(lastLCC, wEEPROMAddress);  //set data out bit as appropriate
+       outb(lastLCC, wEEPROMAddress);  /*set data out bit as appropriate */
 
-       udelay(1000);
+       mdelay(1);
        lastLCC = lastLCC | 0x01;
-       outb(lastLCC, wEEPROMAddress);  //SK rising edge
+       outb(lastLCC, wEEPROMAddress);  /*SK rising edge */
 
        byData = byData << 1;
        lastLCC = lastLCC & 0xfe;
-       udelay(1000);
-       outb(lastLCC, wEEPROMAddress);  //after delay, SK falling edge
+       mdelay(1);
+       outb(lastLCC, wEEPROMAddress);  /*after delay, SK falling edge */
 
 }
 
 static BYTE PCIEE_ReadBit(WORD wEEPROMAddress, BYTE lastLCC)
 {
-       udelay(1000);
+       mdelay(1);
        lastLCC = lastLCC | 0x01;
-       outb(lastLCC, wEEPROMAddress);  //SK rising edge
+       outb(lastLCC, wEEPROMAddress);  /*SK rising edge */
 
        lastLCC = lastLCC & 0xfe;
-       udelay(1000);
-       outb(lastLCC, wEEPROMAddress);  //after delay, SK falling edge
+       mdelay(1);
+       outb(lastLCC, wEEPROMAddress);  /*after delay, SK falling edge */
 
        return ((inb(wEEPROMAddress) >> 3) & 1);
 }
@@ -6240,9 +7638,9 @@ static BOOL PCIEE_ReadWord(WORD wAddress, WORD wLoc, WORD * pwResult)
        lastLCC = inb(wEEPROMAddress);
        lastLCC = lastLCC | 0x02;
        lastLCC = lastLCC & 0xfe;
-       outb(lastLCC, wEEPROMAddress);  // CS hi, SK lo
+       outb(lastLCC, wEEPROMAddress);  /* CS hi, SK lo */
 
-       udelay(1000);           // delay
+       mdelay(1);              /* delay */
 
        PCIEE_WriteBit(wEEPROMAddress, lastLCC, 1);
        PCIEE_WriteBit(wEEPROMAddress, lastLCC, 1);
@@ -6257,10 +7655,10 @@ static BOOL PCIEE_ReadWord(WORD wAddress, WORD wLoc, WORD * pwResult)
                *pwResult = (*pwResult << 1) | byResult;
        }
 
-       udelay(1000);           // another delay
+       mdelay(1);              /* another delay */
 
        lastLCC = lastLCC & 0xfd;
-       outb(lastLCC, wEEPROMAddress);  // negate CS
+       outb(lastLCC, wEEPROMAddress);  /* negate CS */
 
        return 0;
 }
@@ -6275,51 +7673,31 @@ static DWORD PCIEE_GetSerialNumber(WORD wAddress)
        return (((DWORD) wHi << 16) | wLo);
 }
 
-#ifndef CONFIG_ISAPNP
-static int dspio[IXJMAX + 1];
-static int xio[IXJMAX + 1];
+static int dspio[IXJMAX + 1] =
+{
+       0,
+};
+static int xio[IXJMAX + 1] =
+{
+       0,
+};
 
 MODULE_PARM(dspio, "1-" __MODULE_STRING(IXJMAX) "i");
 MODULE_PARM(xio, "1-" __MODULE_STRING(IXJMAX) "i");
-#endif
+MODULE_DESCRIPTION("Quicknet VoIP Telephony card module - www.quicknet.net");
+MODULE_AUTHOR("Ed Okerson <eokerson@quicknet.net>");
+MODULE_LICENSE("GPL");
 
 void ixj_exit(void)
 {
-       cleanup();
-}
-
-#if defined(CONFIG_PCMCIA)
-int __init ixj_register_pcmcia(void)
-{
-       servinfo_t serv;
-
-       DEBUG(0, "%s\n", version);
-       CardServices(GetCardServicesInfo, &serv);
-       if (serv.Revision != CS_RELEASE_CODE) {
-               printk(KERN_NOTICE "ixj_cs: Card Services release does not match!\n");
-               return -EINVAL;
-       }
-       register_pcmcia_driver(&dev_info, &ixj_attach, &ixj_detach);
-       return 0;
-}
-#else
-extern __inline__ int ixj_register_pcmcia(void)
-{
-       return 0;
-}
-#endif /* CONFIG_PCMCIA */
-
-#if defined(CONFIG_ISAPNP)
-extern __inline__ int ixj_probe_isa(int *cnt)
-{
-       return 0;
+        cleanup();
 }
 
 int __init ixj_probe_isapnp(int *cnt)
-{
+{               
        int probe = 0;
        int func = 0x110;
-       struct pci_dev *dev = NULL, *old_dev = NULL;
+        struct pci_dev *dev = NULL, *old_dev = NULL;
 
        while (1) {
                do {
@@ -6328,7 +7706,7 @@ int __init ixj_probe_isapnp(int *cnt)
 
                        old_dev = dev;
                        dev = isapnp_find_dev(NULL, ISAPNP_VENDOR('Q', 'T', 'I'),
-                                             ISAPNP_FUNCTION(func), old_dev);
+                                        ISAPNP_FUNCTION(func), old_dev);
                        if (!dev)
                                break;
                        result = dev->prepare(dev);
@@ -6348,28 +7726,17 @@ int __init ixj_probe_isapnp(int *cnt)
                                return -ENOMEM;
                        }
 
-                       /* DSP base */
-                       if ((result = check_region(dev->resource[0].start, 16)) < 0) {
-                               printk(KERN_INFO "ixj: can't get I/O address 0x%lx\n",
-                                      dev->resource[0].start);
-                               cleanup();
-                               return result;
-                       }
-
-                       if ((j = kmalloc(sizeof(*j), GFP_KERNEL)) == NULL) {
-                               cleanup();
-                               return -ENOMEM;
+                       result = check_region(dev->resource[0].start, 16);
+                       if (result) {
+                               printk(KERN_INFO "ixj: can't get I/O address 0x%lx\n", dev->resource[0].start);
+                               break;
                        }
 
-                       ixj[*cnt] = j;
-
-                       j->DSPbase = dev->resource[0].start;
-
-                       /* XXX is this racy? */
+                       j = ixj_alloc();
                        request_region(j->DSPbase, 16, "ixj DSP");
 
                        if (func != 0x110)
-                               j->XILINXbase = dev->resource[1].start;
+                               j->XILINXbase = dev->resource[1].start; /* get real port */
 
                        switch (func) {
                        case (0x110):
@@ -6382,23 +7749,22 @@ int __init ixj_probe_isapnp(int *cnt)
                                j->cardtype = QTI_PHONEJACK_LITE;
                                break;
                        }
-                       probe = ixj_selfprobe(j, *cnt);
-                       
-                       j->serial = dev->bus->serial;
-                       j->dev = dev;
-                       switch (func) {
-                       case 0x110:
-                               printk(KERN_INFO "ixj: found Internet PhoneJACK at 0x%x\n",
-                                      j->DSPbase);
-                               break;
-                       case 0x310:
-                               printk(KERN_INFO "ixj: found Internet LineJACK at 0x%x\n",
-                                      j->DSPbase);
-                               break;
-                       case 0x410:
-                               printk(KERN_INFO "ixj: found Internet PhoneJACK Lite at 0x%x\n",
-                                      j->DSPbase);
-                               break;
+                       j->board = *cnt;
+                       probe = ixj_selfprobe(j);
+                       if(!probe) {
+                               j->serial = dev->bus->serial;
+                               j->dev = dev;
+                               switch (func) {
+                               case 0x110:
+                                       printk(KERN_INFO "ixj: found Internet PhoneJACK at 0x%x\n", j->DSPbase);
+                                       break;
+                               case 0x310:
+                                       printk(KERN_INFO "ixj: found Internet LineJACK at 0x%x\n", j->DSPbase);
+                                       break;
+                               case 0x410:
+                                       printk(KERN_INFO "ixj: found Internet PhoneJACK Lite at 0x%x\n", j->DSPbase);
+                                       break;
+                               }
                        }
                        ++*cnt;
                } while (dev);
@@ -6410,15 +7776,9 @@ int __init ixj_probe_isapnp(int *cnt)
                        func = 0x310;
                dev = NULL;
        }
-
        return probe;
 }
-#else
-extern __inline__ int ixj_probe_isapnp(int *cnt)
-{
-       return 0;
-}
-
+                        
 int __init ixj_probe_isa(int *cnt)
 {
        int i, result, probe;
@@ -6428,17 +7788,12 @@ int __init ixj_probe_isa(int *cnt)
                if (dspio[i]) {
                        IXJ *j;
 
-                       if ((result = check_region(dspio[i], 16)) < 0) {
-                               printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", dspio[i]);
-                               cleanup();
-                               return result;
+                       if ((result = check_region(ixj[*cnt].DSPbase, 16)) < 0) {
+                               printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", ixj[*cnt].DSPbase);
+                               break;
                        }
 
-                       if ((j = kmalloc(sizeof(*j), GFP_KERNEL)) == NULL) {
-                               cleanup();
-                               return -ENOMEM;
-                       }
-                       ixj[*cnt] = j;
+                       j = ixj_alloc();
 
                        j->DSPbase = dspio[i];
                        request_region(j->DSPbase, 16, "ixj DSP");
@@ -6446,78 +7801,64 @@ int __init ixj_probe_isa(int *cnt)
                        j->XILINXbase = xio[i];
                        j->cardtype = 0;
 
-                       probe = ixj_selfprobe(j, *cnt);
+                       j->board = *cnt;
+                       probe = ixj_selfprobe(j);
                        j->dev = NULL;
-
                        ++*cnt;
                }
        }
-
        return 0;
 }
-#endif /* CONFIG_ISAPNP */
 
-#if defined(CONFIG_PCI)
 int __init ixj_probe_pci(int *cnt)
 {
-       struct pci_dev *pci = NULL;
+       struct pci_dev *pci = NULL;   
        int i, probe = 0;
+       IXJ *j = NULL;
+       int result;
+
+       if(!pci_present())
+               return 0;
 
        for (i = 0; i < IXJMAX - *cnt; i++) {
                pci = pci_find_device(0x15E2, 0x0500, pci);
                if (!pci)
                        break;
+
                if (pci_enable_device(pci))
                        break;
-               {
-                       IXJ *j;
-                       int result;
-
-                       if ((result = check_region(pci_resource_start(pci, 0), 16)) < 0) {
-                               printk(KERN_INFO "ixj: can't get I/O address 0x%lx\n",
-                                      pci_resource_start(pci, 0));
-                               cleanup();
-                               return result;
-                       }
-
-                       if ((j = kmalloc(sizeof(*j), GFP_KERNEL)) == NULL) {
-                               cleanup();
-                               return -ENOMEM;
-                       }
-                       ixj[*cnt] = j;
-
-                       j->DSPbase = pci_resource_start(pci, 0);
-                       request_region(j->DSPbase, 16, "ixj DSP");
-
-                       j->XILINXbase = j->DSPbase + 0x10;
-                       j->serial = (PCIEE_GetSerialNumber)pci_resource_start(pci, 2);
-                       j->cardtype = QTI_PHONEJACK_PCI;
-
-                       probe = ixj_selfprobe(j, *cnt);
-                       if (probe)
-                               printk(KERN_INFO "ixj: found Internet PhoneJACK PCI at 0x%x\n", j->DSPbase);
-                       ++*cnt;
+               if ((result = check_region(pci_resource_start(pci, 0), 16)) < 0) {
+                       printk(KERN_INFO "ixj: can't get I/O address\n");
+                       break;
                }
-       }
 
+               /* Grab a device slot */        
+               j = ixj_alloc();
+               if(j == NULL)
+                       break;
+       
+               j->DSPbase = pci_resource_start(pci, 0);
+               j->serial = (PCIEE_GetSerialNumber)pci_resource_start(pci, 2);
+               j->XILINXbase = j->DSPbase + 0x10;
+               request_region(j->DSPbase, 16, "ixj DSP");
+               j->cardtype = QTI_PHONEJACK_PCI;
+               j->board = *cnt;
+               probe = ixj_selfprobe(j);
+               if (!probe)
+                       printk(KERN_INFO "ixj: found Internet PhoneJACK PCI at 0x%x\n", j->DSPbase);
+               ++*cnt;
+       }
        return probe;
 }
-#else
-extern __inline__ int ixj_probe_pci(int *cnt)
-{
-       return 0;
-}
-#endif /* CONFIG_PCI */
 
 int __init ixj_init(void)
 {
        int cnt = 0;
-       int probe = 0;
+       int probe = 0;   
+
+       cnt = 0;
 
        /* These might be no-ops, see above. */
-       if ((probe = ixj_register_pcmcia()) < 0) {
-               return probe;
-       }
        if ((probe = ixj_probe_isapnp(&cnt)) < 0) {
                return probe;
        }
@@ -6528,16 +7869,9 @@ int __init ixj_init(void)
                if ((probe = ixj_probe_pci(&cnt)) < 0) {
                        return probe;
                }
-       }
-
+       }
        printk("%s\n", ixj_c_rcsid);
-
        create_proc_read_entry ("ixj", 0, NULL, ixj_read_proc, NULL);
-       create_proc_read_entry ("ixjfsk", 0, NULL, ixj_read_proc_fsk, NULL);
-
-       ixj_init_timer();
-       ixj_add_timer();
-
        return probe;
 }
 
@@ -6549,112 +7883,138 @@ static void DAA_Coeff_US(IXJ *j)
        int i;
 
        j->daa_country = DAA_US;
-       //-----------------------------------------------
-       // CAO
+       /*----------------------------------------------- */
+       /* CAO */
        for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
                j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
        }
 
-// Bytes for IM-filter part 1 (04): 0E,32,E2,2F,C2,5A,C0,00
-       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x0E;
-       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0x32;
-       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xE2;
-       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x2F;
-       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xC2;
-       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x5A;
-       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xC0;
+/* Bytes for IM-filter part 1 (04): 0E,32,E2,2F,C2,5A,C0,00 */
+       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x03;
+       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0x4B;
+       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0x5D;
+       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0xCD;
+       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0x24;
+       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xC5;
+       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-// Bytes for IM-filter part 2 (05): 72,85,00,0E,2B,3A,D0,08
-       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x72;
-       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x85;
+/* Bytes for IM-filter part 2 (05): 72,85,00,0E,2B,3A,D0,08 */
+       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x71;
+       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x1A;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
-       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0E;
-       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0x2B;
-       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x3A;
-       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xD0;
+       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0A;
+       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0xB5;
+       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
+       j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-// Bytes for FRX-filter       (08): 03,8F,48,F2,8F,48,70,08
-       j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x03;
-       j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x8F;
-       j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x48;
-       j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0xF2;
-       j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x8F;
-       j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x48;
-       j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x70;
+/* Bytes for FRX-filter       (08): 03,8F,48,F2,8F,48,70,08 */
+       j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x05;
+       j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0xA3;
+       j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x72;
+       j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x34;
+       j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x3F;
+       j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x3B;
+       j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x30;
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-// Bytes for FRR-filter       (07): 04,8F,38,7F,9B,EA,B0,08
-       j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x04;
-       j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x8F;
-       j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0x38;
-       j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x7F;
-       j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x9B;
-       j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xEA;
+/* Bytes for FRR-filter       (07): 04,8F,38,7F,9B,EA,B0,08 */
+       j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x05;
+       j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x87;
+       j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xF9;
+       j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x3E;
+       j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x32;
+       j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xDA;
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xB0;
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-// Bytes for AX-filter        (0A): 16,55,DD,CA
-       j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x16;
-       j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0x55;
+/* Bytes for AX-filter        (0A): 16,55,DD,CA */
+       j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x41;
+       j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xB5;
        j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
        j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-// Bytes for AR-filter        (09): 52,D3,11,42
-       j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x52;
-       j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xD3;
-       j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x11;
-       j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0x42;
-// Bytes for TH-filter part 1 (00): 00,42,48,81,B3,80,00,98
+/* Bytes for AR-filter        (09): 52,D3,11,42 */
+       j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x25;
+       j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xC7;
+       j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
+       j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
+/* Bytes for TH-filter part 1 (00): 00,42,48,81,B3,80,00,98 */
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81;
-       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xB3;
+       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xA5;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-// Bytes for TH-filter part 2 (01): 02,F2,33,A0,68,AB,8A,AD
+/* Bytes for TH-filter part 2 (01): 02,F2,33,A0,68,AB,8A,AD */
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
-       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xF2;
-       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x33;
-       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0xA0;
-       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x68;
+       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xA2;
+       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x2B;
+       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0xB0;
+       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0xE8;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0xAB;
-       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x8A;
-       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xAD;
-// Bytes for TH-filter part 3 (02): 00,88,DA,54,A4,BA,2D,BB
+       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x81;
+       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xCC;
+/* Bytes for TH-filter part 3 (02): 00,88,DA,54,A4,BA,2D,BB */
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
-       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xDA;
-       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x54;
-       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0xA4;
-       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xBA;
-       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x2D;
-       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xBB;
-// ;  (10K, 0.68uF)
-       /
-       // Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23
+       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xD2;
+       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x24;
+       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0xBA;
+       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xA9;
+       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x3B;
+       j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xA6;
+/* ;  (10K, 0.68uF) */
+       /*  */
+       /* Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23 */
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
-       j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3B;
-       j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x9B;
-       j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0xBA;
-       j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0xD4;
-       j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x1C;
-       j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xB3;
+       j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
+       j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
+       j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A;
+       j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22;
+       j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
+       j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-// Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5
-       j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x13;
-       j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0x42;
+       /* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */
+       j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
+       j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA;
-       j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0xD4;
-       j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x73;
-       j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0xCA;
+       j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22;
+       j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
+       j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-// 
-       // Levelmetering Ringing        (0D):B2,45,0F,8E      
-       j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xB2;
-       j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
+
+       /* Levelmetering Ringing        (0D):B2,45,0F,8E       */
+       j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA;
+       j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35;
        j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
        j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
-// Caller ID 1st Tone           (0E):CA,0E,CA,09,99,99,99,99
+
+       /* Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23 */
+/*     j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1C; */
+/*     j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0xB3; */
+/*     j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0xAB; */
+/*     j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0xAB; */
+/*     j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x54; */
+/*     j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x2D; */
+/*     j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0x62; */
+/*     j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x2D; */
+       /* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */ 
+/*     j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x2D; */
+/*     j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0x62; */
+/*     j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; */
+/*     j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBB; */
+/*     j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x2A; */
+/*     j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7D; */
+/*     j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A; */
+/*     j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD4; */
+/* */
+       /* Levelmetering Ringing        (0D):B2,45,0F,8E       */
+/*     j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA; */
+/*     j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x05; */
+/*     j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F; */
+/*     j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E; */
+
+       /* Caller ID 1st Tone           (0E):CA,0E,CA,09,99,99,99,99 */
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
@@ -6663,7 +8023,7 @@ static void DAA_Coeff_US(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-// Caller ID 2nd Tone           (0F):FD,B5,BA,07,DA,00,00,00
+/* Caller ID 2nd Tone           (0F):FD,B5,BA,07,DA,00,00,00 */
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
@@ -6672,56 +8032,56 @@ static void DAA_Coeff_US(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-/
-       // ;CR Registers
-       // Config. Reg. 0 (filters)       (cr0):FE ; CLK gen. by crystal
+/*  */
+       /* ;CR Registers */
+       /* Config. Reg. 0 (filters)       (cr0):FE ; CLK gen. by crystal */
        j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
-// Config. Reg. 1 (dialing)       (cr1):05
+/* Config. Reg. 1 (dialing)       (cr1):05 */
        j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-// Config. Reg. 2 (caller ID)     (cr2):04
+/* Config. Reg. 2 (caller ID)     (cr2):04 */
        j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-// Config. Reg. 3 (testloops)     (cr3):03 ; SEL Bit==0, HP-disabled
-       j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x03;
-// Config. Reg. 4 (analog gain)   (cr4):01
-       j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;         //0x01;
-       // Config. Reg. 5 (Version)       (cr5):02
-       // Config. Reg. 6 (Reserved)      (cr6):00
-       // Config. Reg. 7 (Reserved)      (cr7):00
-       /
-       // ;xr Registers
-       // Ext. Reg. 0 (Interrupt Reg.)   (xr0):02
-
-       j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;        // SO_1 set to '1' because it is inverted.
-       // Ext. Reg. 1 (Interrupt enable) (xr1):1C // Cadence, RING, Caller ID, VDD_OK
+/* Config. Reg. 3 (testloops)     (cr3):03 ; SEL Bit==0, HP-disabled */
+       j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
+/* Config. Reg. 4 (analog gain)   (cr4):02 */
+       j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
+       /* Config. Reg. 5 (Version)       (cr5):02 */
+       /* Config. Reg. 6 (Reserved)      (cr6):00 */
+       /* Config. Reg. 7 (Reserved)      (cr7):00 */
+       /*  */
+       /* ;xr Registers */
+       /* Ext. Reg. 0 (Interrupt Reg.)   (xr0):02 */
+
+       j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;        /* SO_1 set to '1' because it is inverted. */
+       /* Ext. Reg. 1 (Interrupt enable) (xr1):3C Cadence, RING, Caller ID, VDD_OK */
 
        j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x3C;
-// Ext. Reg. 2 (Cadence Time Out) (xr2):7D
+/* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */
        j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-// Ext. Reg. 3 (DC Char)          (xr3):32 ; B-Filter Off == 1
-       j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x12;         //0x32;
-       // Ext. Reg. 4 (Cadence)          (xr4):00
+/* Ext. Reg. 3 (DC Char)          (xr3):32 ; B-Filter Off == 1 */
+       j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x3B;         /*0x32; */
+       /* Ext. Reg. 4 (Cadence)          (xr4):00 */
 
        j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-// Ext. Reg. 5 (Ring timer)       (xr5):22
+/* Ext. Reg. 5 (Ring timer)       (xr5):22 */
        j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-// Ext. Reg. 6 (Power State)      (xr6):00
+/* Ext. Reg. 6 (Power State)      (xr6):00 */
        j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-// Ext. Reg. 7 (Vdd)              (xr7):40
-       j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40;         // 0x40 ??? Should it be 0x00?
-       /
-       // DTMF Tone 1                     (0B): 11,B3,5A,2C ;   697 Hz  
-       //                                       12,33,5A,C3 ;  770 Hz  
-       //                                       13,3C,5B,32 ;  852 Hz  
-       //                                       1D,1B,5C,CC ;  941 Hz  
+/* Ext. Reg. 7 (Vdd)              (xr7):40 */
+       j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40;         /* 0x40 ??? Should it be 0x00? */
+       /*  */
+       /* DTMF Tone 1                     (0B): 11,B3,5A,2C ;   697 Hz   */
+       /*                                       12,33,5A,C3 ;  770 Hz   */
+       /*                                       13,3C,5B,32 ;  852 Hz   */
+       /*                                       1D,1B,5C,CC ;  941 Hz   */
 
        j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-// DTMF Tone 2                     (0C): 32,32,52,B3 ;  1209 Hz  
-       //                                       EC,1D,52,22 ;  1336 Hz  
-       //                                       AA,AC,51,D2 ;  1477 Hz  
-       //                                       9B,3B,51,25 ;  1633 Hz  
+/* DTMF Tone 2                     (0C): 32,32,52,B3 ;  1209 Hz   */
+       /*                                       EC,1D,52,22 ;  1336 Hz   */
+       /*                                       AA,AC,51,D2 ;  1477 Hz   */
+       /*                                       9B,3B,51,25 ;  1633 Hz   */
        j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
@@ -6733,13 +8093,13 @@ static void DAA_Coeff_UK(IXJ *j)
        int i;
 
        j->daa_country = DAA_UK;
-       //-----------------------------------------------
-       // CAO
+       /*----------------------------------------------- */
+       /* CAO */
        for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
                j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
        }
 
-//  Bytes for IM-filter part 1 (04): 00,C2,BB,A8,CB,81,A0,00
+/*  Bytes for IM-filter part 1 (04): 00,C2,BB,A8,CB,81,A0,00 */
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xC2;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xBB;
@@ -6748,7 +8108,7 @@ static void DAA_Coeff_UK(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x81;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-// Bytes for IM-filter part 2 (05): 40,00,00,0A,A4,33,E0,08
+/* Bytes for IM-filter part 2 (05): 40,00,00,0A,A4,33,E0,08 */
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x40;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
@@ -6757,7 +8117,7 @@ static void DAA_Coeff_UK(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-// Bytes for FRX-filter       (08): 07,9B,ED,24,B2,A2,A0,08
+/* Bytes for FRX-filter       (08): 07,9B,ED,24,B2,A2,A0,08 */
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x9B;
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0xED;
@@ -6766,7 +8126,7 @@ static void DAA_Coeff_UK(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0xA2;
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xA0;
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-// Bytes for FRR-filter       (07): 0F,92,F2,B2,87,D2,30,08
+/* Bytes for FRR-filter       (07): 0F,92,F2,B2,87,D2,30,08 */
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x0F;
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x92;
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xF2;
@@ -6775,17 +8135,17 @@ static void DAA_Coeff_UK(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xD2;
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x30;
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-// Bytes for AX-filter        (0A): 1B,A5,DD,CA
+/* Bytes for AX-filter        (0A): 1B,A5,DD,CA */
        j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x1B;
        j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xA5;
        j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
        j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-// Bytes for AR-filter        (09): E2,27,10,D6
+/* Bytes for AR-filter        (09): E2,27,10,D6 */
        j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0xE2;
        j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x27;
        j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
        j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-// Bytes for TH-filter part 1 (00): 80,2D,38,8B,D0,00,00,98
+/* Bytes for TH-filter part 1 (00): 80,2D,38,8B,D0,00,00,98 */
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x2D;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x38;
@@ -6794,7 +8154,7 @@ static void DAA_Coeff_UK(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-// Bytes for TH-filter part 2 (01): 02,5A,53,F0,0B,5F,84,D4
+/* Bytes for TH-filter part 2 (01): 02,5A,53,F0,0B,5F,84,D4 */
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0x5A;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x53;
@@ -6803,7 +8163,7 @@ static void DAA_Coeff_UK(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x5F;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x84;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xD4;
-// Bytes for TH-filter part 3 (02): 00,88,6A,A4,8F,52,F5,32
+/* Bytes for TH-filter part 3 (02): 00,88,6A,A4,8F,52,F5,32 */
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0x6A;
@@ -6812,8 +8172,8 @@ static void DAA_Coeff_UK(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x52;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0xF5;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x32;
-// ; idle
-       // Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23
+/* ; idle */
+       /* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
@@ -6822,7 +8182,7 @@ static void DAA_Coeff_UK(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-// Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5
+/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
@@ -6831,12 +8191,12 @@ static void DAA_Coeff_UK(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-// Levelmetering Ringing           (0D):AA,35,0F,8E     ; 25Hz 30V less possible?
+/* Levelmetering Ringing           (0D):AA,35,0F,8E     ; 25Hz 30V less possible? */
        j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA;
        j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35;
        j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
        j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
-// Caller ID 1st Tone              (0E):CA,0E,CA,09,99,99,99,99
+/* Caller ID 1st Tone              (0E):CA,0E,CA,09,99,99,99,99 */
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
@@ -6845,7 +8205,7 @@ static void DAA_Coeff_UK(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-// Caller ID 2nd Tone              (0F):FD,B5,BA,07,DA,00,00,00
+/* Caller ID 2nd Tone              (0F):FD,B5,BA,07,DA,00,00,00 */
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
@@ -6854,53 +8214,53 @@ static void DAA_Coeff_UK(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-// ;CR Registers
-       // Config. Reg. 0 (filters)        (cr0):FF
-       j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFE;
-// Config. Reg. 1 (dialing)        (cr1):05
+/* ;CR Registers */
+       /* Config. Reg. 0 (filters)        (cr0):FF */
+       j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
+/* Config. Reg. 1 (dialing)        (cr1):05 */
        j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-// Config. Reg. 2 (caller ID)      (cr2):04
+/* Config. Reg. 2 (caller ID)      (cr2):04 */
        j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-// Config. Reg. 3 (testloops)      (cr3):00        ; 
+/* Config. Reg. 3 (testloops)      (cr3):00        ;  */
        j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-// Config. Reg. 4 (analog gain)    (cr4):01
-       j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;         //0x01;
-       // Config. Reg. 5 (Version)        (cr5):02
-       // Config. Reg. 6 (Reserved)       (cr6):00
-       // Config. Reg. 7 (Reserved)       (cr7):00
-       // ;xr Registers
-       // Ext. Reg. 0 (Interrupt Reg.)    (xr0):02
+/* Config. Reg. 4 (analog gain)    (cr4):02 */
+       j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
+       /* Config. Reg. 5 (Version)        (cr5):02 */
+       /* Config. Reg. 6 (Reserved)       (cr6):00 */
+       /* Config. Reg. 7 (Reserved)       (cr7):00 */
+       /* ;xr Registers */
+       /* Ext. Reg. 0 (Interrupt Reg.)    (xr0):02 */
 
-       j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;        // SO_1 set to '1' because it is inverted.
-       // Ext. Reg. 1 (Interrupt enable)  (xr1):1C
+       j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;        /* SO_1 set to '1' because it is inverted. */
+       /* Ext. Reg. 1 (Interrupt enable)  (xr1):1C */
 
-       j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;         // RING, Caller ID, VDD_OK
-       // Ext. Reg. 2 (Cadence Time Out)  (xr2):7D
+       j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;         /* RING, Caller ID, VDD_OK */
+       /* Ext. Reg. 2 (Cadence Time Out)  (xr2):7D */
 
        j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-// Ext. Reg. 3 (DC Char)           (xr3):36        ; 
+/* Ext. Reg. 3 (DC Char)           (xr3):36        ;  */
        j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x36;
-// Ext. Reg. 4 (Cadence)           (xr4):00
+/* Ext. Reg. 4 (Cadence)           (xr4):00 */
        j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-// Ext. Reg. 5 (Ring timer)        (xr5):22
+/* Ext. Reg. 5 (Ring timer)        (xr5):22 */
        j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-// Ext. Reg. 6 (Power State)       (xr6):00
+/* Ext. Reg. 6 (Power State)       (xr6):00 */
        j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-// Ext. Reg. 7 (Vdd)               (xr7):46
-       j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x46;         // 0x46 ??? Should it be 0x00?
-       // DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz  
-       //                                       12,33,5A,C3    ;  770 Hz  
-       //                                       13,3C,5B,32    ;  852 Hz  
-       //                                       1D,1B,5C,CC    ;  941 Hz  
+/* Ext. Reg. 7 (Vdd)               (xr7):46 */
+       j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x46;         /* 0x46 ??? Should it be 0x00? */
+       /* DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz   */
+       /*                                       12,33,5A,C3    ;  770 Hz   */
+       /*                                       13,3C,5B,32    ;  852 Hz   */
+       /*                                       1D,1B,5C,CC    ;  941 Hz   */
 
        j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-// DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz  
-       //                                       EC,1D,52,22    ;  1336 Hz  
-       //                                       AA,AC,51,D2    ;  1477 Hz  
-       //                                       9B,3B,51,25    ;  1633 Hz  
+/* DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz   */
+       /*                                       EC,1D,52,22    ;  1336 Hz   */
+       /*                                       AA,AC,51,D2    ;  1477 Hz   */
+       /*                                       9B,3B,51,25    ;  1633 Hz   */
        j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
@@ -6913,13 +8273,13 @@ static void DAA_Coeff_France(IXJ *j)
        int i;
 
        j->daa_country = DAA_FRANCE;
-       //-----------------------------------------------
-       // CAO
+       /*----------------------------------------------- */
+       /* CAO */
        for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
                j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
        }
 
-// Bytes for IM-filter part 1 (04): 02,A2,43,2C,22,AF,A0,00
+/* Bytes for IM-filter part 1 (04): 02,A2,43,2C,22,AF,A0,00 */
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x02;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xA2;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0x43;
@@ -6928,7 +8288,7 @@ static void DAA_Coeff_France(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xAF;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-// Bytes for IM-filter part 2 (05): 67,CE,00,0C,22,33,E0,08
+/* Bytes for IM-filter part 2 (05): 67,CE,00,0C,22,33,E0,08 */
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x67;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0xCE;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
@@ -6937,7 +8297,7 @@ static void DAA_Coeff_France(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-// Bytes for FRX-filter       (08): 07,9A,28,F6,23,4A,B0,08
+/* Bytes for FRX-filter       (08): 07,9A,28,F6,23,4A,B0,08 */
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x9A;
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x28;
@@ -6946,7 +8306,7 @@ static void DAA_Coeff_France(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x4A;
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xB0;
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-// Bytes for FRR-filter       (07): 03,8F,F9,2F,9E,FA,20,08
+/* Bytes for FRR-filter       (07): 03,8F,F9,2F,9E,FA,20,08 */
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x03;
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x8F;
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xF9;
@@ -6955,17 +8315,17 @@ static void DAA_Coeff_France(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xFA;
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x20;
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-// Bytes for AX-filter        (0A): 16,B5,DD,CA
+/* Bytes for AX-filter        (0A): 16,B5,DD,CA */
        j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x16;
        j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xB5;
        j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
        j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-// Bytes for AR-filter        (09): 52,C7,10,D6
+/* Bytes for AR-filter        (09): 52,C7,10,D6 */
        j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0xE2;
        j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xC7;
        j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
        j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-// Bytes for TH-filter part 1 (00): 00,42,48,81,A6,80,00,98
+/* Bytes for TH-filter part 1 (00): 00,42,48,81,A6,80,00,98 */
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
@@ -6974,7 +8334,7 @@ static void DAA_Coeff_France(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-// Bytes for TH-filter part 2 (01): 02,AC,2A,30,78,AC,8A,2C
+/* Bytes for TH-filter part 2 (01): 02,AC,2A,30,78,AC,8A,2C */
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xAC;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x2A;
@@ -6983,7 +8343,7 @@ static void DAA_Coeff_France(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0xAC;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x8A;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x2C;
-// Bytes for TH-filter part 3 (02): 00,88,DA,A5,22,BA,2C,45
+/* Bytes for TH-filter part 3 (02): 00,88,DA,A5,22,BA,2C,45 */
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xDA;
@@ -6992,8 +8352,8 @@ static void DAA_Coeff_France(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xBA;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x2C;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x45;
-// ; idle
-       // Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23
+/* ; idle */
+       /* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
@@ -7002,7 +8362,7 @@ static void DAA_Coeff_France(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-// Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5
+/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
@@ -7011,12 +8371,12 @@ static void DAA_Coeff_France(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-// Levelmetering Ringing           (0D):32,45,B5,84     ; 50Hz 20V
+/* Levelmetering Ringing           (0D):32,45,B5,84     ; 50Hz 20V */
        j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0x32;
        j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
        j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0xB5;
        j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x84;
-// Caller ID 1st Tone              (0E):CA,0E,CA,09,99,99,99,99
+/* Caller ID 1st Tone              (0E):CA,0E,CA,09,99,99,99,99 */
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
@@ -7025,7 +8385,7 @@ static void DAA_Coeff_France(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-// Caller ID 2nd Tone              (0F):FD,B5,BA,07,DA,00,00,00
+/* Caller ID 2nd Tone              (0F):FD,B5,BA,07,DA,00,00,00 */
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
@@ -7034,53 +8394,53 @@ static void DAA_Coeff_France(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-// ;CR Registers
-       // Config. Reg. 0 (filters)        (cr0):FF
-       j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFE;
-// Config. Reg. 1 (dialing)        (cr1):05
+/* ;CR Registers */
+       /* Config. Reg. 0 (filters)        (cr0):FF */
+       j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
+/* Config. Reg. 1 (dialing)        (cr1):05 */
        j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-// Config. Reg. 2 (caller ID)      (cr2):04
+/* Config. Reg. 2 (caller ID)      (cr2):04 */
        j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-// Config. Reg. 3 (testloops)      (cr3):00        ; 
+/* Config. Reg. 3 (testloops)      (cr3):00        ;  */
        j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-// Config. Reg. 4 (analog gain)    (cr4):01
-       j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;         //0x01;
-       // Config. Reg. 5 (Version)        (cr5):02
-       // Config. Reg. 6 (Reserved)       (cr6):00
-       // Config. Reg. 7 (Reserved)       (cr7):00
-       // ;xr Registers
-       // Ext. Reg. 0 (Interrupt Reg.)    (xr0):02
+/* Config. Reg. 4 (analog gain)    (cr4):02 */
+       j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
+       /* Config. Reg. 5 (Version)        (cr5):02 */
+       /* Config. Reg. 6 (Reserved)       (cr6):00 */
+       /* Config. Reg. 7 (Reserved)       (cr7):00 */
+       /* ;xr Registers */
+       /* Ext. Reg. 0 (Interrupt Reg.)    (xr0):02 */
 
-       j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;        // SO_1 set to '1' because it is inverted.
-       // Ext. Reg. 1 (Interrupt enable)  (xr1):1C
+       j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;        /* SO_1 set to '1' because it is inverted. */
+       /* Ext. Reg. 1 (Interrupt enable)  (xr1):1C */
 
-       j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;         // RING, Caller ID, VDD_OK
-       // Ext. Reg. 2 (Cadence Time Out)  (xr2):7D
+       j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;         /* RING, Caller ID, VDD_OK */
+       /* Ext. Reg. 2 (Cadence Time Out)  (xr2):7D */
 
        j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-// Ext. Reg. 3 (DC Char)           (xr3):36        ; 
+/* Ext. Reg. 3 (DC Char)           (xr3):36        ;  */
        j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x36;
-// Ext. Reg. 4 (Cadence)           (xr4):00
+/* Ext. Reg. 4 (Cadence)           (xr4):00 */
        j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-// Ext. Reg. 5 (Ring timer)        (xr5):22
+/* Ext. Reg. 5 (Ring timer)        (xr5):22 */
        j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-// Ext. Reg. 6 (Power State)       (xr6):00
+/* Ext. Reg. 6 (Power State)       (xr6):00 */
        j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-// Ext. Reg. 7 (Vdd)               (xr7):46
-       j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x46;         // 0x46 ??? Should it be 0x00?
-       // DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz  
-       //                                       12,33,5A,C3    ;  770 Hz  
-       //                                       13,3C,5B,32    ;  852 Hz  
-       //                                       1D,1B,5C,CC    ;  941 Hz  
+/* Ext. Reg. 7 (Vdd)               (xr7):46 */
+       j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x46;         /* 0x46 ??? Should it be 0x00? */
+       /* DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz   */
+       /*                                       12,33,5A,C3    ;  770 Hz   */
+       /*                                       13,3C,5B,32    ;  852 Hz   */
+       /*                                       1D,1B,5C,CC    ;  941 Hz   */
 
        j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-// DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz  
-       //                                       EC,1D,52,22    ;  1336 Hz  
-       //                                       AA,AC,51,D2    ;  1477 Hz  
-       //                                       9B,3B,51,25    ;  1633 Hz  
+/* DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz   */
+       /*                                       EC,1D,52,22    ;  1336 Hz   */
+       /*                                       AA,AC,51,D2    ;  1477 Hz   */
+       /*                                       9B,3B,51,25    ;  1633 Hz   */
        j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
@@ -7093,13 +8453,13 @@ static void DAA_Coeff_Germany(IXJ *j)
        int i;
 
        j->daa_country = DAA_GERMANY;
-       //-----------------------------------------------
-       // CAO
+       /*----------------------------------------------- */
+       /* CAO */
        for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
                j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
        }
 
-// Bytes for IM-filter part 1 (04): 00,CE,BB,B8,D2,81,B0,00
+/* Bytes for IM-filter part 1 (04): 00,CE,BB,B8,D2,81,B0,00 */
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xCE;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xBB;
@@ -7108,7 +8468,7 @@ static void DAA_Coeff_Germany(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x81;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xB0;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-// Bytes for IM-filter part 2 (05): 45,8F,00,0C,D2,3A,D0,08
+/* Bytes for IM-filter part 2 (05): 45,8F,00,0C,D2,3A,D0,08 */
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x45;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x8F;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
@@ -7117,7 +8477,7 @@ static void DAA_Coeff_Germany(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x3A;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xD0;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-// Bytes for FRX-filter       (08): 07,AA,E2,34,24,89,20,08
+/* Bytes for FRX-filter       (08): 07,AA,E2,34,24,89,20,08 */
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0xAA;
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0xE2;
@@ -7126,7 +8486,7 @@ static void DAA_Coeff_Germany(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x89;
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x20;
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-// Bytes for FRR-filter       (07): 02,87,FA,37,9A,CA,B0,08
+/* Bytes for FRR-filter       (07): 02,87,FA,37,9A,CA,B0,08 */
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x02;
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x87;
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xFA;
@@ -7135,17 +8495,17 @@ static void DAA_Coeff_Germany(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xCA;
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xB0;
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-// Bytes for AX-filter        (0A): 72,D5,DD,CA
+/* Bytes for AX-filter        (0A): 72,D5,DD,CA */
        j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x72;
        j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xD5;
        j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
        j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-// Bytes for AR-filter        (09): 72,42,13,4B
+/* Bytes for AR-filter        (09): 72,42,13,4B */
        j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x72;
        j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x42;
        j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x13;
        j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0x4B;
-// Bytes for TH-filter part 1 (00): 80,52,48,81,AD,80,00,98
+/* Bytes for TH-filter part 1 (00): 80,52,48,81,AD,80,00,98 */
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x52;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
@@ -7154,7 +8514,7 @@ static void DAA_Coeff_Germany(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-// Bytes for TH-filter part 2 (01): 02,42,5A,20,E8,1A,81,27
+/* Bytes for TH-filter part 2 (01): 02,42,5A,20,E8,1A,81,27 */
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0x42;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x5A;
@@ -7163,7 +8523,7 @@ static void DAA_Coeff_Germany(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x1A;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x81;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x27;
-// Bytes for TH-filter part 3 (02): 00,88,63,26,BD,4B,A3,C2
+/* Bytes for TH-filter part 3 (02): 00,88,63,26,BD,4B,A3,C2 */
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0x63;
@@ -7172,8 +8532,8 @@ static void DAA_Coeff_Germany(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x4B;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0xA3;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xC2;
-// ;  (10K, 0.68uF)
-       // Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23
+/* ;  (10K, 0.68uF) */
+       /* Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23 */
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3B;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x9B;
@@ -7182,7 +8542,7 @@ static void DAA_Coeff_Germany(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x1C;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xB3;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-// Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5
+/* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x13;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0x42;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
@@ -7191,12 +8551,12 @@ static void DAA_Coeff_Germany(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x73;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0xCA;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-// Levelmetering Ringing        (0D):B2,45,0F,8E      
+/* Levelmetering Ringing        (0D):B2,45,0F,8E       */
        j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xB2;
        j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
        j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
        j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
-// Caller ID 1st Tone           (0E):CA,0E,CA,09,99,99,99,99
+/* Caller ID 1st Tone           (0E):CA,0E,CA,09,99,99,99,99 */
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
@@ -7205,7 +8565,7 @@ static void DAA_Coeff_Germany(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-// Caller ID 2nd Tone           (0F):FD,B5,BA,07,DA,00,00,00
+/* Caller ID 2nd Tone           (0F):FD,B5,BA,07,DA,00,00,00 */
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
@@ -7214,53 +8574,53 @@ static void DAA_Coeff_Germany(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-// ;CR Registers
-       // Config. Reg. 0 (filters)        (cr0):FF ; all Filters enabled, CLK from ext. source
-       j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFE;
-// Config. Reg. 1 (dialing)        (cr1):05 ; Manual Ring, Ring metering enabled
+/* ;CR Registers */
+       /* Config. Reg. 0 (filters)        (cr0):FF ; all Filters enabled, CLK from ext. source */
+       j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
+/* Config. Reg. 1 (dialing)        (cr1):05 ; Manual Ring, Ring metering enabled */
        j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-// Config. Reg. 2 (caller ID)      (cr2):04 ; Analog Gain 0dB, FSC internal
+/* Config. Reg. 2 (caller ID)      (cr2):04 ; Analog Gain 0dB, FSC internal */
        j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-// Config. Reg. 3 (testloops)      (cr3):00 ; SEL Bit==0, HP-enabled
+/* Config. Reg. 3 (testloops)      (cr3):00 ; SEL Bit==0, HP-enabled */
        j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-// Config. Reg. 4 (analog gain)    (cr4):01
-       j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;         //0x01;
-       // Config. Reg. 5 (Version)        (cr5):02
-       // Config. Reg. 6 (Reserved)       (cr6):00
-       // Config. Reg. 7 (Reserved)       (cr7):00
-       // ;xr Registers
-       // Ext. Reg. 0 (Interrupt Reg.)    (xr0):02
+/* Config. Reg. 4 (analog gain)    (cr4):02 */
+       j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
+       /* Config. Reg. 5 (Version)        (cr5):02 */
+       /* Config. Reg. 6 (Reserved)       (cr6):00 */
+       /* Config. Reg. 7 (Reserved)       (cr7):00 */
+       /* ;xr Registers */
+       /* Ext. Reg. 0 (Interrupt Reg.)    (xr0):02 */
 
-       j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;        // SO_1 set to '1' because it is inverted.
-       // Ext. Reg. 1 (Interrupt enable)  (xr1):1C ; Ring, CID, VDDOK Interrupts enabled
+       j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;        /* SO_1 set to '1' because it is inverted. */
+       /* Ext. Reg. 1 (Interrupt enable)  (xr1):1C ; Ring, CID, VDDOK Interrupts enabled */
 
-       j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;         // RING, Caller ID, VDD_OK
-       // Ext. Reg. 2 (Cadence Time Out)  (xr2):7D
+       j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;         /* RING, Caller ID, VDD_OK */
+       /* Ext. Reg. 2 (Cadence Time Out)  (xr2):7D */
 
        j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-// Ext. Reg. 3 (DC Char)           (xr3):32 ; B-Filter Off==1, U0=3.5V, R=200Ohm
+/* Ext. Reg. 3 (DC Char)           (xr3):32 ; B-Filter Off==1, U0=3.5V, R=200Ohm */
        j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x32;
-// Ext. Reg. 4 (Cadence)           (xr4):00
+/* Ext. Reg. 4 (Cadence)           (xr4):00 */
        j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-// Ext. Reg. 5 (Ring timer)        (xr5):22
+/* Ext. Reg. 5 (Ring timer)        (xr5):22 */
        j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-// Ext. Reg. 6 (Power State)       (xr6):00
+/* Ext. Reg. 6 (Power State)       (xr6):00 */
        j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-// Ext. Reg. 7 (Vdd)               (xr7):40 ; VDD=4.25 V
-       j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40;         // 0x40 ??? Should it be 0x00?
-       // DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz  
-       //                                       12,33,5A,C3    ;  770 Hz  
-       //                                       13,3C,5B,32    ;  852 Hz  
-       //                                       1D,1B,5C,CC    ;  941 Hz  
+/* Ext. Reg. 7 (Vdd)               (xr7):40 ; VDD=4.25 V */
+       j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40;         /* 0x40 ??? Should it be 0x00? */
+       /* DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz   */
+       /*                                       12,33,5A,C3    ;  770 Hz   */
+       /*                                       13,3C,5B,32    ;  852 Hz   */
+       /*                                       1D,1B,5C,CC    ;  941 Hz   */
 
        j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-// DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz  
-       //                                       EC,1D,52,22    ;  1336 Hz  
-       //                                       AA,AC,51,D2    ;  1477 Hz  
-       //                                       9B,3B,51,25    ;  1633 Hz  
+/* DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz   */
+       /*                                       EC,1D,52,22    ;  1336 Hz   */
+       /*                                       AA,AC,51,D2    ;  1477 Hz   */
+       /*                                       9B,3B,51,25    ;  1633 Hz   */
        j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
@@ -7273,13 +8633,13 @@ static void DAA_Coeff_Australia(IXJ *j)
        int i;
 
        j->daa_country = DAA_AUSTRALIA;
-       //-----------------------------------------------
-       // CAO
+       /*----------------------------------------------- */
+       /* CAO */
        for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
                j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
        }
 
-// Bytes for IM-filter part 1 (04): 00,A3,AA,28,B3,82,D0,00
+/* Bytes for IM-filter part 1 (04): 00,A3,AA,28,B3,82,D0,00 */
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xA3;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xAA;
@@ -7288,7 +8648,7 @@ static void DAA_Coeff_Australia(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x82;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xD0;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-// Bytes for IM-filter part 2 (05): 70,96,00,09,32,6B,C0,08
+/* Bytes for IM-filter part 2 (05): 70,96,00,09,32,6B,C0,08 */
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x70;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x96;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
@@ -7297,7 +8657,7 @@ static void DAA_Coeff_Australia(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x6B;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xC0;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-// Bytes for FRX-filter       (08): 07,96,E2,34,32,9B,30,08
+/* Bytes for FRX-filter       (08): 07,96,E2,34,32,9B,30,08 */
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x96;
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0xE2;
@@ -7306,7 +8666,7 @@ static void DAA_Coeff_Australia(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x9B;
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x30;
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-// Bytes for FRR-filter       (07): 0F,9A,E9,2F,22,CC,A0,08
+/* Bytes for FRR-filter       (07): 0F,9A,E9,2F,22,CC,A0,08 */
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x0F;
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x9A;
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xE9;
@@ -7315,17 +8675,17 @@ static void DAA_Coeff_Australia(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xCC;
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xA0;
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-// Bytes for AX-filter        (0A): CB,45,DD,CA
+/* Bytes for AX-filter        (0A): CB,45,DD,CA */
        j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0xCB;
        j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0x45;
        j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
        j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-// Bytes for AR-filter        (09): 1B,67,10,D6
+/* Bytes for AR-filter        (09): 1B,67,10,D6 */
        j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x1B;
        j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x67;
        j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
        j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-// Bytes for TH-filter part 1 (00): 80,52,48,81,AF,80,00,98
+/* Bytes for TH-filter part 1 (00): 80,52,48,81,AF,80,00,98 */
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x52;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
@@ -7334,7 +8694,7 @@ static void DAA_Coeff_Australia(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-// Bytes for TH-filter part 2 (01): 02,DB,52,B0,38,01,82,AC
+/* Bytes for TH-filter part 2 (01): 02,DB,52,B0,38,01,82,AC */
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xDB;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x52;
@@ -7343,7 +8703,7 @@ static void DAA_Coeff_Australia(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x01;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x82;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xAC;
-// Bytes for TH-filter part 3 (02): 00,88,4A,3E,2C,3B,24,46
+/* Bytes for TH-filter part 3 (02): 00,88,4A,3E,2C,3B,24,46 */
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0x4A;
@@ -7352,8 +8712,8 @@ static void DAA_Coeff_Australia(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x3B;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x24;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x46;
-// ;  idle
-       // Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23
+/* ;  idle */
+       /* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
@@ -7362,7 +8722,7 @@ static void DAA_Coeff_Australia(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-// Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5
+/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
@@ -7371,12 +8731,12 @@ static void DAA_Coeff_Australia(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-// Levelmetering Ringing           (0D):32,45,B5,84   ; 50Hz 20V
+/* Levelmetering Ringing           (0D):32,45,B5,84   ; 50Hz 20V */
        j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0x32;
        j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
        j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0xB5;
        j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x84;
-// Caller ID 1st Tone              (0E):CA,0E,CA,09,99,99,99,99
+/* Caller ID 1st Tone              (0E):CA,0E,CA,09,99,99,99,99 */
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
@@ -7385,7 +8745,7 @@ static void DAA_Coeff_Australia(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-// Caller ID 2nd Tone              (0F):FD,B5,BA,07,DA,00,00,00
+/* Caller ID 2nd Tone              (0F):FD,B5,BA,07,DA,00,00,00 */
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
@@ -7394,53 +8754,54 @@ static void DAA_Coeff_Australia(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-// ;CR Registers
-       // Config. Reg. 0 (filters)        (cr0):FF
+/* ;CR Registers */
+       /* Config. Reg. 0 (filters)        (cr0):FF */
        j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
-// Config. Reg. 1 (dialing)        (cr1):05
+/* Config. Reg. 1 (dialing)        (cr1):05 */
        j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-// Config. Reg. 2 (caller ID)      (cr2):04
+/* Config. Reg. 2 (caller ID)      (cr2):04 */
        j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-// Config. Reg. 3 (testloops)      (cr3):00        ; 
+/* Config. Reg. 3 (testloops)      (cr3):00        ;  */
        j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-// Config. Reg. 4 (analog gain)    (cr4):01
-       j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;         //0x01;
-       // Config. Reg. 5 (Version)        (cr5):02
-       // Config. Reg. 6 (Reserved)       (cr6):00
-       // Config. Reg. 7 (Reserved)       (cr7):00
-       // ;xr Registers
-       // Ext. Reg. 0 (Interrupt Reg.)    (xr0):02
+/* Config. Reg. 4 (analog gain)    (cr4):02 */
+       j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
+       /* Config. Reg. 5 (Version)        (cr5):02 */
+       /* Config. Reg. 6 (Reserved)       (cr6):00 */
+       /* Config. Reg. 7 (Reserved)       (cr7):00 */
+       /* ;xr Registers */
+       /* Ext. Reg. 0 (Interrupt Reg.)    (xr0):02 */
 
-       j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;        // SO_1 set to '1' because it is inverted.
-       // Ext. Reg. 1 (Interrupt enable)  (xr1):1C
+       j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;        /* SO_1 set to '1' because it is inverted. */
+       /* Ext. Reg. 1 (Interrupt enable)  (xr1):1C */
 
-       j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;         // RING, Caller ID, VDD_OK
-       // Ext. Reg. 2 (Cadence Time Out)  (xr2):7D
+       j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;         /* RING, Caller ID, VDD_OK */
+       /* Ext. Reg. 2 (Cadence Time Out)  (xr2):7D */
 
        j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-// Ext. Reg. 3 (DC Char)           (xr3):2B      ; 
+/* Ext. Reg. 3 (DC Char)           (xr3):2B      ;  */
        j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x2B;
-// Ext. Reg. 4 (Cadence)           (xr4):00
+/* Ext. Reg. 4 (Cadence)           (xr4):00 */
        j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-// Ext. Reg. 5 (Ring timer)        (xr5):22
+/* Ext. Reg. 5 (Ring timer)        (xr5):22 */
        j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-// Ext. Reg. 6 (Power State)       (xr6):00
+/* Ext. Reg. 6 (Power State)       (xr6):00 */
        j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-// Ext. Reg. 7 (Vdd)               (xr7):40
-       j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40;         // 0x40 ??? Should it be 0x00?
-       // DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz  
-       //                                       12,33,5A,C3    ;  770 Hz  
-       //                                       13,3C,5B,32    ;  852 Hz  
-       //                                       1D,1B,5C,CC    ;  941 Hz  
+/* Ext. Reg. 7 (Vdd)               (xr7):40 */
+       j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40;         /* 0x40 ??? Should it be 0x00? */
 
+       /* DTMF Tone 1                     (0B): 11,B3,5A,2C    ;  697 Hz   */
+       /*                                       12,33,5A,C3    ;  770 Hz   */
+       /*                                       13,3C,5B,32    ;  852 Hz   */
+       /*                                       1D,1B,5C,CC    ;  941 Hz   */
        j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-// DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz  
-       //                                       EC,1D,52,22    ;  1336 Hz  
-       //                                       AA,AC,51,D2    ;  1477 Hz  
-       //                                       9B,3B,51,25    ;  1633 Hz  
+
+       /* DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz   */
+       /*                                       EC,1D,52,22    ;  1336 Hz   */
+       /*                                       AA,AC,51,D2    ;  1477 Hz   */
+       /*                                       9B,3B,51,25    ;  1633 Hz   */
        j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
@@ -7452,13 +8813,13 @@ static void DAA_Coeff_Japan(IXJ *j)
        int i;
 
        j->daa_country = DAA_JAPAN;
-       //-----------------------------------------------
-       // CAO
+       /*----------------------------------------------- */
+       /* CAO */
        for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
                j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
        }
 
-// Bytes for IM-filter part 1 (04): 06,BD,E2,2D,BA,F9,A0,00
+/* Bytes for IM-filter part 1 (04): 06,BD,E2,2D,BA,F9,A0,00 */
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x06;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xBD;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xE2;
@@ -7467,7 +8828,7 @@ static void DAA_Coeff_Japan(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xF9;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-// Bytes for IM-filter part 2 (05): 6F,F7,00,0E,34,33,E0,08
+/* Bytes for IM-filter part 2 (05): 6F,F7,00,0E,34,33,E0,08 */
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x6F;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0xF7;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
@@ -7476,7 +8837,7 @@ static void DAA_Coeff_Japan(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
        j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-// Bytes for FRX-filter       (08): 02,8F,68,77,9C,58,F0,08
+/* Bytes for FRX-filter       (08): 02,8F,68,77,9C,58,F0,08 */
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x02;
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x8F;
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x68;
@@ -7485,7 +8846,7 @@ static void DAA_Coeff_Japan(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x58;
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xF0;
        j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-// Bytes for FRR-filter       (07): 03,8F,38,73,87,EA,20,08
+/* Bytes for FRR-filter       (07): 03,8F,38,73,87,EA,20,08 */
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x03;
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x8F;
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0x38;
@@ -7494,17 +8855,17 @@ static void DAA_Coeff_Japan(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xEA;
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x20;
        j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-// Bytes for AX-filter        (0A): 51,C5,DD,CA
+/* Bytes for AX-filter        (0A): 51,C5,DD,CA */
        j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x51;
        j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xC5;
        j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
        j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-// Bytes for AR-filter        (09): 25,A7,10,D6
+/* Bytes for AR-filter        (09): 25,A7,10,D6 */
        j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x25;
        j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xA7;
        j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
        j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-// Bytes for TH-filter part 1 (00): 00,42,48,81,AE,80,00,98
+/* Bytes for TH-filter part 1 (00): 00,42,48,81,AE,80,00,98 */
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
@@ -7513,7 +8874,7 @@ static void DAA_Coeff_Japan(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-// Bytes for TH-filter part 2 (01): 02,AB,2A,20,99,5B,89,28
+/* Bytes for TH-filter part 2 (01): 02,AB,2A,20,99,5B,89,28 */
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xAB;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x2A;
@@ -7522,7 +8883,7 @@ static void DAA_Coeff_Japan(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x5B;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x89;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x28;
-// Bytes for TH-filter part 3 (02): 00,88,DA,25,34,C5,4C,BA
+/* Bytes for TH-filter part 3 (02): 00,88,DA,25,34,C5,4C,BA */
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xDA;
@@ -7531,8 +8892,8 @@ static void DAA_Coeff_Japan(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xC5;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x4C;
        j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xBA;
-// ;  idle
-       // Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23
+/* ;  idle */
+       /* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
@@ -7541,7 +8902,7 @@ static void DAA_Coeff_Japan(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-// Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5
+/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
@@ -7550,12 +8911,12 @@ static void DAA_Coeff_Japan(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
        j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-// Levelmetering Ringing           (0D):AA,35,0F,8E    ; 25Hz 30V ?????????
+/* Levelmetering Ringing           (0D):AA,35,0F,8E    ; 25Hz 30V ????????? */
        j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA;
        j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35;
        j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
        j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
-// Caller ID 1st Tone              (0E):CA,0E,CA,09,99,99,99,99
+/* Caller ID 1st Tone              (0E):CA,0E,CA,09,99,99,99,99 */
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
@@ -7564,7 +8925,7 @@ static void DAA_Coeff_Japan(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-// Caller ID 2nd Tone              (0F):FD,B5,BA,07,DA,00,00,00
+/* Caller ID 2nd Tone              (0F):FD,B5,BA,07,DA,00,00,00 */
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
@@ -7573,53 +8934,53 @@ static void DAA_Coeff_Japan(IXJ *j)
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
        j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-// ;CR Registers
-       // Config. Reg. 0 (filters)        (cr0):FF
-       j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFE;
-// Config. Reg. 1 (dialing)        (cr1):05
+/* ;CR Registers */
+       /* Config. Reg. 0 (filters)        (cr0):FF */
+       j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
+/* Config. Reg. 1 (dialing)        (cr1):05 */
        j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-// Config. Reg. 2 (caller ID)      (cr2):04
+/* Config. Reg. 2 (caller ID)      (cr2):04 */
        j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-// Config. Reg. 3 (testloops)      (cr3):00        ; 
+/* Config. Reg. 3 (testloops)      (cr3):00        ;  */
        j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-// Config. Reg. 4 (analog gain)    (cr4):01
-       j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;         //0x01;
-       // Config. Reg. 5 (Version)        (cr5):02
-       // Config. Reg. 6 (Reserved)       (cr6):00
-       // Config. Reg. 7 (Reserved)       (cr7):00
-       // ;xr Registers
-       // Ext. Reg. 0 (Interrupt Reg.)    (xr0):02
+/* Config. Reg. 4 (analog gain)    (cr4):02 */
+       j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
+       /* Config. Reg. 5 (Version)        (cr5):02 */
+       /* Config. Reg. 6 (Reserved)       (cr6):00 */
+       /* Config. Reg. 7 (Reserved)       (cr7):00 */
+       /* ;xr Registers */
+       /* Ext. Reg. 0 (Interrupt Reg.)    (xr0):02 */
 
-       j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;        // SO_1 set to '1' because it is inverted.
-       // Ext. Reg. 1 (Interrupt enable)  (xr1):1C
+       j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;        /* SO_1 set to '1' because it is inverted. */
+       /* Ext. Reg. 1 (Interrupt enable)  (xr1):1C */
 
-       j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;         // RING, Caller ID, VDD_OK
-       // Ext. Reg. 2 (Cadence Time Out)  (xr2):7D
+       j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;         /* RING, Caller ID, VDD_OK */
+       /* Ext. Reg. 2 (Cadence Time Out)  (xr2):7D */
 
        j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-// Ext. Reg. 3 (DC Char)           (xr3):22        ; 
+/* Ext. Reg. 3 (DC Char)           (xr3):22        ;  */
        j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x22;
-// Ext. Reg. 4 (Cadence)           (xr4):00
+/* Ext. Reg. 4 (Cadence)           (xr4):00 */
        j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-// Ext. Reg. 5 (Ring timer)        (xr5):22
+/* Ext. Reg. 5 (Ring timer)        (xr5):22 */
        j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-// Ext. Reg. 6 (Power State)       (xr6):00
+/* Ext. Reg. 6 (Power State)       (xr6):00 */
        j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-// Ext. Reg. 7 (Vdd)               (xr7):40
-       j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40;         // 0x40 ??? Should it be 0x00?
-       // DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz  
-       //                                       12,33,5A,C3    ;  770 Hz  
-       //                                       13,3C,5B,32    ;  852 Hz  
-       //                                       1D,1B,5C,CC    ;  941 Hz  
+/* Ext. Reg. 7 (Vdd)               (xr7):40 */
+       j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40;         /* 0x40 ??? Should it be 0x00? */
+       /* DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz   */
+       /*                                       12,33,5A,C3    ;  770 Hz   */
+       /*                                       13,3C,5B,32    ;  852 Hz   */
+       /*                                       1D,1B,5C,CC    ;  941 Hz   */
 
        j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-// DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz  
-       //                                       EC,1D,52,22    ;  1336 Hz  
-       //                                       AA,AC,51,D2    ;  1477 Hz  
-       //                                       9B,3B,51,25    ;  1633 Hz  
+/* DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz   */
+       /*                                       EC,1D,52,22    ;  1336 Hz   */
+       /*                                       AA,AC,51,D2    ;  1477 Hz   */
+       /*                                       9B,3B,51,25    ;  1633 Hz   */
        j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
        j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
@@ -7628,1538 +8989,1562 @@ static void DAA_Coeff_Japan(IXJ *j)
 
 static s16 tone_table[][19] =
 {
-       {                       // f20_50[] 11
-               32538,          // A1 = 1.985962
-                -32325,        // A2 = -0.986511
-                -343,          // B2 = -0.010493
-                0,             // B1 = 0
-                343,           // B0 = 0.010493
-                32619,         // A1 = 1.990906
-                -32520,        // A2 = -0.992462
-                19179,         // B2 = 0.585327
-                -19178,        // B1 = -1.170593
-                19179,         // B0 = 0.585327
-                32723,         // A1 = 1.997314
-                -32686,        // A2 = -0.997528
-                9973,          // B2 = 0.304352
-                -9955,         // B1 = -0.607605
-                9973,          // B0 = 0.304352
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f20_50[] 11 */
+               32538,          /* A1 = 1.985962 */
+                -32325,        /* A2 = -0.986511 */
+                -343,          /* B2 = -0.010493 */
+                0,             /* B1 = 0 */
+                343,           /* B0 = 0.010493 */
+                32619,         /* A1 = 1.990906 */
+                -32520,        /* A2 = -0.992462 */
+                19179,         /* B2 = 0.585327 */
+                -19178,        /* B1 = -1.170593 */
+                19179,         /* B0 = 0.585327 */
+                32723,         /* A1 = 1.997314 */
+                -32686,        /* A2 = -0.997528 */
+                9973,          /* B2 = 0.304352 */
+                -9955,         /* B1 = -0.607605 */
+                9973,          /* B0 = 0.304352 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+       },
+       {                       /* f133_200[] 12 */
+               32072,          /* A1 = 1.95752 */
+                -31896,        /* A2 = -0.973419 */
+                -435,          /* B2 = -0.013294 */
+                0,             /* B1 = 0 */
+                435,           /* B0 = 0.013294 */
+                32188,         /* A1 = 1.9646 */
+                -32400,        /* A2 = -0.98877 */
+                15139,         /* B2 = 0.462036 */
+                -14882,        /* B1 = -0.908356 */
+                15139,         /* B0 = 0.462036 */
+                32473,         /* A1 = 1.981995 */
+                -32524,        /* A2 = -0.992584 */
+                23200,         /* B2 = 0.708008 */
+                -23113,        /* B1 = -1.410706 */
+                23200,         /* B0 = 0.708008 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // f133_200[] 12
-               32072,          // A1 = 1.95752
-                -31896,        // A2 = -0.973419
-                -435,          // B2 = -0.013294
-                0,             // B1 = 0
-                435,           // B0 = 0.013294
-                32188,         // A1 = 1.9646
-                -32400,        // A2 = -0.98877
-                15139,         // B2 = 0.462036
-                -14882,        // B1 = -0.908356
-                15139,         // B0 = 0.462036
-                32473,         // A1 = 1.981995
-                -32524,        // A2 = -0.992584
-                23200,         // B2 = 0.708008
-                -23113,        // B1 = -1.410706
-                23200,         // B0 = 0.708008
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f300 13 */
+               31769,          /* A1 = -1.939026 */
+                -32584,        /* A2 = 0.994385 */
+                -475,          /* B2 = -0.014522 */
+                0,             /* B1 = 0.000000 */
+                475,           /* B0 = 0.014522 */
+                31789,         /* A1 = -1.940247 */
+                -32679,        /* A2 = 0.997284 */
+                17280,         /* B2 = 0.527344 */
+                -16865,        /* B1 = -1.029358 */
+                17280,         /* B0 = 0.527344 */
+                31841,         /* A1 = -1.943481 */
+                -32681,        /* A2 = 0.997345 */
+                543,           /* B2 = 0.016579 */
+                -525,          /* B1 = -0.032097 */
+                543,           /* B0 = 0.016579 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 300.txt 13
-               31769,          // A1 = -1.939026
-                -32584,        // A2 = 0.994385
-                -475,          // B2 = -0.014522
-                0,             // B1 = 0.000000
-                475,           // B0 = 0.014522
-                31789,         // A1 = -1.940247
-                -32679,        // A2 = 0.997284
-                17280,         // B2 = 0.527344
-                -16865,        // B1 = -1.029358
-                17280,         // B0 = 0.527344
-                31841,         // A1 = -1.943481
-                -32681,        // A2 = 0.997345
-                543,           // B2 = 0.016579
-                -525,          // B1 = -0.032097
-                543,           // B0 = 0.016579
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f300_420[] 14 */
+               30750,          /* A1 = 1.876892 */
+                -31212,        /* A2 = -0.952515 */
+                -804,          /* B2 = -0.024541 */
+                0,             /* B1 = 0 */
+                804,           /* B0 = 0.024541 */
+                30686,         /* A1 = 1.872925 */
+                -32145,        /* A2 = -0.980988 */
+                14747,         /* B2 = 0.450043 */
+                -13703,        /* B1 = -0.836395 */
+                14747,         /* B0 = 0.450043 */
+                31651,         /* A1 = 1.931824 */
+                -32321,        /* A2 = -0.986389 */
+                24425,         /* B2 = 0.745422 */
+                -23914,        /* B1 = -1.459595 */
+                24427,         /* B0 = 0.745483 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // f300_420[] 14
-               30750,          // A1 = 1.876892
-                -31212,        // A2 = -0.952515
-                -804,          // B2 = -0.024541
-                0,             // B1 = 0
-                804,           // B0 = 0.024541
-                30686,         // A1 = 1.872925
-                -32145,        // A2 = -0.980988
-                14747,         // B2 = 0.450043
-                -13703,        // B1 = -0.836395
-                14747,         // B0 = 0.450043
-                31651,         // A1 = 1.931824
-                -32321,        // A2 = -0.986389
-                24425,         // B2 = 0.745422
-                -23914,        // B1 = -1.459595
-                24427,         // B0 = 0.745483
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f330 15 */
+               31613,          /* A1 = -1.929565 */
+                -32646,        /* A2 = 0.996277 */
+                -185,          /* B2 = -0.005657 */
+                0,             /* B1 = 0.000000 */
+                185,           /* B0 = 0.005657 */
+                31620,         /* A1 = -1.929932 */
+                -32713,        /* A2 = 0.998352 */
+                19253,         /* B2 = 0.587585 */
+                -18566,        /* B1 = -1.133179 */
+                19253,         /* B0 = 0.587585 */
+                31674,         /* A1 = -1.933228 */
+                -32715,        /* A2 = 0.998413 */
+                2575,          /* B2 = 0.078590 */
+                -2495,         /* B1 = -0.152283 */
+                2575,          /* B0 = 0.078590 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 330.txt 15
-               31613,          // A1 = -1.929565
-                -32646,        // A2 = 0.996277
-                -185,          // B2 = -0.005657
-                0,             // B1 = 0.000000
-                185,           // B0 = 0.005657
-                31620,         // A1 = -1.929932
-                -32713,        // A2 = 0.998352
-                19253,         // B2 = 0.587585
-                -18566,        // B1 = -1.133179
-                19253,         // B0 = 0.587585
-                31674,         // A1 = -1.933228
-                -32715,        // A2 = 0.998413
-                2575,          // B2 = 0.078590
-                -2495,         // B1 = -0.152283
-                2575,          // B0 = 0.078590
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f300_425[] 16 */
+               30741,          /* A1 = 1.876282 */
+                -31475,        /* A2 = -0.960541 */
+                -703,          /* B2 = -0.021484 */
+                0,             /* B1 = 0 */
+                703,           /* B0 = 0.021484 */
+                30688,         /* A1 = 1.873047 */
+                -32248,        /* A2 = -0.984161 */
+                14542,         /* B2 = 0.443787 */
+                -13523,        /* B1 = -0.825439 */
+                14542,         /* B0 = 0.443817 */
+                31494,         /* A1 = 1.922302 */
+                -32366,        /* A2 = -0.987762 */
+                21577,         /* B2 = 0.658508 */
+                -21013,        /* B1 = -1.282532 */
+                21577,         /* B0 = 0.658508 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // f300_425[] 16
-               30741,          // A1 = 1.876282
-                -31475,        // A2 = -0.960541
-                -703,          // B2 = -0.021484
-                0,             // B1 = 0
-                703,           // B0 = 0.021484
-                30688,         // A1 = 1.873047
-                -32248,        // A2 = -0.984161
-                14542,         // B2 = 0.443787
-                -13523,        // B1 = -0.825439
-                14542,         // B0 = 0.443817
-                31494,         // A1 = 1.922302
-                -32366,        // A2 = -0.987762
-                21577,         // B2 = 0.658508
-                -21013,        // B1 = -1.282532
-                21577,         // B0 = 0.658508
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f330_440[] 17 */
+               30627,          /* A1 = 1.869324 */
+                -31338,        /* A2 = -0.95636 */
+                -843,          /* B2 = -0.025749 */
+                0,             /* B1 = 0 */
+                843,           /* B0 = 0.025749 */
+                30550,         /* A1 = 1.864685 */
+                -32221,        /* A2 = -0.983337 */
+                13594,         /* B2 = 0.414886 */
+                -12589,        /* B1 = -0.768402 */
+                13594,         /* B0 = 0.414886 */
+                31488,         /* A1 = 1.921936 */
+                -32358,        /* A2 = -0.987518 */
+                24684,         /* B2 = 0.753296 */
+                -24029,        /* B1 = -1.466614 */
+                24684,         /* B0 = 0.753296 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // f330_440[] 17
-               30627,          // A1 = 1.869324
-                -31338,        // A2 = -0.95636
-                -843,          // B2 = -0.025749
-                0,             // B1 = 0
-                843,           // B0 = 0.025749
-                30550,         // A1 = 1.864685
-                -32221,        // A2 = -0.983337
-                13594,         // B2 = 0.414886
-                -12589,        // B1 = -0.768402
-                13594,         // B0 = 0.414886
-                31488,         // A1 = 1.921936
-                -32358,        // A2 = -0.987518
-                24684,         // B2 = 0.753296
-                -24029,        // B1 = -1.466614
-                24684,         // B0 = 0.753296
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f340 18 */
+               31546,          /* A1 = -1.925476 */
+                -32646,        /* A2 = 0.996277 */
+                -445,          /* B2 = -0.013588 */
+                0,             /* B1 = 0.000000 */
+                445,           /* B0 = 0.013588 */
+                31551,         /* A1 = -1.925781 */
+                -32713,        /* A2 = 0.998352 */
+                23884,         /* B2 = 0.728882 */
+                -22979,        /* B1 = -1.402527 */
+                23884,         /* B0 = 0.728882 */
+                31606,         /* A1 = -1.929138 */
+                -32715,        /* A2 = 0.998413 */
+                863,           /* B2 = 0.026367 */
+                -835,          /* B1 = -0.050985 */
+                863,           /* B0 = 0.026367 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 340.txt 18
-               31546,          // A1 = -1.925476
-                -32646,        // A2 = 0.996277
-                -445,          // B2 = -0.013588
-                0,             // B1 = 0.000000
-                445,           // B0 = 0.013588
-                31551,         // A1 = -1.925781
-                -32713,        // A2 = 0.998352
-                23884,         // B2 = 0.728882
-                -22979,        // B1 = -1.402527
-                23884,         // B0 = 0.728882
-                31606,         // A1 = -1.929138
-                -32715,        // A2 = 0.998413
-                863,           // B2 = 0.026367
-                -835,          // B1 = -0.050985
-                863,           // B0 = 0.026367
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f350_400[] 19 */
+               31006,          /* A1 = 1.892517 */
+                -32029,        /* A2 = -0.977448 */
+                -461,          /* B2 = -0.014096 */
+                0,             /* B1 = 0 */
+                461,           /* B0 = 0.014096 */
+                30999,         /* A1 = 1.892029 */
+                -32487,        /* A2 = -0.991455 */
+                11325,         /* B2 = 0.345612 */
+                -10682,        /* B1 = -0.651978 */
+                11325,         /* B0 = 0.345612 */
+                31441,         /* A1 = 1.919067 */
+                -32526,        /* A2 = -0.992615 */
+                24324,         /* B2 = 0.74231 */
+                -23535,        /* B1 = -1.436523 */
+                24324,         /* B0 = 0.74231 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // f350_400[] 19
-               31006,          // A1 = 1.892517
-                -32029,        // A2 = -0.977448
-                -461,          // B2 = -0.014096
-                0,             // B1 = 0
-                461,           // B0 = 0.014096
-                30999,         // A1 = 1.892029
-                -32487,        // A2 = -0.991455
-                11325,         // B2 = 0.345612
-                -10682,        // B1 = -0.651978
-                11325,         // B0 = 0.345612
-                31441,         // A1 = 1.919067
-                -32526,        // A2 = -0.992615
-                24324,         // B2 = 0.74231
-                -23535,        // B1 = -1.436523
-                24324,         // B0 = 0.74231
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f350_440[] */
+               30634,          /* A1 = 1.869751 */
+                -31533,        /* A2 = -0.962341 */
+                -680,          /* B2 = -0.020782 */
+                0,             /* B1 = 0 */
+                680,           /* B0 = 0.020782 */
+                30571,         /* A1 = 1.865906 */
+                -32277,        /* A2 = -0.985016 */
+                12894,         /* B2 = 0.393524 */
+                -11945,        /* B1 = -0.729065 */
+                12894,         /* B0 = 0.393524 */
+                31367,         /* A1 = 1.91449 */
+                -32379,        /* A2 = -0.988129 */
+                23820,         /* B2 = 0.726929 */
+                -23104,        /* B1 = -1.410217 */
+                23820,         /* B0 = 0.726929 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // f350_440[]
-               30634,          // A1 = 1.869751
-                -31533,        // A2 = -0.962341
-                -680,          // B2 = -0.020782
-                0,             // B1 = 0
-                680,           // B0 = 0.020782
-                30571,         // A1 = 1.865906
-                -32277,        // A2 = -0.985016
-                12894,         // B2 = 0.393524
-                -11945,        // B1 = -0.729065
-                12894,         // B0 = 0.393524
-                31367,         // A1 = 1.91449
-                -32379,        // A2 = -0.988129
-                23820,         // B2 = 0.726929
-                -23104,        // B1 = -1.410217
-                23820,         // B0 = 0.726929
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f350_450[] */
+               30552,          /* A1 = 1.864807 */
+                -31434,        /* A2 = -0.95929 */
+                -690,          /* B2 = -0.021066 */
+                0,             /* B1 = 0 */
+                690,           /* B0 = 0.021066 */
+                30472,         /* A1 = 1.859924 */
+                -32248,        /* A2 = -0.984161 */
+                13385,         /* B2 = 0.408478 */
+                -12357,        /* B1 = -0.754242 */
+                13385,         /* B0 = 0.408478 */
+                31358,         /* A1 = 1.914001 */
+                -32366,        /* A2 = -0.987732 */
+                26488,         /* B2 = 0.80835 */
+                -25692,        /* B1 = -1.568176 */
+                26490,         /* B0 = 0.808411 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // f350_450[]
-               30552,          // A1 = 1.864807
-                -31434,        // A2 = -0.95929
-                -690,          // B2 = -0.021066
-                0,             // B1 = 0
-                690,           // B0 = 0.021066
-                30472,         // A1 = 1.859924
-                -32248,        // A2 = -0.984161
-                13385,         // B2 = 0.408478
-                -12357,        // B1 = -0.754242
-                13385,         // B0 = 0.408478
-                31358,         // A1 = 1.914001
-                -32366,        // A2 = -0.987732
-                26488,         // B2 = 0.80835
-                -25692,        // B1 = -1.568176
-                26490,         // B0 = 0.808411
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f360 */
+               31397,          /* A1 = -1.916321 */
+                -32623,        /* A2 = 0.995605 */
+                -117,          /* B2 = -0.003598 */
+                0,             /* B1 = 0.000000 */
+                117,           /* B0 = 0.003598 */
+                31403,         /* A1 = -1.916687 */
+                -32700,        /* A2 = 0.997925 */
+                3388,          /* B2 = 0.103401 */
+                -3240,         /* B1 = -0.197784 */
+                3388,          /* B0 = 0.103401 */
+                31463,         /* A1 = -1.920410 */
+                -32702,        /* A2 = 0.997986 */
+                13346,         /* B2 = 0.407288 */
+                -12863,        /* B1 = -0.785126 */
+                13346,         /* B0 = 0.407288 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 360.txt
-               31397,          // A1 = -1.916321
-                -32623,        // A2 = 0.995605
-                -117,          // B2 = -0.003598
-                0,             // B1 = 0.000000
-                117,           // B0 = 0.003598
-                31403,         // A1 = -1.916687
-                -32700,        // A2 = 0.997925
-                3388,          // B2 = 0.103401
-                -3240,         // B1 = -0.197784
-                3388,          // B0 = 0.103401
-                31463,         // A1 = -1.920410
-                -32702,        // A2 = 0.997986
-                13346,         // B2 = 0.407288
-                -12863,        // B1 = -0.785126
-                13346,         // B0 = 0.407288
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f380_420[] */
+               30831,          /* A1 = 1.881775 */
+                -32064,        /* A2 = -0.978546 */
+                -367,          /* B2 = -0.01122 */
+                0,             /* B1 = 0 */
+                367,           /* B0 = 0.01122 */
+                30813,         /* A1 = 1.880737 */
+                -32456,        /* A2 = -0.990509 */
+                11068,         /* B2 = 0.337769 */
+                -10338,        /* B1 = -0.631042 */
+                11068,         /* B0 = 0.337769 */
+                31214,         /* A1 = 1.905212 */
+                -32491,        /* A2 = -0.991577 */
+                16374,         /* B2 = 0.499695 */
+                -15781,        /* B1 = -0.963196 */
+                16374,         /* B0 = 0.499695 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // f380_420[]
-               30831,          // A1 = 1.881775
-                -32064,        // A2 = -0.978546
-                -367,          // B2 = -0.01122
-                0,             // B1 = 0
-                367,           // B0 = 0.01122
-                30813,         // A1 = 1.880737
-                -32456,        // A2 = -0.990509
-                11068,         // B2 = 0.337769
-                -10338,        // B1 = -0.631042
-                11068,         // B0 = 0.337769
-                31214,         // A1 = 1.905212
-                -32491,        // A2 = -0.991577
-                16374,         // B2 = 0.499695
-                -15781,        // B1 = -0.963196
-                16374,         // B0 = 0.499695
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f392 */
+               31152,          /* A1 = -1.901428 */
+                -32613,        /* A2 = 0.995300 */
+                -314,          /* B2 = -0.009605 */
+                0,             /* B1 = 0.000000 */
+                314,           /* B0 = 0.009605 */
+                31156,         /* A1 = -1.901672 */
+                -32694,        /* A2 = 0.997742 */
+                28847,         /* B2 = 0.880371 */
+                -2734,         /* B1 = -0.166901 */
+                28847,         /* B0 = 0.880371 */
+                31225,         /* A1 = -1.905823 */
+                -32696,        /* A2 = 0.997803 */
+                462,           /* B2 = 0.014108 */
+                -442,          /* B1 = -0.027019 */
+                462,           /* B0 = 0.014108 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 392.txt
-               31152,          // A1 = -1.901428
-                -32613,        // A2 = 0.995300
-                -314,          // B2 = -0.009605
-                0,             // B1 = 0.000000
-                314,           // B0 = 0.009605
-                31156,         // A1 = -1.901672
-                -32694,        // A2 = 0.997742
-                28847,         // B2 = 0.880371
-                -2734,         // B1 = -0.166901
-                28847,         // B0 = 0.880371
-                31225,         // A1 = -1.905823
-                -32696,        // A2 = 0.997803
-                462,           // B2 = 0.014108
-                -442,          // B1 = -0.027019
-                462,           // B0 = 0.014108
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f400_425[] */
+               30836,          /* A1 = 1.882141 */
+                -32296,        /* A2 = -0.985596 */
+                -324,          /* B2 = -0.009903 */
+                0,             /* B1 = 0 */
+                324,           /* B0 = 0.009903 */
+                30825,         /* A1 = 1.881409 */
+                -32570,        /* A2 = -0.993958 */
+                16847,         /* B2 = 0.51416 */
+                -15792,        /* B1 = -0.963898 */
+                16847,         /* B0 = 0.51416 */
+                31106,         /* A1 = 1.89856 */
+                -32584,        /* A2 = -0.994415 */
+                9579,          /* B2 = 0.292328 */
+                -9164,         /* B1 = -0.559357 */
+                9579,          /* B0 = 0.292328 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // f400_425[]
-               30836,          // A1 = 1.882141
-                -32296,        // A2 = -0.985596
-                -324,          // B2 = -0.009903
-                0,             // B1 = 0
-                324,           // B0 = 0.009903
-                30825,         // A1 = 1.881409
-                -32570,        // A2 = -0.993958
-                16847,         // B2 = 0.51416
-                -15792,        // B1 = -0.963898
-                16847,         // B0 = 0.51416
-                31106,         // A1 = 1.89856
-                -32584,        // A2 = -0.994415
-                9579,          // B2 = 0.292328
-                -9164,         // B1 = -0.559357
-                9579,          // B0 = 0.292328
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f400_440[] */
+               30702,          /* A1 = 1.873962 */
+                -32134,        /* A2 = -0.980682 */
+                -517,          /* B2 = -0.015793 */
+                0,             /* B1 = 0 */
+                517,           /* B0 = 0.015793 */
+                30676,         /* A1 = 1.872375 */
+                -32520,        /* A2 = -0.992462 */
+                8144,          /* B2 = 0.24855 */
+                -7596,         /* B1 = -0.463684 */
+                8144,          /* B0 = 0.24855 */
+                31084,         /* A1 = 1.897217 */
+                -32547,        /* A2 = -0.993256 */
+                22713,         /* B2 = 0.693176 */
+                -21734,        /* B1 = -1.326599 */
+                22713,         /* B0 = 0.693176 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // f400_440[]
-               30702,          // A1 = 1.873962
-                -32134,        // A2 = -0.980682
-                -517,          // B2 = -0.015793
-                0,             // B1 = 0
-                517,           // B0 = 0.015793
-                30676,         // A1 = 1.872375
-                -32520,        // A2 = -0.992462
-                8144,          // B2 = 0.24855
-                -7596,         // B1 = -0.463684
-                8144,          // B0 = 0.24855
-                31084,         // A1 = 1.897217
-                -32547,        // A2 = -0.993256
-                22713,         // B2 = 0.693176
-                -21734,        // B1 = -1.326599
-                22713,         // B0 = 0.693176
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f400_450[] */
+               30613,          /* A1 = 1.86853 */
+                -32031,        /* A2 = -0.977509 */
+                -618,          /* B2 = -0.018866 */
+                0,             /* B1 = 0 */
+                618,           /* B0 = 0.018866 */
+                30577,         /* A1 = 1.866272 */
+                -32491,        /* A2 = -0.991577 */
+                9612,          /* B2 = 0.293335 */
+                -8935,         /* B1 = -0.54541 */
+                9612,          /* B0 = 0.293335 */
+                31071,         /* A1 = 1.896484 */
+                -32524,        /* A2 = -0.992584 */
+                21596,         /* B2 = 0.659058 */
+                -20667,        /* B1 = -1.261414 */
+                21596,         /* B0 = 0.659058 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // f400_450[]
-               30613,          // A1 = 1.86853
-                -32031,        // A2 = -0.977509
-                -618,          // B2 = -0.018866
-                0,             // B1 = 0
-                618,           // B0 = 0.018866
-                30577,         // A1 = 1.866272
-                -32491,        // A2 = -0.991577
-                9612,          // B2 = 0.293335
-                -8935,         // B1 = -0.54541
-                9612,          // B0 = 0.293335
-                31071,         // A1 = 1.896484
-                -32524,        // A2 = -0.992584
-                21596,         // B2 = 0.659058
-                -20667,        // B1 = -1.261414
-                21596,         // B0 = 0.659058
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f420 */
+               30914,          /* A1 = -1.886841 */
+                -32584,        /* A2 = 0.994385 */
+                -426,          /* B2 = -0.013020 */
+                0,             /* B1 = 0.000000 */
+                426,           /* B0 = 0.013020 */
+                30914,         /* A1 = -1.886841 */
+                -32679,        /* A2 = 0.997314 */
+                17520,         /* B2 = 0.534668 */
+                -16471,        /* B1 = -1.005310 */
+                17520,         /* B0 = 0.534668 */
+                31004,         /* A1 = -1.892334 */
+                -32683,        /* A2 = 0.997406 */
+                819,           /* B2 = 0.025023 */
+                -780,          /* B1 = -0.047619 */
+                819,           /* B0 = 0.025023 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 420.txt
-               30914,          // A1 = -1.886841
-                -32584,        // A2 = 0.994385
-                -426,          // B2 = -0.013020
-                0,             // B1 = 0.000000
-                426,           // B0 = 0.013020
-                30914,         // A1 = -1.886841
-                -32679,        // A2 = 0.997314
-                17520,         // B2 = 0.534668
-                -16471,        // B1 = -1.005310
-                17520,         // B0 = 0.534668
-                31004,         // A1 = -1.892334
-                -32683,        // A2 = 0.997406
-                819,           // B2 = 0.025023
-                -780,          // B1 = -0.047619
-                819,           // B0 = 0.025023
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+#if 0
+       {                       /* f425 */
+               30881,          /* A1 = -1.884827 */
+                -32603,        /* A2 = 0.994965 */
+                -496,          /* B2 = -0.015144 */
+                0,             /* B1 = 0.000000 */
+                496,           /* B0 = 0.015144 */
+                30880,         /* A1 = -1.884766 */
+                -32692,        /* A2 = 0.997711 */
+                24767,         /* B2 = 0.755859 */
+                -23290,        /* B1 = -1.421509 */
+                24767,         /* B0 = 0.755859 */
+                30967,         /* A1 = -1.890076 */
+                -32694,        /* A2 = 0.997772 */
+                728,           /* B2 = 0.022232 */
+                -691,          /* B1 = -0.042194 */
+                728,           /* B0 = 0.022232 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 425.txt
-               30881,          // A1 = -1.884827
-                -32603,        // A2 = 0.994965
-                -496,          // B2 = -0.015144
-                0,             // B1 = 0.000000
-                496,           // B0 = 0.015144
-                30880,         // A1 = -1.884766
-                -32692,        // A2 = 0.997711
-                24767,         // B2 = 0.755859
-                -23290,        // B1 = -1.421509
-                24767,         // B0 = 0.755859
-                30967,         // A1 = -1.890076
-                -32694,        // A2 = 0.997772
-                728,           // B2 = 0.022232
-                -691,          // B1 = -0.042194
-                728,           // B0 = 0.022232
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+#else
+       {
+               30850,
+               -32534,
+               -504,
+               0,
+               504,
+               30831,
+               -32669,
+               24303,
+               -22080,
+               24303,
+               30994,
+               -32673,
+               1905,
+               -1811,
+               1905,
+               5,
+               129,
+               17,
+               0xff5
        },
-       {                       // f425_450[]
-               30646,          // A1 = 1.870544
-                -32327,        // A2 = -0.986572
-                -287,          // B2 = -0.008769
-                0,             // B1 = 0
-                287,           // B0 = 0.008769
-                30627,         // A1 = 1.869324
-                -32607,        // A2 = -0.995087
-                13269,         // B2 = 0.404968
-                -12376,        // B1 = -0.755432
-                13269,         // B0 = 0.404968
-                30924,         // A1 = 1.887512
-                -32619,        // A2 = -0.995453
-                19950,         // B2 = 0.608826
-                -18940,        // B1 = -1.156006
-                19950,         // B0 = 0.608826
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+#endif
+       {                       /* f425_450[] */
+               30646,          /* A1 = 1.870544 */
+                -32327,        /* A2 = -0.986572 */
+                -287,          /* B2 = -0.008769 */
+                0,             /* B1 = 0 */
+                287,           /* B0 = 0.008769 */
+                30627,         /* A1 = 1.869324 */
+                -32607,        /* A2 = -0.995087 */
+                13269,         /* B2 = 0.404968 */
+                -12376,        /* B1 = -0.755432 */
+                13269,         /* B0 = 0.404968 */
+                30924,         /* A1 = 1.887512 */
+                -32619,        /* A2 = -0.995453 */
+                19950,         /* B2 = 0.608826 */
+                -18940,        /* B1 = -1.156006 */
+                19950,         /* B0 = 0.608826 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // f425_475[]
-               30396,          // A1 = 1.855225
-                -32014,        // A2 = -0.97699
-                -395,          // B2 = -0.012055
-                0,             // B1 = 0
-                395,           // B0 = 0.012055
-                30343,         // A1 = 1.85199
-                -32482,        // A2 = -0.991302
-                17823,         // B2 = 0.543945
-                -16431,        // B1 = -1.002869
-                17823,         // B0 = 0.543945
-                30872,         // A1 = 1.884338
-                -32516,        // A2 = -0.99231
-                18124,         // B2 = 0.553101
-                -17246,        // B1 = -1.052673
-                18124,         // B0 = 0.553101
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f425_475[] */
+               30396,          /* A1 = 1.855225 */
+                -32014,        /* A2 = -0.97699 */
+                -395,          /* B2 = -0.012055 */
+                0,             /* B1 = 0 */
+                395,           /* B0 = 0.012055 */
+                30343,         /* A1 = 1.85199 */
+                -32482,        /* A2 = -0.991302 */
+                17823,         /* B2 = 0.543945 */
+                -16431,        /* B1 = -1.002869 */
+                17823,         /* B0 = 0.543945 */
+                30872,         /* A1 = 1.884338 */
+                -32516,        /* A2 = -0.99231 */
+                18124,         /* B2 = 0.553101 */
+                -17246,        /* B1 = -1.052673 */
+                18124,         /* B0 = 0.553101 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 435.txt
-               30796,          // A1 = -1.879639
-                -32603,        // A2 = 0.994965
-                -254,          // B2 = -0.007762
-                0,             // B1 = 0.000000
-                254,           // B0 = 0.007762
-                30793,         // A1 = -1.879456
-                -32692,        // A2 = 0.997711
-                18934,         // B2 = 0.577820
-                -17751,        // B1 = -1.083496
-                18934,         // B0 = 0.577820
-                30882,         // A1 = -1.884888
-                -32694,        // A2 = 0.997772
-                1858,          // B2 = 0.056713
-                -1758,         // B1 = -0.107357
-                1858,          // B0 = 0.056713
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f435 */
+               30796,          /* A1 = -1.879639 */
+                -32603,        /* A2 = 0.994965 */
+                -254,          /* B2 = -0.007762 */
+                0,             /* B1 = 0.000000 */
+                254,           /* B0 = 0.007762 */
+                30793,         /* A1 = -1.879456 */
+                -32692,        /* A2 = 0.997711 */
+                18934,         /* B2 = 0.577820 */
+                -17751,        /* B1 = -1.083496 */
+                18934,         /* B0 = 0.577820 */
+                30882,         /* A1 = -1.884888 */
+                -32694,        /* A2 = 0.997772 */
+                1858,          /* B2 = 0.056713 */
+                -1758,         /* B1 = -0.107357 */
+                1858,          /* B0 = 0.056713 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // f440_450[]
-               30641,          // A1 = 1.870239
-                -32458,        // A2 = -0.99057
-                -155,          // B2 = -0.004735
-                0,             // B1 = 0
-                155,           // B0 = 0.004735
-                30631,         // A1 = 1.869568
-                -32630,        // A2 = -0.995789
-                11453,         // B2 = 0.349548
-                -10666,        // B1 = -0.651001
-                11453,         // B0 = 0.349548
-                30810,         // A1 = 1.880554
-                -32634,        // A2 = -0.995941
-                12237,         // B2 = 0.373474
-                -11588,        // B1 = -0.707336
-                12237,         // B0 = 0.373474
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f440_450[] */
+               30641,          /* A1 = 1.870239 */
+                -32458,        /* A2 = -0.99057 */
+                -155,          /* B2 = -0.004735 */
+                0,             /* B1 = 0 */
+                155,           /* B0 = 0.004735 */
+                30631,         /* A1 = 1.869568 */
+                -32630,        /* A2 = -0.995789 */
+                11453,         /* B2 = 0.349548 */
+                -10666,        /* B1 = -0.651001 */
+                11453,         /* B0 = 0.349548 */
+                30810,         /* A1 = 1.880554 */
+                -32634,        /* A2 = -0.995941 */
+                12237,         /* B2 = 0.373474 */
+                -11588,        /* B1 = -0.707336 */
+                12237,         /* B0 = 0.373474 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // f440_480[]
-               30367,          // A1 = 1.853455
-                -32147,        // A2 = -0.981079
-                -495,          // B2 = -0.015113
-                0,             // B1 = 0
-                495,           // B0 = 0.015113
-                30322,         // A1 = 1.850769
-                -32543,        // A2 = -0.993134
-                10031,         // B2 = 0.306152
-                -9252,         // B1 = -0.564728
-                10031,         // B0 = 0.306152
-                30770,         // A1 = 1.878052
-                -32563,        // A2 = -0.993774
-                22674,         // B2 = 0.691956
-                -21465,        // B1 = -1.31012
-                22674,         // B0 = 0.691956
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f440_480[] */
+               30367,          /* A1 = 1.853455 */
+                -32147,        /* A2 = -0.981079 */
+                -495,          /* B2 = -0.015113 */
+                0,             /* B1 = 0 */
+                495,           /* B0 = 0.015113 */
+                30322,         /* A1 = 1.850769 */
+                -32543,        /* A2 = -0.993134 */
+                10031,         /* B2 = 0.306152 */
+                -9252,         /* B1 = -0.564728 */
+                10031,         /* B0 = 0.306152 */
+                30770,         /* A1 = 1.878052 */
+                -32563,        /* A2 = -0.993774 */
+                22674,         /* B2 = 0.691956 */
+                -21465,        /* B1 = -1.31012 */
+                22674,         /* B0 = 0.691956 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 445.txt
-               30709,          // A1 = -1.874329
-                -32603,        // A2 = 0.994965
-                -83,           // B2 = -0.002545
-                0,             // B1 = 0.000000
-                83,            // B0 = 0.002545
-                30704,         // A1 = -1.874084
-                -32692,        // A2 = 0.997711
-                10641,         // B2 = 0.324738
-                -9947,         // B1 = -0.607147
-                10641,         // B0 = 0.324738
-                30796,         // A1 = -1.879639
-                -32694,        // A2 = 0.997772
-                10079,         // B2 = 0.307587
-                9513,          // B1 = 0.580688
-                10079,         // B0 = 0.307587
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f445 */
+               30709,          /* A1 = -1.874329 */
+                -32603,        /* A2 = 0.994965 */
+                -83,           /* B2 = -0.002545 */
+                0,             /* B1 = 0.000000 */
+                83,            /* B0 = 0.002545 */
+                30704,         /* A1 = -1.874084 */
+                -32692,        /* A2 = 0.997711 */
+                10641,         /* B2 = 0.324738 */
+                -9947,         /* B1 = -0.607147 */
+                10641,         /* B0 = 0.324738 */
+                30796,         /* A1 = -1.879639 */
+                -32694,        /* A2 = 0.997772 */
+                10079,         /* B2 = 0.307587 */
+                9513,          /* B1 = 0.580688 */
+                10079,         /* B0 = 0.307587 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 450.txt
-               30664,          // A1 = -1.871643
-                -32603,        // A2 = 0.994965
-                -164,          // B2 = -0.005029
-                0,             // B1 = 0.000000
-                164,           // B0 = 0.005029
-                30661,         // A1 = -1.871399
-                -32692,        // A2 = 0.997711
-                15294,         // B2 = 0.466736
-                -14275,        // B1 = -0.871307
-                15294,         // B0 = 0.466736
-                30751,         // A1 = -1.876953
-                -32694,        // A2 = 0.997772
-                3548,          // B2 = 0.108284
-                -3344,         // B1 = -0.204155
-                3548,          // B0 = 0.108284
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f450 */
+               30664,          /* A1 = -1.871643 */
+                -32603,        /* A2 = 0.994965 */
+                -164,          /* B2 = -0.005029 */
+                0,             /* B1 = 0.000000 */
+                164,           /* B0 = 0.005029 */
+                30661,         /* A1 = -1.871399 */
+                -32692,        /* A2 = 0.997711 */
+                15294,         /* B2 = 0.466736 */
+                -14275,        /* B1 = -0.871307 */
+                15294,         /* B0 = 0.466736 */
+                30751,         /* A1 = -1.876953 */
+                -32694,        /* A2 = 0.997772 */
+                3548,          /* B2 = 0.108284 */
+                -3344,         /* B1 = -0.204155 */
+                3548,          /* B0 = 0.108284 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 452.txt
-               30653,          // A1 = -1.870911
-                -32615,        // A2 = 0.995361
-                -209,          // B2 = -0.006382
-                0,             // B1 = 0.000000
-                209,           // B0 = 0.006382
-                30647,         // A1 = -1.870605
-                -32702,        // A2 = 0.997986
-                18971,         // B2 = 0.578979
-                -17716,        // B1 = -1.081299
-                18971,         // B0 = 0.578979
-                30738,         // A1 = -1.876099
-                -32702,        // A2 = 0.998016
-                2967,          // B2 = 0.090561
-                -2793,         // B1 = -0.170502
-                2967,          // B0 = 0.090561
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f452 */
+               30653,          /* A1 = -1.870911 */
+                -32615,        /* A2 = 0.995361 */
+                -209,          /* B2 = -0.006382 */
+                0,             /* B1 = 0.000000 */
+                209,           /* B0 = 0.006382 */
+                30647,         /* A1 = -1.870605 */
+                -32702,        /* A2 = 0.997986 */
+                18971,         /* B2 = 0.578979 */
+                -17716,        /* B1 = -1.081299 */
+                18971,         /* B0 = 0.578979 */
+                30738,         /* A1 = -1.876099 */
+                -32702,        /* A2 = 0.998016 */
+                2967,          /* B2 = 0.090561 */
+                -2793,         /* B1 = -0.170502 */
+                2967,          /* B0 = 0.090561 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 475.txt
-               30437,          // A1 = -1.857727
-                -32603,        // A2 = 0.994965
-                -264,          // B2 = -0.008062
-                0,             // B1 = 0.000000
-                264,           // B0 = 0.008062
-                30430,         // A1 = -1.857300
-                -32692,        // A2 = 0.997711
-                21681,         // B2 = 0.661682
-                -20082,        // B1 = -1.225708
-                21681,         // B0 = 0.661682
-                30526,         // A1 = -1.863220
-                -32694,        // A2 = 0.997742
-                1559,          // B2 = 0.047600
-                -1459,         // B1 = -0.089096
-                1559,          // B0 = 0.047600
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f475 */
+               30437,          /* A1 = -1.857727 */
+                -32603,        /* A2 = 0.994965 */
+                -264,          /* B2 = -0.008062 */
+                0,             /* B1 = 0.000000 */
+                264,           /* B0 = 0.008062 */
+                30430,         /* A1 = -1.857300 */
+                -32692,        /* A2 = 0.997711 */
+                21681,         /* B2 = 0.661682 */
+                -20082,        /* B1 = -1.225708 */
+                21681,         /* B0 = 0.661682 */
+                30526,         /* A1 = -1.863220 */
+                -32694,        /* A2 = 0.997742 */
+                1559,          /* B2 = 0.047600 */
+                -1459,         /* B1 = -0.089096 */
+                1559,          /* B0 = 0.047600 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // f480_620[]
-               28975,          // A1 = 1.768494
-                -30955,        // A2 = -0.944672
-                -1026,         // B2 = -0.03133
-                0,             // B1 = 0
-                1026,          // B0 = 0.03133
-                28613,         // A1 = 1.746399
-                -32089,        // A2 = -0.979309
-                14214,         // B2 = 0.433807
-                -12202,        // B1 = -0.744812
-                14214,         // B0 = 0.433807
-                30243,         // A1 = 1.845947
-                -32238,        // A2 = -0.983856
-                24825,         // B2 = 0.757629
-                -23402,        // B1 = -1.428345
-                24825,         // B0 = 0.757629
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f480_620[] */
+               28975,          /* A1 = 1.768494 */
+                -30955,        /* A2 = -0.944672 */
+                -1026,         /* B2 = -0.03133 */
+                0,             /* B1 = 0 */
+                1026,          /* B0 = 0.03133 */
+                28613,         /* A1 = 1.746399 */
+                -32089,        /* A2 = -0.979309 */
+                14214,         /* B2 = 0.433807 */
+                -12202,        /* B1 = -0.744812 */
+                14214,         /* B0 = 0.433807 */
+                30243,         /* A1 = 1.845947 */
+                -32238,        /* A2 = -0.983856 */
+                24825,         /* B2 = 0.757629 */
+                -23402,        /* B1 = -1.428345 */
+                24825,         /* B0 = 0.757629 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 494.txt
-               30257,          // A1 = -1.846741
-                -32605,        // A2 = 0.995056
-                -249,          // B2 = -0.007625
-                0,             // B1 = 0.000000
-                249,           // B0 = 0.007625
-                30247,         // A1 = -1.846191
-                -32694,        // A2 = 0.997772
-                18088,         // B2 = 0.552002
-                -16652,        // B1 = -1.016418
-                18088,         // B0 = 0.552002
-                30348,         // A1 = -1.852295
-                -32696,        // A2 = 0.997803
-                2099,          // B2 = 0.064064
-                -1953,         // B1 = -0.119202
-                2099,          // B0 = 0.064064
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f494 */
+               30257,          /* A1 = -1.846741 */
+                -32605,        /* A2 = 0.995056 */
+                -249,          /* B2 = -0.007625 */
+                0,             /* B1 = 0.000000 */
+                249,           /* B0 = 0.007625 */
+                30247,         /* A1 = -1.846191 */
+                -32694,        /* A2 = 0.997772 */
+                18088,         /* B2 = 0.552002 */
+                -16652,        /* B1 = -1.016418 */
+                18088,         /* B0 = 0.552002 */
+                30348,         /* A1 = -1.852295 */
+                -32696,        /* A2 = 0.997803 */
+                2099,          /* B2 = 0.064064 */
+                -1953,         /* B1 = -0.119202 */
+                2099,          /* B0 = 0.064064 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 500.txt
-               30202,          // A1 = -1.843431
-                -32624,        // A2 = 0.995622
-                -413,          // B2 = -0.012622
-                0,             // B1 = 0.000000
-                413,           // B0 = 0.012622
-                30191,         // A1 = -1.842721
-                -32714,        // A2 = 0.998364
-                25954,         // B2 = 0.792057
-                -23890,        // B1 = -1.458131
-                25954,         // B0 = 0.792057
-                30296,         // A1 = -1.849172
-                -32715,        // A2 = 0.998397
-                2007,          // B2 = 0.061264
-                -1860,         // B1 = -0.113568
-                2007,          // B0 = 0.061264
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f500 */
+               30202,          /* A1 = -1.843431 */
+                -32624,        /* A2 = 0.995622 */
+                -413,          /* B2 = -0.012622 */
+                0,             /* B1 = 0.000000 */
+                413,           /* B0 = 0.012622 */
+                30191,         /* A1 = -1.842721 */
+                -32714,        /* A2 = 0.998364 */
+                25954,         /* B2 = 0.792057 */
+                -23890,        /* B1 = -1.458131 */
+                25954,         /* B0 = 0.792057 */
+                30296,         /* A1 = -1.849172 */
+                -32715,        /* A2 = 0.998397 */
+                2007,          /* B2 = 0.061264 */
+                -1860,         /* B1 = -0.113568 */
+                2007,          /* B0 = 0.061264 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 520.txt
-               30001,          // A1 = -1.831116
-                -32613,        // A2 = 0.995270
-                -155,          // B2 = -0.004750
-                0,             // B1 = 0.000000
-                155,           // B0 = 0.004750
-                29985,         // A1 = -1.830200
-                -32710,        // A2 = 0.998260
-                6584,          // B2 = 0.200928
-                -6018,         // B1 = -0.367355
-                6584,          // B0 = 0.200928
-                30105,         // A1 = -1.837524
-                -32712,        // A2 = 0.998291
-                23812,         // B2 = 0.726685
-                -21936,        // B1 = -1.338928
-                23812,         // B0 = 0.726685
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f520 */
+               30001,          /* A1 = -1.831116 */
+                -32613,        /* A2 = 0.995270 */
+                -155,          /* B2 = -0.004750 */
+                0,             /* B1 = 0.000000 */
+                155,           /* B0 = 0.004750 */
+                29985,         /* A1 = -1.830200 */
+                -32710,        /* A2 = 0.998260 */
+                6584,          /* B2 = 0.200928 */
+                -6018,         /* B1 = -0.367355 */
+                6584,          /* B0 = 0.200928 */
+                30105,         /* A1 = -1.837524 */
+                -32712,        /* A2 = 0.998291 */
+                23812,         /* B2 = 0.726685 */
+                -21936,        /* B1 = -1.338928 */
+                23812,         /* B0 = 0.726685 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 523.txt
-               29964,          // A1 = -1.828918
-                -32601,        // A2 = 0.994904
-                -101,          // B2 = -0.003110
-                0,             // B1 = 0.000000
-                101,           // B0 = 0.003110
-                29949,         // A1 = -1.827942
-                -32700,        // A2 = 0.997925
-                11041,         // B2 = 0.336975
-                -10075,        // B1 = -0.614960
-                11041,         // B0 = 0.336975
-                30070,         // A1 = -1.835388
-                -32702,        // A2 = 0.997986
-                16762,         // B2 = 0.511536
-                -15437,        // B1 = -0.942230
-                16762,         // B0 = 0.511536
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f523 */
+               29964,          /* A1 = -1.828918 */
+                -32601,        /* A2 = 0.994904 */
+                -101,          /* B2 = -0.003110 */
+                0,             /* B1 = 0.000000 */
+                101,           /* B0 = 0.003110 */
+                29949,         /* A1 = -1.827942 */
+                -32700,        /* A2 = 0.997925 */
+                11041,         /* B2 = 0.336975 */
+                -10075,        /* B1 = -0.614960 */
+                11041,         /* B0 = 0.336975 */
+                30070,         /* A1 = -1.835388 */
+                -32702,        /* A2 = 0.997986 */
+                16762,         /* B2 = 0.511536 */
+                -15437,        /* B1 = -0.942230 */
+                16762,         /* B0 = 0.511536 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 525.txt
-               29936,          // A1 = -1.827209
-                -32584,        // A2 = 0.994415
-                -91,           // B2 = -0.002806
-                0,             // B1 = 0.000000
-                91,            // B0 = 0.002806
-                29921,         // A1 = -1.826233
-                -32688,        // A2 = 0.997559
-                11449,         // B2 = 0.349396
-                -10426,        // B1 = -0.636383
-                11449,         // B0 = 0.349396
-                30045,         // A1 = -1.833862
-                -32688,        // A2 = 0.997589
-                13055,         // B2 = 0.398407
-                -12028,        // B1 = -0.734161
-                13055,         // B0 = 0.398407
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f525 */
+               29936,          /* A1 = -1.827209 */
+                -32584,        /* A2 = 0.994415 */
+                -91,           /* B2 = -0.002806 */
+                0,             /* B1 = 0.000000 */
+                91,            /* B0 = 0.002806 */
+                29921,         /* A1 = -1.826233 */
+                -32688,        /* A2 = 0.997559 */
+                11449,         /* B2 = 0.349396 */
+                -10426,        /* B1 = -0.636383 */
+                11449,         /* B0 = 0.349396 */
+                30045,         /* A1 = -1.833862 */
+                -32688,        /* A2 = 0.997589 */
+                13055,         /* B2 = 0.398407 */
+                -12028,        /* B1 = -0.734161 */
+                13055,         /* B0 = 0.398407 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // f540_660[]
-               28499,          // A1 = 1.739441
-                -31129,        // A2 = -0.949982
-                -849,          // B2 = -0.025922
-                0,             // B1 = 0
-                849,           // B0 = 0.025922
-                28128,         // A1 = 1.716797
-                -32130,        // A2 = -0.98056
-                14556,         // B2 = 0.444214
-                -12251,        // B1 = -0.747772
-                14556,         // B0 = 0.444244
-                29667,         // A1 = 1.81073
-                -32244,        // A2 = -0.984039
-                23038,         // B2 = 0.703064
-                -21358,        // B1 = -1.303589
-                23040,         // B0 = 0.703125
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f540_660[] */
+               28499,          /* A1 = 1.739441 */
+                -31129,        /* A2 = -0.949982 */
+                -849,          /* B2 = -0.025922 */
+                0,             /* B1 = 0 */
+                849,           /* B0 = 0.025922 */
+                28128,         /* A1 = 1.716797 */
+                -32130,        /* A2 = -0.98056 */
+                14556,         /* B2 = 0.444214 */
+                -12251,        /* B1 = -0.747772 */
+                14556,         /* B0 = 0.444244 */
+                29667,         /* A1 = 1.81073 */
+                -32244,        /* A2 = -0.984039 */
+                23038,         /* B2 = 0.703064 */
+                -21358,        /* B1 = -1.303589 */
+                23040,         /* B0 = 0.703125 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 587.txt
-               29271,          // A1 = -1.786560
-                -32599,        // A2 = 0.994873
-                -490,          // B2 = -0.014957
-                0,             // B1 = 0.000000
-                490,           // B0 = 0.014957
-                29246,         // A1 = -1.785095
-                -32700,        // A2 = 0.997925
-                28961,         // B2 = 0.883850
-                -25796,        // B1 = -1.574463
-                28961,         // B0 = 0.883850
-                29383,         // A1 = -1.793396
-                -32700,        // A2 = 0.997955
-                1299,          // B2 = 0.039650
-                -1169,         // B1 = -0.071396
-                1299,          // B0 = 0.039650
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f587 */
+               29271,          /* A1 = -1.786560 */
+                -32599,        /* A2 = 0.994873 */
+                -490,          /* B2 = -0.014957 */
+                0,             /* B1 = 0.000000 */
+                490,           /* B0 = 0.014957 */
+                29246,         /* A1 = -1.785095 */
+                -32700,        /* A2 = 0.997925 */
+                28961,         /* B2 = 0.883850 */
+                -25796,        /* B1 = -1.574463 */
+                28961,         /* B0 = 0.883850 */
+                29383,         /* A1 = -1.793396 */
+                -32700,        /* A2 = 0.997955 */
+                1299,          /* B2 = 0.039650 */
+                -1169,         /* B1 = -0.071396 */
+                1299,          /* B0 = 0.039650 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 590.txt
-               29230,          // A1 = -1.784058
-                -32584,        // A2 = 0.994415
-                -418,          // B2 = -0.012757
-                0,             // B1 = 0.000000
-                418,           // B0 = 0.012757
-                29206,         // A1 = -1.782593
-                -32688,        // A2 = 0.997559
-                36556,         // B2 = 1.115601
-                -32478,        // B1 = -1.982300
-                36556,         // B0 = 1.115601
-                29345,         // A1 = -1.791077
-                -32688,        // A2 = 0.997589
-                897,           // B2 = 0.027397
-                -808,          // B1 = -0.049334
-                897,           // B0 = 0.027397
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f590 */
+               29230,          /* A1 = -1.784058 */
+                -32584,        /* A2 = 0.994415 */
+                -418,          /* B2 = -0.012757 */
+                0,             /* B1 = 0.000000 */
+                418,           /* B0 = 0.012757 */
+                29206,         /* A1 = -1.782593 */
+                -32688,        /* A2 = 0.997559 */
+                36556,         /* B2 = 1.115601 */
+                -32478,        /* B1 = -1.982300 */
+                36556,         /* B0 = 1.115601 */
+                29345,         /* A1 = -1.791077 */
+                -32688,        /* A2 = 0.997589 */
+                897,           /* B2 = 0.027397 */
+                -808,          /* B1 = -0.049334 */
+                897,           /* B0 = 0.027397 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 600.txt
-               29116,          // A1 = -1.777100
-                -32603,        // A2 = 0.994965
-                -165,          // B2 = -0.005039
-                0,             // B1 = 0.000000
-                165,           // B0 = 0.005039
-                29089,         // A1 = -1.775452
-                -32708,        // A2 = 0.998199
-                6963,          // B2 = 0.212494
-                -6172,         // B1 = -0.376770
-                6963,          // B0 = 0.212494
-                29237,         // A1 = -1.784485
-                -32710,        // A2 = 0.998230
-                24197,         // B2 = 0.738464
-                -21657,        // B1 = -1.321899
-                24197,         // B0 = 0.738464
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f600 */
+               29116,          /* A1 = -1.777100 */
+                -32603,        /* A2 = 0.994965 */
+                -165,          /* B2 = -0.005039 */
+                0,             /* B1 = 0.000000 */
+                165,           /* B0 = 0.005039 */
+                29089,         /* A1 = -1.775452 */
+                -32708,        /* A2 = 0.998199 */
+                6963,          /* B2 = 0.212494 */
+                -6172,         /* B1 = -0.376770 */
+                6963,          /* B0 = 0.212494 */
+                29237,         /* A1 = -1.784485 */
+                -32710,        /* A2 = 0.998230 */
+                24197,         /* B2 = 0.738464 */
+                -21657,        /* B1 = -1.321899 */
+                24197,         /* B0 = 0.738464 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 660.txt
-               28376,          // A1 = -1.731934
-                -32567,        // A2 = 0.993896
-                -363,          // B2 = -0.011102
-                0,             // B1 = 0.000000
-                363,           // B0 = 0.011102
-                28337,         // A1 = -1.729614
-                -32683,        // A2 = 0.997434
-                21766,         // B2 = 0.664246
-                -18761,        // B1 = -1.145081
-                21766,         // B0 = 0.664246
-                28513,         // A1 = -1.740356
-                -32686,        // A2 = 0.997498
-                2509,          // B2 = 0.076584
-                -2196,         // B1 = -0.134041
-                2509,          // B0 = 0.076584
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f660 */
+               28376,          /* A1 = -1.731934 */
+                -32567,        /* A2 = 0.993896 */
+                -363,          /* B2 = -0.011102 */
+                0,             /* B1 = 0.000000 */
+                363,           /* B0 = 0.011102 */
+                28337,         /* A1 = -1.729614 */
+                -32683,        /* A2 = 0.997434 */
+                21766,         /* B2 = 0.664246 */
+                -18761,        /* B1 = -1.145081 */
+                21766,         /* B0 = 0.664246 */
+                28513,         /* A1 = -1.740356 */
+                -32686,        /* A2 = 0.997498 */
+                2509,          /* B2 = 0.076584 */
+                -2196,         /* B1 = -0.134041 */
+                2509,          /* B0 = 0.076584 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 700.txt
-               27844,          // A1 = -1.699463
-                -32563,        // A2 = 0.993744
-                -366,          // B2 = -0.011187
-                0,             // B1 = 0.000000
-                366,           // B0 = 0.011187
-                27797,         // A1 = -1.696655
-                -32686,        // A2 = 0.997498
-                22748,         // B2 = 0.694214
-                -19235,        // B1 = -1.174072
-                22748,         // B0 = 0.694214
-                27995,         // A1 = -1.708740
-                -32688,        // A2 = 0.997559
-                2964,          // B2 = 0.090477
-                -2546,         // B1 = -0.155449
-                2964,          // B0 = 0.090477
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f700 */
+               27844,          /* A1 = -1.699463 */
+                -32563,        /* A2 = 0.993744 */
+                -366,          /* B2 = -0.011187 */
+                0,             /* B1 = 0.000000 */
+                366,           /* B0 = 0.011187 */
+                27797,         /* A1 = -1.696655 */
+                -32686,        /* A2 = 0.997498 */
+                22748,         /* B2 = 0.694214 */
+                -19235,        /* B1 = -1.174072 */
+                22748,         /* B0 = 0.694214 */
+                27995,         /* A1 = -1.708740 */
+                -32688,        /* A2 = 0.997559 */
+                2964,          /* B2 = 0.090477 */
+                -2546,         /* B1 = -0.155449 */
+                2964,          /* B0 = 0.090477 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 740.txt
-               27297,          // A1 = -1.666077
-                -32551,        // A2 = 0.993408
-                -345,          // B2 = -0.010540
-                0,             // B1 = 0.000000
-                345,           // B0 = 0.010540
-                27240,         // A1 = -1.662598
-                -32683,        // A2 = 0.997406
-                22560,         // B2 = 0.688477
-                -18688,        // B1 = -1.140625
-                22560,         // B0 = 0.688477
-                27461,         // A1 = -1.676147
-                -32684,        // A2 = 0.997467
-                3541,          // B2 = 0.108086
-                -2985,         // B1 = -0.182220
-                3541,          // B0 = 0.108086
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f740 */
+               27297,          /* A1 = -1.666077 */
+                -32551,        /* A2 = 0.993408 */
+                -345,          /* B2 = -0.010540 */
+                0,             /* B1 = 0.000000 */
+                345,           /* B0 = 0.010540 */
+                27240,         /* A1 = -1.662598 */
+                -32683,        /* A2 = 0.997406 */
+                22560,         /* B2 = 0.688477 */
+                -18688,        /* B1 = -1.140625 */
+                22560,         /* B0 = 0.688477 */
+                27461,         /* A1 = -1.676147 */
+                -32684,        /* A2 = 0.997467 */
+                3541,          /* B2 = 0.108086 */
+                -2985,         /* B1 = -0.182220 */
+                3541,          /* B0 = 0.108086 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 750.txt
-               27155,          // A1 = -1.657410
-                -32551,        // A2 = 0.993408
-                -462,          // B2 = -0.014117
-                0,             // B1 = 0.000000
-                462,           // B0 = 0.014117
-                27097,         // A1 = -1.653870
-                -32683,        // A2 = 0.997406
-                32495,         // B2 = 0.991699
-                -26776,        // B1 = -1.634338
-                32495,         // B0 = 0.991699
-                27321,         // A1 = -1.667542
-                -32684,        // A2 = 0.997467
-                1835,          // B2 = 0.056007
-                -1539,         // B1 = -0.093948
-                1835,          // B0 = 0.056007
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f750 */
+               27155,          /* A1 = -1.657410 */
+                -32551,        /* A2 = 0.993408 */
+                -462,          /* B2 = -0.014117 */
+                0,             /* B1 = 0.000000 */
+                462,           /* B0 = 0.014117 */
+                27097,         /* A1 = -1.653870 */
+                -32683,        /* A2 = 0.997406 */
+                32495,         /* B2 = 0.991699 */
+                -26776,        /* B1 = -1.634338 */
+                32495,         /* B0 = 0.991699 */
+                27321,         /* A1 = -1.667542 */
+                -32684,        /* A2 = 0.997467 */
+                1835,          /* B2 = 0.056007 */
+                -1539,         /* B1 = -0.093948 */
+                1835,          /* B0 = 0.056007 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // f750_1450[]
-               19298,          // A1 = 1.177917
-                -24471,        // A2 = -0.746796
-                -4152,         // B2 = -0.126709
-                0,             // B1 = 0
-                4152,          // B0 = 0.126709
-                12902,         // A1 = 0.787476
-                -29091,        // A2 = -0.887817
-                12491,         // B2 = 0.38121
-                -1794,         // B1 = -0.109528
-                12494,         // B0 = 0.381317
-                26291,         // A1 = 1.604736
-                -30470,        // A2 = -0.929901
-                28859,         // B2 = 0.880737
-                -26084,        // B1 = -1.592102
-                28861,         // B0 = 0.880798
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f750_1450[] */
+               19298,          /* A1 = 1.177917 */
+                -24471,        /* A2 = -0.746796 */
+                -4152,         /* B2 = -0.126709 */
+                0,             /* B1 = 0 */
+                4152,          /* B0 = 0.126709 */
+                12902,         /* A1 = 0.787476 */
+                -29091,        /* A2 = -0.887817 */
+                12491,         /* B2 = 0.38121 */
+                -1794,         /* B1 = -0.109528 */
+                12494,         /* B0 = 0.381317 */
+                26291,         /* A1 = 1.604736 */
+                -30470,        /* A2 = -0.929901 */
+                28859,         /* B2 = 0.880737 */
+                -26084,        /* B1 = -1.592102 */
+                28861,         /* B0 = 0.880798 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 770.txt
-               26867,          // A1 = -1.639832
-                -32551,        // A2 = 0.993408
-                -123,          // B2 = -0.003755
-                0,             // B1 = 0.000000
-                123,           // B0 = 0.003755
-                26805,         // A1 = -1.636108
-                -32683,        // A2 = 0.997406
-                17297,         // B2 = 0.527863
-                -14096,        // B1 = -0.860382
-                17297,         // B0 = 0.527863
-                27034,         // A1 = -1.650085
-                -32684,        // A2 = 0.997467
-                12958,         // B2 = 0.395477
-                -10756,        // B1 = -0.656525
-                12958,         // B0 = 0.395477
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f770 */
+               26867,          /* A1 = -1.639832 */
+                -32551,        /* A2 = 0.993408 */
+                -123,          /* B2 = -0.003755 */
+                0,             /* B1 = 0.000000 */
+                123,           /* B0 = 0.003755 */
+                26805,         /* A1 = -1.636108 */
+                -32683,        /* A2 = 0.997406 */
+                17297,         /* B2 = 0.527863 */
+                -14096,        /* B1 = -0.860382 */
+                17297,         /* B0 = 0.527863 */
+                27034,         /* A1 = -1.650085 */
+                -32684,        /* A2 = 0.997467 */
+                12958,         /* B2 = 0.395477 */
+                -10756,        /* B1 = -0.656525 */
+                12958,         /* B0 = 0.395477 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 800.txt
-               26413,          // A1 = -1.612122
-                -32547,        // A2 = 0.993286
-                -223,          // B2 = -0.006825
-                0,             // B1 = 0.000000
-                223,           // B0 = 0.006825
-                26342,         // A1 = -1.607849
-                -32686,        // A2 = 0.997498
-                6391,          // B2 = 0.195053
-                -5120,         // B1 = -0.312531
-                6391,          // B0 = 0.195053
-                26593,         // A1 = -1.623108
-                -32688,        // A2 = 0.997559
-                23681,         // B2 = 0.722717
-                -19328,        // B1 = -1.179688
-                23681,         // B0 = 0.722717
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f800 */
+               26413,          /* A1 = -1.612122 */
+                -32547,        /* A2 = 0.993286 */
+                -223,          /* B2 = -0.006825 */
+                0,             /* B1 = 0.000000 */
+                223,           /* B0 = 0.006825 */
+                26342,         /* A1 = -1.607849 */
+                -32686,        /* A2 = 0.997498 */
+                6391,          /* B2 = 0.195053 */
+                -5120,         /* B1 = -0.312531 */
+                6391,          /* B0 = 0.195053 */
+                26593,         /* A1 = -1.623108 */
+                -32688,        /* A2 = 0.997559 */
+                23681,         /* B2 = 0.722717 */
+                -19328,        /* B1 = -1.179688 */
+                23681,         /* B0 = 0.722717 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 816.txt
-               26168,          // A1 = -1.597209
-                -32528,        // A2 = 0.992706
-                -235,          // B2 = -0.007182
-                0,             // B1 = 0.000000
-                235,           // B0 = 0.007182
-                26092,         // A1 = -1.592590
-                -32675,        // A2 = 0.997192
-                20823,         // B2 = 0.635498
-                -16510,        // B1 = -1.007751
-                20823,         // B0 = 0.635498
-                26363,         // A1 = -1.609070
-                -32677,        // A2 = 0.997253
-                6739,          // B2 = 0.205688
-                -5459,         // B1 = -0.333206
-                6739,          // B0 = 0.205688
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f816 */
+               26168,          /* A1 = -1.597209 */
+                -32528,        /* A2 = 0.992706 */
+                -235,          /* B2 = -0.007182 */
+                0,             /* B1 = 0.000000 */
+                235,           /* B0 = 0.007182 */
+                26092,         /* A1 = -1.592590 */
+                -32675,        /* A2 = 0.997192 */
+                20823,         /* B2 = 0.635498 */
+                -16510,        /* B1 = -1.007751 */
+                20823,         /* B0 = 0.635498 */
+                26363,         /* A1 = -1.609070 */
+                -32677,        /* A2 = 0.997253 */
+                6739,          /* B2 = 0.205688 */
+                -5459,         /* B1 = -0.333206 */
+                6739,          /* B0 = 0.205688 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 850.txt
-               25641,          // A1 = -1.565063
-                -32536,        // A2 = 0.992950
-                -121,          // B2 = -0.003707
-                0,             // B1 = 0.000000
-                121,           // B0 = 0.003707
-                25560,         // A1 = -1.560059
-                -32684,        // A2 = 0.997437
-                18341,         // B2 = 0.559753
-                -14252,        // B1 = -0.869904
-                18341,         // B0 = 0.559753
-                25837,         // A1 = -1.577026
-                -32684,        // A2 = 0.997467
-                16679,         // B2 = 0.509003
-                -13232,        // B1 = -0.807648
-                16679,         // B0 = 0.509003
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f850 */
+               25641,          /* A1 = -1.565063 */
+                -32536,        /* A2 = 0.992950 */
+                -121,          /* B2 = -0.003707 */
+                0,             /* B1 = 0.000000 */
+                121,           /* B0 = 0.003707 */
+                25560,         /* A1 = -1.560059 */
+                -32684,        /* A2 = 0.997437 */
+                18341,         /* B2 = 0.559753 */
+                -14252,        /* B1 = -0.869904 */
+                18341,         /* B0 = 0.559753 */
+                25837,         /* A1 = -1.577026 */
+                -32684,        /* A2 = 0.997467 */
+                16679,         /* B2 = 0.509003 */
+                -13232,        /* B1 = -0.807648 */
+                16679,         /* B0 = 0.509003 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // f857_1645[]
-               16415,          // A1 = 1.001953
-                -23669,        // A2 = -0.722321
-                -4549,         // B2 = -0.138847
-                0,             // B1 = 0
-                4549,          // B0 = 0.138847
-                8456,          // A1 = 0.516174
-                -28996,        // A2 = -0.884918
-                13753,         // B2 = 0.419724
-                -12,           // B1 = -0.000763
-                13757,         // B0 = 0.419846
-                24632,         // A1 = 1.503418
-                -30271,        // A2 = -0.923828
-                29070,         // B2 = 0.887146
-                -25265,        // B1 = -1.542114
-                29073,         // B0 = 0.887268
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f857_1645[] */
+               16415,          /* A1 = 1.001953 */
+                -23669,        /* A2 = -0.722321 */
+                -4549,         /* B2 = -0.138847 */
+                0,             /* B1 = 0 */
+                4549,          /* B0 = 0.138847 */
+                8456,          /* A1 = 0.516174 */
+                -28996,        /* A2 = -0.884918 */
+                13753,         /* B2 = 0.419724 */
+                -12,           /* B1 = -0.000763 */
+                13757,         /* B0 = 0.419846 */
+                24632,         /* A1 = 1.503418 */
+                -30271,        /* A2 = -0.923828 */
+                29070,         /* B2 = 0.887146 */
+                -25265,        /* B1 = -1.542114 */
+                29073,         /* B0 = 0.887268 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 900.txt
-               24806,          // A1 = -1.514099
-                -32501,        // A2 = 0.991852
-                -326,          // B2 = -0.009969
-                0,             // B1 = 0.000000
-                326,           // B0 = 0.009969
-                24709,         // A1 = -1.508118
-                -32659,        // A2 = 0.996674
-                20277,         // B2 = 0.618835
-                -15182,        // B1 = -0.926636
-                20277,         // B0 = 0.618835
-                25022,         // A1 = -1.527222
-                -32661,        // A2 = 0.996735
-                4320,          // B2 = 0.131836
-                -3331,         // B1 = -0.203339
-                4320,          // B0 = 0.131836
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f900 */
+               24806,          /* A1 = -1.514099 */
+                -32501,        /* A2 = 0.991852 */
+                -326,          /* B2 = -0.009969 */
+                0,             /* B1 = 0.000000 */
+                326,           /* B0 = 0.009969 */
+                24709,         /* A1 = -1.508118 */
+                -32659,        /* A2 = 0.996674 */
+                20277,         /* B2 = 0.618835 */
+                -15182,        /* B1 = -0.926636 */
+                20277,         /* B0 = 0.618835 */
+                25022,         /* A1 = -1.527222 */
+                -32661,        /* A2 = 0.996735 */
+                4320,          /* B2 = 0.131836 */
+                -3331,         /* B1 = -0.203339 */
+                4320,          /* B0 = 0.131836 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // f900_1300[]
-               19776,          // A1 = 1.207092
-                -27437,        // A2 = -0.837341
-                -2666,         // B2 = -0.081371
-                0,             // B1 = 0
-                2666,          // B0 = 0.081371
-                16302,         // A1 = 0.995026
-                -30354,        // A2 = -0.926361
-                10389,         // B2 = 0.317062
-                -3327,         // B1 = -0.203064
-                10389,         // B0 = 0.317062
-                24299,         // A1 = 1.483154
-                -30930,        // A2 = -0.943909
-                25016,         // B2 = 0.763428
-                -21171,        // B1 = -1.292236
-                25016,         // B0 = 0.763428
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f900_1300[] */
+               19776,          /* A1 = 1.207092 */
+                -27437,        /* A2 = -0.837341 */
+                -2666,         /* B2 = -0.081371 */
+                0,             /* B1 = 0 */
+                2666,          /* B0 = 0.081371 */
+                16302,         /* A1 = 0.995026 */
+                -30354,        /* A2 = -0.926361 */
+                10389,         /* B2 = 0.317062 */
+                -3327,         /* B1 = -0.203064 */
+                10389,         /* B0 = 0.317062 */
+                24299,         /* A1 = 1.483154 */
+                -30930,        /* A2 = -0.943909 */
+                25016,         /* B2 = 0.763428 */
+                -21171,        /* B1 = -1.292236 */
+                25016,         /* B0 = 0.763428 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // f935_1215[]
-               20554,          // A1 = 1.254517
-                -28764,        // A2 = -0.877838
-                -2048,         // B2 = -0.062515
-                0,             // B1 = 0
-                2048,          // B0 = 0.062515
-                18209,         // A1 = 1.11145
-                -30951,        // A2 = -0.94458
-                9390,          // B2 = 0.286575
-                -3955,         // B1 = -0.241455
-                9390,          // B0 = 0.286575
-                23902,         // A1 = 1.458923
-                -31286,        // A2 = -0.954803
-                23252,         // B2 = 0.709595
-                -19132,        // B1 = -1.167725
-                23252,         // B0 = 0.709595
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f935_1215[] */
+               20554,          /* A1 = 1.254517 */
+                -28764,        /* A2 = -0.877838 */
+                -2048,         /* B2 = -0.062515 */
+                0,             /* B1 = 0 */
+                2048,          /* B0 = 0.062515 */
+                18209,         /* A1 = 1.11145 */
+                -30951,        /* A2 = -0.94458 */
+                9390,          /* B2 = 0.286575 */
+                -3955,         /* B1 = -0.241455 */
+                9390,          /* B0 = 0.286575 */
+                23902,         /* A1 = 1.458923 */
+                -31286,        /* A2 = -0.954803 */
+                23252,         /* B2 = 0.709595 */
+                -19132,        /* B1 = -1.167725 */
+                23252,         /* B0 = 0.709595 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // f941_1477[]
-               17543,          // A1 = 1.07074
-                -26220,        // A2 = -0.800201
-                -3298,         // B2 = -0.100647
-                0,             // B1 = 0
-                3298,          // B0 = 0.100647
-                12423,         // A1 = 0.75827
-                -30036,        // A2 = -0.916626
-                12651,         // B2 = 0.386078
-                -2444,         // B1 = -0.14917
-                12653,         // B0 = 0.386154
-                23518,         // A1 = 1.435425
-                -30745,        // A2 = -0.938293
-                27282,         // B2 = 0.832581
-                -22529,        // B1 = -1.375122
-                27286,         // B0 = 0.832703
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f941_1477[] */
+               17543,          /* A1 = 1.07074 */
+                -26220,        /* A2 = -0.800201 */
+                -3298,         /* B2 = -0.100647 */
+                0,             /* B1 = 0 */
+                3298,          /* B0 = 0.100647 */
+                12423,         /* A1 = 0.75827 */
+                -30036,        /* A2 = -0.916626 */
+                12651,         /* B2 = 0.386078 */
+                -2444,         /* B1 = -0.14917 */
+                12653,         /* B0 = 0.386154 */
+                23518,         /* A1 = 1.435425 */
+                -30745,        /* A2 = -0.938293 */
+                27282,         /* B2 = 0.832581 */
+                -22529,        /* B1 = -1.375122 */
+                27286,         /* B0 = 0.832703 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 942.txt
-               24104,          // A1 = -1.471252
-                -32507,        // A2 = 0.992065
-                -351,          // B2 = -0.010722
-                0,             // B1 = 0.000000
-                351,           // B0 = 0.010722
-                23996,         // A1 = -1.464600
-                -32671,        // A2 = 0.997040
-                22848,         // B2 = 0.697266
-                -16639,        // B1 = -1.015564
-                22848,         // B0 = 0.697266
-                24332,         // A1 = -1.485168
-                -32673,        // A2 = 0.997101
-                4906,          // B2 = 0.149727
-                -3672,         // B1 = -0.224174
-                4906,          // B0 = 0.149727
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f942 */
+               24104,          /* A1 = -1.471252 */
+                -32507,        /* A2 = 0.992065 */
+                -351,          /* B2 = -0.010722 */
+                0,             /* B1 = 0.000000 */
+                351,           /* B0 = 0.010722 */
+                23996,         /* A1 = -1.464600 */
+                -32671,        /* A2 = 0.997040 */
+                22848,         /* B2 = 0.697266 */
+                -16639,        /* B1 = -1.015564 */
+                22848,         /* B0 = 0.697266 */
+                24332,         /* A1 = -1.485168 */
+                -32673,        /* A2 = 0.997101 */
+                4906,          /* B2 = 0.149727 */
+                -3672,         /* B1 = -0.224174 */
+                4906,          /* B0 = 0.149727 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 950.txt
-               23967,          // A1 = -1.462830
-                -32507,        // A2 = 0.992065
-                -518,          // B2 = -0.015821
-                0,             // B1 = 0.000000
-                518,           // B0 = 0.015821
-                23856,         // A1 = -1.456055
-                -32671,        // A2 = 0.997040
-                26287,         // B2 = 0.802246
-                -19031,        // B1 = -1.161560
-                26287,         // B0 = 0.802246
-                24195,         // A1 = -1.476746
-                -32673,        // A2 = 0.997101
-                2890,          // B2 = 0.088196
-                -2151,         // B1 = -0.131317
-                2890,          // B0 = 0.088196
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f950 */
+               23967,          /* A1 = -1.462830 */
+                -32507,        /* A2 = 0.992065 */
+                -518,          /* B2 = -0.015821 */
+                0,             /* B1 = 0.000000 */
+                518,           /* B0 = 0.015821 */
+                23856,         /* A1 = -1.456055 */
+                -32671,        /* A2 = 0.997040 */
+                26287,         /* B2 = 0.802246 */
+                -19031,        /* B1 = -1.161560 */
+                26287,         /* B0 = 0.802246 */
+                24195,         /* A1 = -1.476746 */
+                -32673,        /* A2 = 0.997101 */
+                2890,          /* B2 = 0.088196 */
+                -2151,         /* B1 = -0.131317 */
+                2890,          /* B0 = 0.088196 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // f950_1400[]
-               18294,          // A1 = 1.116638
-                -26962,        // A2 = -0.822845
-                -2914,         // B2 = -0.088936
-                0,             // B1 = 0
-                2914,          // B0 = 0.088936
-                14119,         // A1 = 0.861786
-                -30227,        // A2 = -0.922455
-                11466,         // B2 = 0.349945
-                -2833,         // B1 = -0.172943
-                11466,         // B0 = 0.349945
-                23431,         // A1 = 1.430115
-                -30828,        // A2 = -0.940796
-                25331,         // B2 = 0.773071
-                -20911,        // B1 = -1.276367
-                25331,         // B0 = 0.773071
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f950_1400[] */
+               18294,          /* A1 = 1.116638 */
+                -26962,        /* A2 = -0.822845 */
+                -2914,         /* B2 = -0.088936 */
+                0,             /* B1 = 0 */
+                2914,          /* B0 = 0.088936 */
+                14119,         /* A1 = 0.861786 */
+                -30227,        /* A2 = -0.922455 */
+                11466,         /* B2 = 0.349945 */
+                -2833,         /* B1 = -0.172943 */
+                11466,         /* B0 = 0.349945 */
+                23431,         /* A1 = 1.430115 */
+                -30828,        /* A2 = -0.940796 */
+                25331,         /* B2 = 0.773071 */
+                -20911,        /* B1 = -1.276367 */
+                25331,         /* B0 = 0.773071 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 975.txt
-               23521,          // A1 = -1.435608
-                -32489,        // A2 = 0.991516
-                -193,          // B2 = -0.005915
-                0,             // B1 = 0.000000
-                193,           // B0 = 0.005915
-                23404,         // A1 = -1.428467
-                -32655,        // A2 = 0.996582
-                17740,         // B2 = 0.541412
-                -12567,        // B1 = -0.767029
-                17740,         // B0 = 0.541412
-                23753,         // A1 = -1.449829
-                -32657,        // A2 = 0.996613
-                9090,          // B2 = 0.277405
-                -6662,         // B1 = -0.406647
-                9090,          // B0 = 0.277405
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f975 */
+               23521,          /* A1 = -1.435608 */
+                -32489,        /* A2 = 0.991516 */
+                -193,          /* B2 = -0.005915 */
+                0,             /* B1 = 0.000000 */
+                193,           /* B0 = 0.005915 */
+                23404,         /* A1 = -1.428467 */
+                -32655,        /* A2 = 0.996582 */
+                17740,         /* B2 = 0.541412 */
+                -12567,        /* B1 = -0.767029 */
+                17740,         /* B0 = 0.541412 */
+                23753,         /* A1 = -1.449829 */
+                -32657,        /* A2 = 0.996613 */
+                9090,          /* B2 = 0.277405 */
+                -6662,         /* B1 = -0.406647 */
+                9090,          /* B0 = 0.277405 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 1000.txt
-               23071,          // A1 = -1.408203
-                -32489,        // A2 = 0.991516
-                -293,          // B2 = -0.008965
-                0,             // B1 = 0.000000
-                293,           // B0 = 0.008965
-                22951,         // A1 = -1.400818
-                -32655,        // A2 = 0.996582
-                5689,          // B2 = 0.173645
-                -3951,         // B1 = -0.241150
-                5689,          // B0 = 0.173645
-                23307,         // A1 = -1.422607
-                -32657,        // A2 = 0.996613
-                18692,         // B2 = 0.570435
-                -13447,        // B1 = -0.820770
-                18692,         // B0 = 0.570435
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f1000 */
+               23071,          /* A1 = -1.408203 */
+                -32489,        /* A2 = 0.991516 */
+                -293,          /* B2 = -0.008965 */
+                0,             /* B1 = 0.000000 */
+                293,           /* B0 = 0.008965 */
+                22951,         /* A1 = -1.400818 */
+                -32655,        /* A2 = 0.996582 */
+                5689,          /* B2 = 0.173645 */
+                -3951,         /* B1 = -0.241150 */
+                5689,          /* B0 = 0.173645 */
+                23307,         /* A1 = -1.422607 */
+                -32657,        /* A2 = 0.996613 */
+                18692,         /* B2 = 0.570435 */
+                -13447,        /* B1 = -0.820770 */
+                18692,         /* B0 = 0.570435 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 1020.txt
-               22701,          // A1 = -1.385620
-                -32474,        // A2 = 0.991058
-                -292,          // B2 = -0.008933
-                0,             //163840      , // B1 = 10.000000
-                292,           // B0 = 0.008933
-                22564,         // A1 = -1.377258
-                -32655,        // A2 = 0.996552
-                20756,         // B2 = 0.633423
-                -14176,        // B1 = -0.865295
-                20756,         // B0 = 0.633423
-                22960,         // A1 = -1.401428
-                -32657,        // A2 = 0.996613
-                6520,          // B2 = 0.198990
-                -4619,         // B1 = -0.281937
-                6520,          // B0 = 0.198990
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f1020 */
+               22701,          /* A1 = -1.385620 */
+                -32474,        /* A2 = 0.991058 */
+                -292,          /* B2 = -0.008933 */
+                0,             /*163840      , B1 = 10.000000 */
+                292,           /* B0 = 0.008933 */
+                22564,         /* A1 = -1.377258 */
+                -32655,        /* A2 = 0.996552 */
+                20756,         /* B2 = 0.633423 */
+                -14176,        /* B1 = -0.865295 */
+                20756,         /* B0 = 0.633423 */
+                22960,         /* A1 = -1.401428 */
+                -32657,        /* A2 = 0.996613 */
+                6520,          /* B2 = 0.198990 */
+                -4619,         /* B1 = -0.281937 */
+                6520,          /* B0 = 0.198990 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 1050.txt
-               22142,          // A1 = -1.351501
-                -32474,        // A2 = 0.991058
-                -147,          // B2 = -0.004493
-                0,             // B1 = 0.000000
-                147,           // B0 = 0.004493
-                22000,         // A1 = -1.342834
-                -32655,        // A2 = 0.996552
-                15379,         // B2 = 0.469360
-                -10237,        // B1 = -0.624847
-                15379,         // B0 = 0.469360
-                22406,         // A1 = -1.367554
-                -32657,        // A2 = 0.996613
-                17491,         // B2 = 0.533783
-                -12096,        // B1 = -0.738312
-                17491,         // B0 = 0.533783
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f1050 */
+               22142,          /* A1 = -1.351501 */
+                -32474,        /* A2 = 0.991058 */
+                -147,          /* B2 = -0.004493 */
+                0,             /* B1 = 0.000000 */
+                147,           /* B0 = 0.004493 */
+                22000,         /* A1 = -1.342834 */
+                -32655,        /* A2 = 0.996552 */
+                15379,         /* B2 = 0.469360 */
+                -10237,        /* B1 = -0.624847 */
+                15379,         /* B0 = 0.469360 */
+                22406,         /* A1 = -1.367554 */
+                -32657,        /* A2 = 0.996613 */
+                17491,         /* B2 = 0.533783 */
+                -12096,        /* B1 = -0.738312 */
+                17491,         /* B0 = 0.533783 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // f1100_1750[]
-               12973,          // A1 = 0.79184
-                -24916,        // A2 = -0.760376
-                6655,          // B2 = 0.203102
-                367,           // B1 = 0.0224
-                6657,          // B0 = 0.203171
-                5915,          // A1 = 0.361053
-                -29560,        // A2 = -0.90213
-                -7777,         // B2 = -0.23735
-                0,             // B1 = 0
-                7777,          // B0 = 0.23735
-                20510,         // A1 = 1.251892
-                -30260,        // A2 = -0.923462
-                26662,         // B2 = 0.81366
-                -20573,        // B1 = -1.255737
-                26668,         // B0 = 0.813843
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f1100_1750[] */
+               12973,          /* A1 = 0.79184 */
+                -24916,        /* A2 = -0.760376 */
+                6655,          /* B2 = 0.203102 */
+                367,           /* B1 = 0.0224 */
+                6657,          /* B0 = 0.203171 */
+                5915,          /* A1 = 0.361053 */
+                -29560,        /* A2 = -0.90213 */
+                -7777,         /* B2 = -0.23735 */
+                0,             /* B1 = 0 */
+                7777,          /* B0 = 0.23735 */
+                20510,         /* A1 = 1.251892 */
+                -30260,        /* A2 = -0.923462 */
+                26662,         /* B2 = 0.81366 */
+                -20573,        /* B1 = -1.255737 */
+                26668,         /* B0 = 0.813843 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 1140.txt
-               20392,          // A1 = -1.244629
-                -32460,        // A2 = 0.990601
-                -270,          // B2 = -0.008240
-                0,             // B1 = 0.000000
-                270,           // B0 = 0.008240
-                20218,         // A1 = -1.234009
-                -32655,        // A2 = 0.996582
-                21337,         // B2 = 0.651154
-                -13044,        // B1 = -0.796143
-                21337,         // B0 = 0.651154
-                20684,         // A1 = -1.262512
-                -32657,        // A2 = 0.996643
-                8572,          // B2 = 0.261612
-                -5476,         // B1 = -0.334244
-                8572,          // B0 = 0.261612
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f1140 */
+               20392,          /* A1 = -1.244629 */
+                -32460,        /* A2 = 0.990601 */
+                -270,          /* B2 = -0.008240 */
+                0,             /* B1 = 0.000000 */
+                270,           /* B0 = 0.008240 */
+                20218,         /* A1 = -1.234009 */
+                -32655,        /* A2 = 0.996582 */
+                21337,         /* B2 = 0.651154 */
+                -13044,        /* B1 = -0.796143 */
+                21337,         /* B0 = 0.651154 */
+                20684,         /* A1 = -1.262512 */
+                -32657,        /* A2 = 0.996643 */
+                8572,          /* B2 = 0.261612 */
+                -5476,         /* B1 = -0.334244 */
+                8572,          /* B0 = 0.261612 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 1200.txt
-               19159,          // A1 = -1.169373
-                -32456,        // A2 = 0.990509
-                -335,          // B2 = -0.010252
-                0,             // B1 = 0.000000
-                335,           // B0 = 0.010252
-                18966,         // A1 = -1.157593
-                -32661,        // A2 = 0.996735
-                6802,          // B2 = 0.207588
-                -3900,         // B1 = -0.238098
-                6802,          // B0 = 0.207588
-                19467,         // A1 = -1.188232
-                -32661,        // A2 = 0.996765
-                25035,         // B2 = 0.764008
-                -15049,        // B1 = -0.918579
-                25035,         // B0 = 0.764008
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f1200 */
+               19159,          /* A1 = -1.169373 */
+                -32456,        /* A2 = 0.990509 */
+                -335,          /* B2 = -0.010252 */
+                0,             /* B1 = 0.000000 */
+                335,           /* B0 = 0.010252 */
+                18966,         /* A1 = -1.157593 */
+                -32661,        /* A2 = 0.996735 */
+                6802,          /* B2 = 0.207588 */
+                -3900,         /* B1 = -0.238098 */
+                6802,          /* B0 = 0.207588 */
+                19467,         /* A1 = -1.188232 */
+                -32661,        /* A2 = 0.996765 */
+                25035,         /* B2 = 0.764008 */
+                -15049,        /* B1 = -0.918579 */
+                25035,         /* B0 = 0.764008 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 1209.txt
-               18976,          // A1 = -1.158264
-                -32439,        // A2 = 0.989990
-                -183,          // B2 = -0.005588
-                0,             // B1 = 0.000000
-                183,           // B0 = 0.005588
-                18774,         // A1 = -1.145874
-                -32650,        // A2 = 0.996429
-                15468,         // B2 = 0.472076
-                -8768,         // B1 = -0.535217
-                15468,         // B0 = 0.472076
-                19300,         // A1 = -1.177979
-                -32652,        // A2 = 0.996490
-                19840,         // B2 = 0.605499
-                -11842,        // B1 = -0.722809
-                19840,         // B0 = 0.605499
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f1209 */
+               18976,          /* A1 = -1.158264 */
+                -32439,        /* A2 = 0.989990 */
+                -183,          /* B2 = -0.005588 */
+                0,             /* B1 = 0.000000 */
+                183,           /* B0 = 0.005588 */
+                18774,         /* A1 = -1.145874 */
+                -32650,        /* A2 = 0.996429 */
+                15468,         /* B2 = 0.472076 */
+                -8768,         /* B1 = -0.535217 */
+                15468,         /* B0 = 0.472076 */
+                19300,         /* A1 = -1.177979 */
+                -32652,        /* A2 = 0.996490 */
+                19840,         /* B2 = 0.605499 */
+                -11842,        /* B1 = -0.722809 */
+                19840,         /* B0 = 0.605499 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 1330.txt
-               16357,          // A1 = -0.998413
-                -32368,        // A2 = 0.987793
-                -217,          // B2 = -0.006652
-                0,             // B1 = 0.000000
-                217,           // B0 = 0.006652
-                16107,         // A1 = -0.983126
-                -32601,        // A2 = 0.994904
-                11602,         // B2 = 0.354065
-                -5555,         // B1 = -0.339111
-                11602,         // B0 = 0.354065
-                16722,         // A1 = -1.020630
-                -32603,        // A2 = 0.994965
-                15574,         // B2 = 0.475311
-                -8176,         // B1 = -0.499069
-                15574,         // B0 = 0.475311
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f1330 */
+               16357,          /* A1 = -0.998413 */
+                -32368,        /* A2 = 0.987793 */
+                -217,          /* B2 = -0.006652 */
+                0,             /* B1 = 0.000000 */
+                217,           /* B0 = 0.006652 */
+                16107,         /* A1 = -0.983126 */
+                -32601,        /* A2 = 0.994904 */
+                11602,         /* B2 = 0.354065 */
+                -5555,         /* B1 = -0.339111 */
+                11602,         /* B0 = 0.354065 */
+                16722,         /* A1 = -1.020630 */
+                -32603,        /* A2 = 0.994965 */
+                15574,         /* B2 = 0.475311 */
+                -8176,         /* B1 = -0.499069 */
+                15574,         /* B0 = 0.475311 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 1336.txt
-               16234,          // A1 = -0.990875
-                32404,         // A2 = -0.988922
-                -193,          // B2 = -0.005908
-                0,             // B1 = 0.000000
-                193,           // B0 = 0.005908
-                15986,         // A1 = -0.975769
-                -32632,        // A2 = 0.995880
-                18051,         // B2 = 0.550903
-                -8658,         // B1 = -0.528473
-                18051,         // B0 = 0.550903
-                16591,         // A1 = -1.012695
-                -32634,        // A2 = 0.995941
-                15736,         // B2 = 0.480240
-                -8125,         // B1 = -0.495926
-                15736,         // B0 = 0.480240
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f1336 */
+               16234,          /* A1 = -0.990875 */
+                32404,         /* A2 = -0.988922 */
+                -193,          /* B2 = -0.005908 */
+                0,             /* B1 = 0.000000 */
+                193,           /* B0 = 0.005908 */
+                15986,         /* A1 = -0.975769 */
+                -32632,        /* A2 = 0.995880 */
+                18051,         /* B2 = 0.550903 */
+                -8658,         /* B1 = -0.528473 */
+                18051,         /* B0 = 0.550903 */
+                16591,         /* A1 = -1.012695 */
+                -32634,        /* A2 = 0.995941 */
+                15736,         /* B2 = 0.480240 */
+                -8125,         /* B1 = -0.495926 */
+                15736,         /* B0 = 0.480240 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 1366.txt
-               15564,          // A1 = -0.949982
-                -32404,        // A2 = 0.988922
-                -269,          // B2 = -0.008216
-                0,             // B1 = 0.000000
-                269,           // B0 = 0.008216
-                15310,         // A1 = -0.934479
-                -32632,        // A2 = 0.995880
-                10815,         // B2 = 0.330063
-                -4962,         // B1 = -0.302887
-                10815,         // B0 = 0.330063
-                15924,         // A1 = -0.971924
-                -32634,        // A2 = 0.995941
-                18880,         // B2 = 0.576172
-                -9364,         // B1 = -0.571594
-                18880,         // B0 = 0.576172
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f1366 */
+               15564,          /* A1 = -0.949982 */
+                -32404,        /* A2 = 0.988922 */
+                -269,          /* B2 = -0.008216 */
+                0,             /* B1 = 0.000000 */
+                269,           /* B0 = 0.008216 */
+                15310,         /* A1 = -0.934479 */
+                -32632,        /* A2 = 0.995880 */
+                10815,         /* B2 = 0.330063 */
+                -4962,         /* B1 = -0.302887 */
+                10815,         /* B0 = 0.330063 */
+                15924,         /* A1 = -0.971924 */
+                -32634,        /* A2 = 0.995941 */
+                18880,         /* B2 = 0.576172 */
+                -9364,         /* B1 = -0.571594 */
+                18880,         /* B0 = 0.576172 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 1380.txt
-               15247,          // A1 = -0.930603
-                -32397,        // A2 = 0.988708
-                -244,          // B2 = -0.007451
-                0,             // B1 = 0.000000
-                244,           // B0 = 0.007451
-                14989,         // A1 = -0.914886
-                -32627,        // A2 = 0.995697
-                18961,         // B2 = 0.578644
-                -8498,         // B1 = -0.518707
-                18961,         // B0 = 0.578644
-                15608,         // A1 = -0.952667
-                -32628,        // A2 = 0.995758
-                11145,         // B2 = 0.340134
-                -5430,         // B1 = -0.331467
-                11145,         // B0 = 0.340134
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f1380 */
+               15247,          /* A1 = -0.930603 */
+                -32397,        /* A2 = 0.988708 */
+                -244,          /* B2 = -0.007451 */
+                0,             /* B1 = 0.000000 */
+                244,           /* B0 = 0.007451 */
+                14989,         /* A1 = -0.914886 */
+                -32627,        /* A2 = 0.995697 */
+                18961,         /* B2 = 0.578644 */
+                -8498,         /* B1 = -0.518707 */
+                18961,         /* B0 = 0.578644 */
+                15608,         /* A1 = -0.952667 */
+                -32628,        /* A2 = 0.995758 */
+                11145,         /* B2 = 0.340134 */
+                -5430,         /* B1 = -0.331467 */
+                11145,         /* B0 = 0.340134 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 1400.txt
-               14780,          // A1 = -0.902130
-                -32393,        // A2 = 0.988586
-                -396,          // B2 = -0.012086
-                0,             // B1 = 0.000000
-                396,           // B0 = 0.012086
-                14510,         // A1 = -0.885651
-                -32630,        // A2 = 0.995819
-                6326,          // B2 = 0.193069
-                -2747,         // B1 = -0.167671
-                6326,          // B0 = 0.193069
-                15154,         // A1 = -0.924957
-                -32632,        // A2 = 0.995850
-                23235,         // B2 = 0.709076
-                -10983,        // B1 = -0.670380
-                23235,         // B0 = 0.709076
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f1400 */
+               14780,          /* A1 = -0.902130 */
+                -32393,        /* A2 = 0.988586 */
+                -396,          /* B2 = -0.012086 */
+                0,             /* B1 = 0.000000 */
+                396,           /* B0 = 0.012086 */
+                14510,         /* A1 = -0.885651 */
+                -32630,        /* A2 = 0.995819 */
+                6326,          /* B2 = 0.193069 */
+                -2747,         /* B1 = -0.167671 */
+                6326,          /* B0 = 0.193069 */
+                15154,         /* A1 = -0.924957 */
+                -32632,        /* A2 = 0.995850 */
+                23235,         /* B2 = 0.709076 */
+                -10983,        /* B1 = -0.670380 */
+                23235,         /* B0 = 0.709076 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 1477.txt
-               13005,          // A1 = -0.793793
-                -32368,        // A2 = 0.987823
-                -500,          // B2 = -0.015265
-                0,             // B1 = 0.000000
-                500,           // B0 = 0.015265
-                12708,         // A1 = -0.775665
-                -32615,        // A2 = 0.995331
-                11420,         // B2 = 0.348526
-                -4306,         // B1 = -0.262833
-                11420,         // B0 = 0.348526
-                13397,         // A1 = -0.817688
-                -32615,        // A2 = 0.995361
-                9454,          // B2 = 0.288528
-                -3981,         // B1 = -0.243027
-                9454,          // B0 = 0.288528
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f1477 */
+               13005,          /* A1 = -0.793793 */
+                -32368,        /* A2 = 0.987823 */
+                -500,          /* B2 = -0.015265 */
+                0,             /* B1 = 0.000000 */
+                500,           /* B0 = 0.015265 */
+                12708,         /* A1 = -0.775665 */
+                -32615,        /* A2 = 0.995331 */
+                11420,         /* B2 = 0.348526 */
+                -4306,         /* B1 = -0.262833 */
+                11420,         /* B0 = 0.348526 */
+                13397,         /* A1 = -0.817688 */
+                -32615,        /* A2 = 0.995361 */
+                9454,          /* B2 = 0.288528 */
+                -3981,         /* B1 = -0.243027 */
+                9454,          /* B0 = 0.288528 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 1600.txt
-               10046,          // A1 = -0.613190
-                -32331,        // A2 = 0.986694
-                -455,          // B2 = -0.013915
-                0,             // B1 = 0.000000
-                455,           // B0 = 0.013915
-                9694,          // A1 = -0.591705
-                -32601,        // A2 = 0.994934
-                6023,          // B2 = 0.183815
-                -1708,         // B1 = -0.104279
-                6023,          // B0 = 0.183815
-                10478,         // A1 = -0.639587
-                -32603,        // A2 = 0.994965
-                22031,         // B2 = 0.672333
-                -7342,         // B1 = -0.448151
-                22031,         // B0 = 0.672333
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f1600 */
+               10046,          /* A1 = -0.613190 */
+                -32331,        /* A2 = 0.986694 */
+                -455,          /* B2 = -0.013915 */
+                0,             /* B1 = 0.000000 */
+                455,           /* B0 = 0.013915 */
+                9694,          /* A1 = -0.591705 */
+                -32601,        /* A2 = 0.994934 */
+                6023,          /* B2 = 0.183815 */
+                -1708,         /* B1 = -0.104279 */
+                6023,          /* B0 = 0.183815 */
+                10478,         /* A1 = -0.639587 */
+                -32603,        /* A2 = 0.994965 */
+                22031,         /* B2 = 0.672333 */
+                -7342,         /* B1 = -0.448151 */
+                22031,         /* B0 = 0.672333 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // f1633_1638[]
-               9181,           // A1 = 0.560394
-                -32256,        // A2 = -0.984375
-                -556,          // B2 = -0.016975
-                0,             // B1 = 0
-                556,           // B0 = 0.016975
-                8757,          // A1 = 0.534515
-                -32574,        // A2 = -0.99408
-                8443,          // B2 = 0.25769
-                -2135,         // B1 = -0.130341
-                8443,          // B0 = 0.25769
-                9691,          // A1 = 0.591522
-                -32574,        // A2 = -0.99411
-                15446,         // B2 = 0.471375
-                -4809,         // B1 = -0.293579
-                15446,         // B0 = 0.471375
-                7,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f1633_1638[] */
+               9181,           /* A1 = 0.560394 */
+                -32256,        /* A2 = -0.984375 */
+                -556,          /* B2 = -0.016975 */
+                0,             /* B1 = 0 */
+                556,           /* B0 = 0.016975 */
+                8757,          /* A1 = 0.534515 */
+                -32574,        /* A2 = -0.99408 */
+                8443,          /* B2 = 0.25769 */
+                -2135,         /* B1 = -0.130341 */
+                8443,          /* B0 = 0.25769 */
+                9691,          /* A1 = 0.591522 */
+                -32574,        /* A2 = -0.99411 */
+                15446,         /* B2 = 0.471375 */
+                -4809,         /* B1 = -0.293579 */
+                15446,         /* B0 = 0.471375 */
+                7,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 1800.txt
-               5076,           // A1 = -0.309875
-                -32304,        // A2 = 0.985840
-                -508,          // B2 = -0.015503
-                0,             // B1 = 0.000000
-                508,           // B0 = 0.015503
-                4646,          // A1 = -0.283600
-                -32605,        // A2 = 0.995026
-                6742,          // B2 = 0.205780
-                -878,          // B1 = -0.053635
-                6742,          // B0 = 0.205780
-                5552,          // A1 = -0.338928
-                -32605,        // A2 = 0.995056
-                23667,         // B2 = 0.722260
-                -4297,         // B1 = -0.262329
-                23667,         // B0 = 0.722260
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f1800 */
+               5076,           /* A1 = -0.309875 */
+                -32304,        /* A2 = 0.985840 */
+                -508,          /* B2 = -0.015503 */
+                0,             /* B1 = 0.000000 */
+                508,           /* B0 = 0.015503 */
+                4646,          /* A1 = -0.283600 */
+                -32605,        /* A2 = 0.995026 */
+                6742,          /* B2 = 0.205780 */
+                -878,          /* B1 = -0.053635 */
+                6742,          /* B0 = 0.205780 */
+                5552,          /* A1 = -0.338928 */
+                -32605,        /* A2 = 0.995056 */
+                23667,         /* B2 = 0.722260 */
+                -4297,         /* B1 = -0.262329 */
+                23667,         /* B0 = 0.722260 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
-       {                       // 1860.txt
-               3569,           // A1 = -0.217865
-                -32292,        // A2 = 0.985504
-                -239,          // B2 = -0.007322
-                0,             // B1 = 0.000000
-                239,           // B0 = 0.007322
-                3117,          // A1 = -0.190277
-                -32603,        // A2 = 0.994965
-                18658,         // B2 = 0.569427
-                -1557,         // B1 = -0.095032
-                18658,         // B0 = 0.569427
-                4054,          // A1 = -0.247437
-                -32603,        // A2 = 0.994965
-                18886,         // B2 = 0.576385
-                -2566,         // B1 = -0.156647
-                18886,         // B0 = 0.576385
-                5,             // Internal filter scaling
-                159,           // Minimum in-band energy threshold
-                21,            // 21/32 in-band to broad-band ratio
-                0x0FF5         // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+       {                       /* f1860 */
+               3569,           /* A1 = -0.217865 */
+                -32292,        /* A2 = 0.985504 */
+                -239,          /* B2 = -0.007322 */
+                0,             /* B1 = 0.000000 */
+                239,           /* B0 = 0.007322 */
+                3117,          /* A1 = -0.190277 */
+                -32603,        /* A2 = 0.994965 */
+                18658,         /* B2 = 0.569427 */
+                -1557,         /* B1 = -0.095032 */
+                18658,         /* B0 = 0.569427 */
+                4054,          /* A1 = -0.247437 */
+                -32603,        /* A2 = 0.994965 */
+                18886,         /* B2 = 0.576385 */
+                -2566,         /* B1 = -0.156647 */
+                18886,         /* B0 = 0.576385 */
+                5,             /* Internal filter scaling */
+                159,           /* Minimum in-band energy threshold */
+                21,            /* 21/32 in-band to broad-band ratio */
+                0x0FF5         /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
        },
 };
 static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf)
@@ -9170,33 +10555,33 @@ static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf)
        if (jf->filter > 3) {
                return -1;
        }
-       if (ixj_WriteDSPCommand(0x5154 + jf->filter, j))        // Select Filter
+       if (ixj_WriteDSPCommand(0x5154 + jf->filter, j))        /* Select Filter */
 
                return -1;
        if (!jf->enable) {
-               if (ixj_WriteDSPCommand(0x5152, j))             // Disable Filter
+               if (ixj_WriteDSPCommand(0x5152, j))             /* Disable Filter */
 
                        return -1;
                else
                        return 0;
        } else {
-               if (ixj_WriteDSPCommand(0x5153, j))             // Enable Filter
+               if (ixj_WriteDSPCommand(0x5153, j))             /* Enable Filter */
 
                        return -1;
-               // Select the filter (f0 - f3) to use.
+               /* Select the filter (f0 - f3) to use. */
                if (ixj_WriteDSPCommand(0x5154 + jf->filter, j))
                        return -1;
        }
        if (jf->freq < 12 && jf->freq > 3) {
-               // Select the frequency for the selected filter.
+               /* Select the frequency for the selected filter. */
                if (ixj_WriteDSPCommand(0x5170 + jf->freq, j))
                        return -1;
        } else if (jf->freq > 11) {
-               // We need to load a programmable filter set for undefined
-               // frequencies.  So we will point the filter to a programmable set.
-               // Since there are only 4 filters and 4 programmable sets, we will
-               // just point the filter to the same number set and program it for the
-               // frequency we want.
+               /* We need to load a programmable filter set for undefined */
+               /* frequencies.  So we will point the filter to a programmable set. */
+               /* Since there are only 4 filters and 4 programmable sets, we will */
+               /* just point the filter to the same number set and program it for the */
+               /* frequency we want. */
                if (ixj_WriteDSPCommand(0x5170 + jf->filter, j))
                        return -1;
                if (j->ver.low != 0x12) {
@@ -9217,6 +10602,52 @@ static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf)
        return 0;
 }
 
+static int ixj_init_filter_raw(IXJ *j, IXJ_FILTER_RAW * jfr)
+{
+       unsigned short cmd;
+       int cnt, max;
+       if (jfr->filter > 3) {
+               return -1;
+       }
+       if (ixj_WriteDSPCommand(0x5154 + jfr->filter, j))       /* Select Filter */
+               return -1;
+
+       if (!jfr->enable) {
+               if (ixj_WriteDSPCommand(0x5152, j))             /* Disable Filter */
+                       return -1;
+               else
+                       return 0;
+       } else {
+               if (ixj_WriteDSPCommand(0x5153, j))             /* Enable Filter */
+                       return -1;
+               /* Select the filter (f0 - f3) to use. */
+               if (ixj_WriteDSPCommand(0x5154 + jfr->filter, j))
+                       return -1;
+       }
+       /* We need to load a programmable filter set for undefined */
+       /* frequencies.  So we will point the filter to a programmable set. */
+       /* Since there are only 4 filters and 4 programmable sets, we will */
+       /* just point the filter to the same number set and program it for the */
+       /* frequency we want. */
+       if (ixj_WriteDSPCommand(0x5170 + jfr->filter, j))
+               return -1;
+       if (j->ver.low != 0x12) {
+               cmd = 0x515B;
+               max = 19;
+       } else {
+               cmd = 0x515E;
+               max = 15;
+       }
+       if (ixj_WriteDSPCommand(cmd, j))
+               return -1;
+       for (cnt = 0; cnt < max; cnt++) {
+               if (ixj_WriteDSPCommand(jfr->coeff[cnt], j))
+                       return -1;
+       }
+       j->filter_en[jfr->filter] = jfr->enable;
+       return 0;
+}
+
 static int ixj_init_tone(IXJ *j, IXJ_TONE * ti)
 {
        int freq0, freq1;
@@ -9237,7 +10668,7 @@ static int ixj_init_tone(IXJ *j, IXJ_TONE * ti)
        {
                if (ixj_WriteDSPCommand(0x6800 + ti->tone_index, j))
                        return -1;
-               if (ixj_WriteDSPCommand(0x6000 + (ti->gain0 << 4) + ti->gain1, j))
+               if (ixj_WriteDSPCommand(0x6000 + (ti->gain1 << 4) + ti->gain0, j))
                        return -1;
                data = freq0;
                if (ixj_WriteDSPCommand(data, j))
@@ -9248,3 +10679,4 @@ static int ixj_init_tone(IXJ *j, IXJ_TONE * ti)
        }
        return freq0;
 }
+
index 43cc9fe436e147e648d8b7a1ba0765390c4968bf..35187c65cd4f989dfe1502fb604f942d517abf71 100644 (file)
@@ -1,10 +1,13 @@
 /******************************************************************************
  *    ixj.h
  *
- *    Device Driver for the Internet PhoneJACK and
- *    Internet LineJACK Telephony Cards.
  *
- *    (c) Copyright 1999 Quicknet Technologies, Inc.
+ * Device Driver for Quicknet Technologies, Inc.'s Telephony cards
+ * including the Internet PhoneJACK, Internet PhoneJACK Lite,
+ * Internet PhoneJACK PCI, Internet LineJACK, Internet PhoneCARD and
+ * SmartCABLE
+ *
+ *    (c) Copyright 1999-2001  Quicknet Technologies, Inc.
  *
  *    This program is free software; you can redistribute it and/or
  *    modify it under the terms of the GNU General Public License
  * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  *
  *****************************************************************************/
-static char ixj_h_rcsid[] = "$Id: ixj.h,v 3.14 2000/03/30 22:06:48 eokerson Exp $";
+static char ixj_h_rcsid[] = "$Id: ixj.h,v 4.1 2001/08/04 14:49:27 craigs Exp $";
 
-#ifndef _I386_TYPES_H
-#include <asm/types.h>
-#endif
+#define IXJ_VERSION 3031
+
+#include <linux/types.h>
 
 #include <linux/ixjuser.h>
 #include <linux/phonedev.h>
@@ -49,11 +52,20 @@ typedef __u32 DWORD;
 typedef __u8 BYTE;
 typedef __u8 BOOL;
 
+#ifndef IXJMAX
 #define IXJMAX 16
+#endif
 
 #define TRUE 1
 #define FALSE 0
 
+#ifndef min
+#define min(a,b) (((a)<(b))?(a):(b))
+#endif
+#ifndef max
+#define max(a,b) (((a)>(b))?(a):(b))
+#endif
+
 /******************************************************************************
 *
 *  This structure when unioned with the structures below makes simple byte
@@ -225,13 +237,13 @@ typedef struct {
        unsigned int led2:1;
        unsigned int led3:1;
        unsigned int led4:1;
-} PSCRWI;                      // Internet LineJACK and Internet PhoneJACK Lite
+} PSCRWI;                      /* Internet LineJACK and Internet PhoneJACK Lite */
 
 typedef struct {
        unsigned int eidp:1;
        unsigned int eisd:1;
        unsigned int x:6;
-} PSCRWP;                      // Internet PhoneJACK PCI
+} PSCRWP;                      /* Internet PhoneJACK PCI */
 
 typedef union {
        PSCRWI bits;
@@ -355,15 +367,15 @@ typedef struct {
 *
 ******************************************************************************/
 typedef struct {
-       unsigned int x0:4;      // unused bits
+       unsigned int x0:4;      /* unused bits */
 
-       unsigned int ed:1;      // Event Detect
+       unsigned int ed:1;      /* Event Detect */
 
-       unsigned int drf:1;     // Smart Cable Removal Flag 1=no cable
+       unsigned int drf:1;     /* SmartCABLE Removal Flag 1=no cable */
 
-       unsigned int dspf:1;    // DSP Flag 1=DSP Ready
+       unsigned int dspf:1;    /* DSP Flag 1=DSP Ready */
 
-       unsigned int crr:1;     // Control Register Ready
+       unsigned int crr:1;     /* Control Register Ready */
 
 } COMMAND_REG1;
 
@@ -373,13 +385,13 @@ typedef union {
 } PCMCIA_CR1;
 
 typedef struct {
-       unsigned int x0:4;      // unused bits
+       unsigned int x0:4;      /* unused bits */
 
-       unsigned int rstc:1;    // Smart Cable Reset
+       unsigned int rstc:1;    /* SmartCABLE Reset */
 
-       unsigned int pwr:1;     // Smart Cable Power
+       unsigned int pwr:1;     /* SmartCABLE Power */
 
-       unsigned int x1:2;      // unused bits
+       unsigned int x1:2;      /* unused bits */
 
 } COMMAND_REG2;
 
@@ -389,11 +401,11 @@ typedef union {
 } PCMCIA_CR2;
 
 typedef struct {
-       unsigned int addr:5;    // R/W Smart Cable Register Address
+       unsigned int addr:5;    /* R/W SmartCABLE Register Address */
 
-       unsigned int rw:1;      // Read / Write flag
+       unsigned int rw:1;      /* Read / Write flag */
 
-       unsigned int dev:2;     // 2 bit Smart Cable Device Address
+       unsigned int dev:2;     /* 2 bit SmartCABLE Device Address */
 
 } CONTROL_REG;
 
@@ -419,19 +431,19 @@ typedef union {
 } PCMCIA_SLIC;
 
 typedef struct {
-       unsigned int cpd:1;     // Chip Power Down
+       unsigned int cpd:1;     /* Chip Power Down */
 
-       unsigned int mpd:1;     // MIC Bias Power Down
+       unsigned int mpd:1;     /* MIC Bias Power Down */
 
-       unsigned int hpd:1;     // Handset Drive Power Down
+       unsigned int hpd:1;     /* Handset Drive Power Down */
 
-       unsigned int lpd:1;     // Line Drive Power Down
+       unsigned int lpd:1;     /* Line Drive Power Down */
 
-       unsigned int spd:1;     // Speaker Drive Power Down
+       unsigned int spd:1;     /* Speaker Drive Power Down */
 
-       unsigned int x:2;       // unused bits
+       unsigned int x:2;       /* unused bits */
 
-       unsigned int sr:1;      // Software Reset
+       unsigned int sr:1;      /* Software Reset */
 
 } Si3CONTROL1;
 
@@ -441,17 +453,17 @@ typedef union {
 } Si3C1;
 
 typedef struct {
-       unsigned int al:1;      // Analog Loopback DAC analog -> ADC analog
+       unsigned int al:1;      /* Analog Loopback DAC analog -> ADC analog */
 
-       unsigned int dl2:1;     // Digital Loopback DAC -> ADC one bit
+       unsigned int dl2:1;     /* Digital Loopback DAC -> ADC one bit */
 
-       unsigned int dl1:1;     // Digital Loopback ADC -> DAC one bit
+       unsigned int dl1:1;     /* Digital Loopback ADC -> DAC one bit */
 
-       unsigned int pll:1;     // 1 = div 10, 0 = div 5
+       unsigned int pll:1;     /* 1 = div 10, 0 = div 5 */
 
-       unsigned int hpd:1;     // HPF disable
+       unsigned int hpd:1;     /* HPF disable */
 
-       unsigned int x:3;       // unused bits
+       unsigned int x:3;       /* unused bits */
 
 } Si3CONTROL2;
 
@@ -461,17 +473,17 @@ typedef union {
 } Si3C2;
 
 typedef struct {
-       unsigned int iir:1;     // 1 enables IIR, 0 enables FIR
+       unsigned int iir:1;     /* 1 enables IIR, 0 enables FIR */
 
-       unsigned int him:1;     // Handset Input Mute
+       unsigned int him:1;     /* Handset Input Mute */
 
-       unsigned int mcm:1;     // MIC In Mute
+       unsigned int mcm:1;     /* MIC In Mute */
 
-       unsigned int mcg:2;     // MIC In Gain
+       unsigned int mcg:2;     /* MIC In Gain */
 
-       unsigned int lim:1;     // Line In Mute
+       unsigned int lim:1;     /* Line In Mute */
 
-       unsigned int lig:2;     // Line In Gain
+       unsigned int lig:2;     /* Line In Gain */
 
 } Si3RXGAIN;
 
@@ -481,13 +493,13 @@ typedef union {
 } Si3RXG;
 
 typedef struct {
-       unsigned int hom:1;     // Handset Out Mute
+       unsigned int hom:1;     /* Handset Out Mute */
 
-       unsigned int lom:1;     // Line Out Mute
+       unsigned int lom:1;     /* Line Out Mute */
 
-       unsigned int rxg:5;     // RX PGA Gain
+       unsigned int rxg:5;     /* RX PGA Gain */
 
-       unsigned int x:1;       // unused bit
+       unsigned int x:1;       /* unused bit */
 
 } Si3ADCVOLUME;
 
@@ -497,13 +509,13 @@ typedef union {
 } Si3ADC;
 
 typedef struct {
-       unsigned int srm:1;     // Speaker Right Mute
+       unsigned int srm:1;     /* Speaker Right Mute */
 
-       unsigned int slm:1;     // Speaker Left Mute
+       unsigned int slm:1;     /* Speaker Left Mute */
 
-       unsigned int txg:5;     // TX PGA Gain
+       unsigned int txg:5;     /* TX PGA Gain */
 
-       unsigned int x:1;       // unused bit
+       unsigned int x:1;       /* unused bit */
 
 } Si3DACVOLUME;
 
@@ -513,13 +525,13 @@ typedef union {
 } Si3DAC;
 
 typedef struct {
-       unsigned int x:5;       // unused bit
+       unsigned int x:5;       /* unused bit */
 
-       unsigned int losc:1;    // Line Out Short Circuit
+       unsigned int losc:1;    /* Line Out Short Circuit */
 
-       unsigned int srsc:1;    // Speaker Right Short Circuit
+       unsigned int srsc:1;    /* Speaker Right Short Circuit */
 
-       unsigned int slsc:1;    // Speaker Left Short Circuit
+       unsigned int slsc:1;    /* Speaker Left Short Circuit */
 
 } Si3STATUSREPORT;
 
@@ -529,11 +541,11 @@ typedef union {
 } Si3STAT;
 
 typedef struct {
-       unsigned int sot:2;     // Speaker Out Attenuation
+       unsigned int sot:2;     /* Speaker Out Attenuation */
 
-       unsigned int lot:2;     // Line Out Attenuation
+       unsigned int lot:2;     /* Line Out Attenuation */
 
-       unsigned int x:4;       // unused bits
+       unsigned int x:4;       /* unused bits */
 
 } Si3ANALOGATTN;
 
@@ -549,149 +561,149 @@ typedef union {
 ******************************************************************************/
 
 typedef struct _DAA_REGS {
-       //-----------------------------------------------
-       // SOP Registers
-       //
+       /*----------------------------------------------- */
+       /* SOP Registers */
+       /* */
        BYTE bySOP;
 
        union _SOP_REGS {
                struct _SOP {
-                       union   // SOP - CR0 Register
+                       union   /* SOP - CR0 Register */
                         {
                                BYTE reg;
                                struct _CR0_BITREGS {
-                                       BYTE CLK_EXT:1;         // cr0[0:0]
+                                       BYTE CLK_EXT:1;         /* cr0[0:0] */
 
-                                       BYTE RIP:1;     // cr0[1:1]
+                                       BYTE RIP:1;     /* cr0[1:1] */
 
-                                       BYTE AR:1;      // cr0[2:2]
+                                       BYTE AR:1;      /* cr0[2:2] */
 
-                                       BYTE AX:1;      // cr0[3:3]
+                                       BYTE AX:1;      /* cr0[3:3] */
 
-                                       BYTE FRR:1;     // cr0[4:4]
+                                       BYTE FRR:1;     /* cr0[4:4] */
 
-                                       BYTE FRX:1;     // cr0[5:5]
+                                       BYTE FRX:1;     /* cr0[5:5] */
 
-                                       BYTE IM:1;      // cr0[6:6]
+                                       BYTE IM:1;      /* cr0[6:6] */
 
-                                       BYTE TH:1;      // cr0[7:7]
+                                       BYTE TH:1;      /* cr0[7:7] */
 
                                } bitreg;
                        } cr0;
 
-                       union   // SOP - CR1 Register
+                       union   /* SOP - CR1 Register */
                         {
                                BYTE reg;
                                struct _CR1_REGS {
-                                       BYTE RM:1;      // cr1[0:0]
+                                       BYTE RM:1;      /* cr1[0:0] */
 
-                                       BYTE RMR:1;     // cr1[1:1]
+                                       BYTE RMR:1;     /* cr1[1:1] */
 
-                                       BYTE No_auto:1;         // cr1[2:2]
+                                       BYTE No_auto:1;         /* cr1[2:2] */
 
-                                       BYTE Pulse:1;   // cr1[3:3]
+                                       BYTE Pulse:1;   /* cr1[3:3] */
 
-                                       BYTE P_Tone1:1;         // cr1[4:4]
+                                       BYTE P_Tone1:1;         /* cr1[4:4] */
 
-                                       BYTE P_Tone2:1;         // cr1[5:5]
+                                       BYTE P_Tone2:1;         /* cr1[5:5] */
 
-                                       BYTE E_Tone1:1;         // cr1[6:6]
+                                       BYTE E_Tone1:1;         /* cr1[6:6] */
 
-                                       BYTE E_Tone2:1;         // cr1[7:7]
+                                       BYTE E_Tone2:1;         /* cr1[7:7] */
 
                                } bitreg;
                        } cr1;
 
-                       union   // SOP - CR2 Register
+                       union   /* SOP - CR2 Register */
                         {
                                BYTE reg;
                                struct _CR2_REGS {
-                                       BYTE Call_II:1;         // CR2[0:0]
+                                       BYTE Call_II:1;         /* CR2[0:0] */
 
-                                       BYTE Call_I:1;  // CR2[1:1]
+                                       BYTE Call_I:1;  /* CR2[1:1] */
 
-                                       BYTE Call_en:1;         // CR2[2:2]
+                                       BYTE Call_en:1;         /* CR2[2:2] */
 
-                                       BYTE Call_pon:1;        // CR2[3:3]
+                                       BYTE Call_pon:1;        /* CR2[3:3] */
 
-                                       BYTE IDR:1;     // CR2[4:4]
+                                       BYTE IDR:1;     /* CR2[4:4] */
 
-                                       BYTE COT_R:3;   // CR2[5:7]
+                                       BYTE COT_R:3;   /* CR2[5:7] */
 
                                } bitreg;
                        } cr2;
 
-                       union   // SOP - CR3 Register
+                       union   /* SOP - CR3 Register */
                         {
                                BYTE reg;
                                struct _CR3_REGS {
-                                       BYTE DHP_X:1;   // CR3[0:0]
+                                       BYTE DHP_X:1;   /* CR3[0:0] */
 
-                                       BYTE DHP_R:1;   // CR3[1:1]
+                                       BYTE DHP_R:1;   /* CR3[1:1] */
 
-                                       BYTE Cal_pctl:1;        // CR3[2:2]
+                                       BYTE Cal_pctl:1;        /* CR3[2:2] */
 
-                                       BYTE SEL:1;     // CR3[3:3]
+                                       BYTE SEL:1;     /* CR3[3:3] */
 
-                                       BYTE TestLoops:4;       // CR3[4:7]
+                                       BYTE TestLoops:4;       /* CR3[4:7] */
 
                                } bitreg;
                        } cr3;
 
-                       union   // SOP - CR4 Register
+                       union   /* SOP - CR4 Register */
                         {
                                BYTE reg;
                                struct _CR4_REGS {
-                                       BYTE Fsc_en:1;  // CR4[0:0]
+                                       BYTE Fsc_en:1;  /* CR4[0:0] */
 
-                                       BYTE Int_en:1;  // CR4[1:1]
+                                       BYTE Int_en:1;  /* CR4[1:1] */
 
-                                       BYTE AGX:2;     // CR4[2:3]
+                                       BYTE AGX:2;     /* CR4[2:3] */
 
-                                       BYTE AGR_R:2;   // CR4[4:5]
+                                       BYTE AGR_R:2;   /* CR4[4:5] */
 
-                                       BYTE AGR_Z:2;   // CR4[6:7]
+                                       BYTE AGR_Z:2;   /* CR4[6:7] */
 
                                } bitreg;
                        } cr4;
 
-                       union   // SOP - CR5 Register
+                       union   /* SOP - CR5 Register */
                         {
                                BYTE reg;
                                struct _CR5_REGS {
-                                       BYTE V_0:1;     // CR5[0:0]
+                                       BYTE V_0:1;     /* CR5[0:0] */
 
-                                       BYTE V_1:1;     // CR5[1:1]
+                                       BYTE V_1:1;     /* CR5[1:1] */
 
-                                       BYTE V_2:1;     // CR5[2:2]
+                                       BYTE V_2:1;     /* CR5[2:2] */
 
-                                       BYTE V_3:1;     // CR5[3:3]
+                                       BYTE V_3:1;     /* CR5[3:3] */
 
-                                       BYTE V_4:1;     // CR5[4:4]
+                                       BYTE V_4:1;     /* CR5[4:4] */
 
-                                       BYTE V_5:1;     // CR5[5:5]
+                                       BYTE V_5:1;     /* CR5[5:5] */
 
-                                       BYTE V_6:1;     // CR5[6:6]
+                                       BYTE V_6:1;     /* CR5[6:6] */
 
-                                       BYTE V_7:1;     // CR5[7:7]
+                                       BYTE V_7:1;     /* CR5[7:7] */
 
                                } bitreg;
                        } cr5;
 
-                       union   // SOP - CR6 Register
+                       union   /* SOP - CR6 Register */
                         {
                                BYTE reg;
                                struct _CR6_REGS {
-                                       BYTE reserved:8;        // CR6[0:7]
+                                       BYTE reserved:8;        /* CR6[0:7] */
 
                                } bitreg;
                        } cr6;
 
-                       union   // SOP - CR7 Register
+                       union   /* SOP - CR7 Register */
                         {
                                BYTE reg;
                                struct _CR7_REGS {
-                                       BYTE reserved:8;        // CR7[0:7]
+                                       BYTE reserved:8;        /* CR7[0:7] */
 
                                } bitreg;
                        } cr7;
@@ -701,184 +713,184 @@ typedef struct _DAA_REGS {
 
        } SOP_REGS;
 
-       // DAA_REGS.SOP_REGS.SOP.CR5.reg
-       // DAA_REGS.SOP_REGS.SOP.CR5.bitreg
-       // DAA_REGS.SOP_REGS.SOP.CR5.bitreg.V_2
-       // DAA_REGS.SOP_REGS.ByteRegs[5]
+       /* DAA_REGS.SOP_REGS.SOP.CR5.reg */
+       /* DAA_REGS.SOP_REGS.SOP.CR5.bitreg */
+       /* DAA_REGS.SOP_REGS.SOP.CR5.bitreg.V_2 */
+       /* DAA_REGS.SOP_REGS.ByteRegs[5] */
 
-       //-----------------------------------------------
-       // XOP Registers
-       //
+       /*----------------------------------------------- */
+       /* XOP Registers */
+       /* */
        BYTE byXOP;
 
        union _XOP_REGS {
                struct _XOP {
-                       union   // XOP - XR0 Register - Read values
+                       union   XOPXR0/* XOP - XR0 Register - Read values */
                         {
                                BYTE reg;
                                struct _XR0_BITREGS {
-                                       BYTE SI_0:1;    // XR0[0:0] - Read
+                                       BYTE SI_0:1;    /* XR0[0:0] - Read */
 
-                                       BYTE SI_1:1;    // XR0[1:1] - Read
+                                       BYTE SI_1:1;    /* XR0[1:1] - Read */
 
-                                       BYTE VDD_OK:1;  // XR0[2:2] - Read
+                                       BYTE VDD_OK:1;  /* XR0[2:2] - Read */
 
-                                       BYTE Caller_ID:1;       // XR0[3:3] - Read
+                                       BYTE Caller_ID:1;       /* XR0[3:3] - Read */
 
-                                       BYTE RING:1;    // XR0[4:4] - Read
+                                       BYTE RING:1;    /* XR0[4:4] - Read */
 
-                                       BYTE Cadence:1;         // XR0[5:5] - Read
+                                       BYTE Cadence:1;         /* XR0[5:5] - Read */
 
-                                       BYTE Wake_up:1;         // XR0[6:6] - Read
+                                       BYTE Wake_up:1;         /* XR0[6:6] - Read */
 
-                                       BYTE unused:1;  // XR0[7:7] - Read
+                                       BYTE RMR:1;     /* XR0[7:7] - Read */
 
                                } bitreg;
                        } xr0;
 
-                       union   // XOP - XR1 Register
+                       union   /* XOP - XR1 Register */
                         {
                                BYTE reg;
                                struct _XR1_BITREGS {
-                                       BYTE M_SI_0:1;  // XR1[0:0]
+                                       BYTE M_SI_0:1;  /* XR1[0:0] */
 
-                                       BYTE M_SI_1:1;  // XR1[1:1]
+                                       BYTE M_SI_1:1;  /* XR1[1:1] */
 
-                                       BYTE M_VDD_OK:1;        // XR1[2:2]
+                                       BYTE M_VDD_OK:1;        /* XR1[2:2] */
 
-                                       BYTE M_Caller_ID:1;     // XR1[3:3]
+                                       BYTE M_Caller_ID:1;     /* XR1[3:3] */
 
-                                       BYTE M_RING:1;  // XR1[4:4]
+                                       BYTE M_RING:1;  /* XR1[4:4] */
 
-                                       BYTE M_Cadence:1;       // XR1[5:5]
+                                       BYTE M_Cadence:1;       /* XR1[5:5] */
 
-                                       BYTE M_Wake_up:1;       // XR1[6:6]
+                                       BYTE M_Wake_up:1;       /* XR1[6:6] */
 
-                                       BYTE unused:1;  // XR1[7:7]
+                                       BYTE unused:1;  /* XR1[7:7] */
 
                                } bitreg;
                        } xr1;
 
-                       union   // XOP - XR2 Register
+                       union   /* XOP - XR2 Register */
                         {
                                BYTE reg;
                                struct _XR2_BITREGS {
-                                       BYTE CTO0:1;    // XR2[0:0]
+                                       BYTE CTO0:1;    /* XR2[0:0] */
 
-                                       BYTE CTO1:1;    // XR2[1:1]
+                                       BYTE CTO1:1;    /* XR2[1:1] */
 
-                                       BYTE CTO2:1;    // XR2[2:2]
+                                       BYTE CTO2:1;    /* XR2[2:2] */
 
-                                       BYTE CTO3:1;    // XR2[3:3]
+                                       BYTE CTO3:1;    /* XR2[3:3] */
 
-                                       BYTE CTO4:1;    // XR2[4:4]
+                                       BYTE CTO4:1;    /* XR2[4:4] */
 
-                                       BYTE CTO5:1;    // XR2[5:5]
+                                       BYTE CTO5:1;    /* XR2[5:5] */
 
-                                       BYTE CTO6:1;    // XR2[6:6]
+                                       BYTE CTO6:1;    /* XR2[6:6] */
 
-                                       BYTE CTO7:1;    // XR2[7:7]
+                                       BYTE CTO7:1;    /* XR2[7:7] */
 
                                } bitreg;
                        } xr2;
 
-                       union   // XOP - XR3 Register
+                       union   /* XOP - XR3 Register */
                         {
                                BYTE reg;
                                struct _XR3_BITREGS {
-                                       BYTE DCR0:1;    // XR3[0:0]
+                                       BYTE DCR0:1;    /* XR3[0:0] */
 
-                                       BYTE DCR1:1;    // XR3[1:1]
+                                       BYTE DCR1:1;    /* XR3[1:1] */
 
-                                       BYTE DCI:1;     // XR3[2:2]
+                                       BYTE DCI:1;     /* XR3[2:2] */
 
-                                       BYTE DCU0:1;    // XR3[3:3]
+                                       BYTE DCU0:1;    /* XR3[3:3] */
 
-                                       BYTE DCU1:1;    // XR3[4:4]
+                                       BYTE DCU1:1;    /* XR3[4:4] */
 
-                                       BYTE B_off:1;   // XR3[5:5]
+                                       BYTE B_off:1;   /* XR3[5:5] */
 
-                                       BYTE AGB0:1;    // XR3[6:6]
+                                       BYTE AGB0:1;    /* XR3[6:6] */
 
-                                       BYTE AGB1:1;    // XR3[7:7]
+                                       BYTE AGB1:1;    /* XR3[7:7] */
 
                                } bitreg;
                        } xr3;
 
-                       union   // XOP - XR4 Register
+                       union   /* XOP - XR4 Register */
                         {
                                BYTE reg;
                                struct _XR4_BITREGS {
-                                       BYTE C_0:1;     // XR4[0:0]
+                                       BYTE C_0:1;     /* XR4[0:0] */
 
-                                       BYTE C_1:1;     // XR4[1:1]
+                                       BYTE C_1:1;     /* XR4[1:1] */
 
-                                       BYTE C_2:1;     // XR4[2:2]
+                                       BYTE C_2:1;     /* XR4[2:2] */
 
-                                       BYTE C_3:1;     // XR4[3:3]
+                                       BYTE C_3:1;     /* XR4[3:3] */
 
-                                       BYTE C_4:1;     // XR4[4:4]
+                                       BYTE C_4:1;     /* XR4[4:4] */
 
-                                       BYTE C_5:1;     // XR4[5:5]
+                                       BYTE C_5:1;     /* XR4[5:5] */
 
-                                       BYTE C_6:1;     // XR4[6:6]
+                                       BYTE C_6:1;     /* XR4[6:6] */
 
-                                       BYTE C_7:1;     // XR4[7:7]
+                                       BYTE C_7:1;     /* XR4[7:7] */
 
                                } bitreg;
                        } xr4;
 
-                       union   // XOP - XR5 Register
+                       union   /* XOP - XR5 Register */
                         {
                                BYTE reg;
                                struct _XR5_BITREGS {
-                                       BYTE T_0:1;     // XR5[0:0]
+                                       BYTE T_0:1;     /* XR5[0:0] */
 
-                                       BYTE T_1:1;     // XR5[1:1]
+                                       BYTE T_1:1;     /* XR5[1:1] */
 
-                                       BYTE T_2:1;     // XR5[2:2]
+                                       BYTE T_2:1;     /* XR5[2:2] */
 
-                                       BYTE T_3:1;     // XR5[3:3]
+                                       BYTE T_3:1;     /* XR5[3:3] */
 
-                                       BYTE T_4:1;     // XR5[4:4]
+                                       BYTE T_4:1;     /* XR5[4:4] */
 
-                                       BYTE T_5:1;     // XR5[5:5]
+                                       BYTE T_5:1;     /* XR5[5:5] */
 
-                                       BYTE T_6:1;     // XR5[6:6]
+                                       BYTE T_6:1;     /* XR5[6:6] */
 
-                                       BYTE T_7:1;     // XR5[7:7]
+                                       BYTE T_7:1;     /* XR5[7:7] */
 
                                } bitreg;
                        } xr5;
 
-                       union   // XOP - XR6 Register - Read Values
+                       union   /* XOP - XR6 Register - Read Values */
                         {
                                BYTE reg;
                                struct _XR6_BITREGS {
-                                       BYTE CPS0:1;    // XR6[0:0]
+                                       BYTE CPS0:1;    /* XR6[0:0] */
 
-                                       BYTE CPS1:1;    // XR6[1:1]
+                                       BYTE CPS1:1;    /* XR6[1:1] */
 
-                                       BYTE unused1:2;         // XR6[2:3]
+                                       BYTE unused1:2;         /* XR6[2:3] */
 
-                                       BYTE CLK_OFF:1;         // XR6[4:4]
+                                       BYTE CLK_OFF:1;         /* XR6[4:4] */
 
-                                       BYTE unused2:3;         // XR6[5:7]
+                                       BYTE unused2:3;         /* XR6[5:7] */
 
                                } bitreg;
                        } xr6;
 
-                       union   // XOP - XR7 Register
+                       union   /* XOP - XR7 Register */
                         {
                                BYTE reg;
                                struct _XR7_BITREGS {
-                                       BYTE unused1:1;         // XR7[0:0]
+                                       BYTE unused1:1;         /* XR7[0:0] */
 
-                                       BYTE Vdd0:1;    // XR7[1:1]
+                                       BYTE Vdd0:1;    /* XR7[1:1] */
 
-                                       BYTE Vdd1:1;    // XR7[2:2]
+                                       BYTE Vdd1:1;    /* XR7[2:2] */
 
-                                       BYTE unused2:5;         // XR7[3:7]
+                                       BYTE unused2:5;         /* XR7[3:7] */
 
                                } bitreg;
                        } xr7;
@@ -888,49 +900,49 @@ typedef struct _DAA_REGS {
 
        } XOP_REGS;
 
-       // DAA_REGS.XOP_REGS.XOP.XR7.reg
-       // DAA_REGS.XOP_REGS.XOP.XR7.bitreg
-       // DAA_REGS.XOP_REGS.XOP.XR7.bitreg.Vdd0
-       // DAA_REGS.XOP_REGS.ByteRegs[7]
+       /* DAA_REGS.XOP_REGS.XOP.XR7.reg */
+       /* DAA_REGS.XOP_REGS.XOP.XR7.bitreg */
+       /* DAA_REGS.XOP_REGS.XOP.XR7.bitreg.Vdd0 */
+       /* DAA_REGS.XOP_REGS.ByteRegs[7] */
 
-       //-----------------------------------------------
-       // COP Registers
-       //
+       /*----------------------------------------------- */
+       /* COP Registers */
+       /* */
        BYTE byCOP;
 
        union _COP_REGS {
                struct _COP {
-                       BYTE THFilterCoeff_1[8];        // COP - TH Filter Coefficients,      CODE=0, Part 1
+                       BYTE THFilterCoeff_1[8];        /* COP - TH Filter Coefficients,      CODE=0, Part 1 */
 
-                       BYTE THFilterCoeff_2[8];        // COP - TH Filter Coefficients,      CODE=1, Part 2
+                       BYTE THFilterCoeff_2[8];        /* COP - TH Filter Coefficients,      CODE=1, Part 2 */
 
-                       BYTE THFilterCoeff_3[8];        // COP - TH Filter Coefficients,      CODE=2, Part 3
+                       BYTE THFilterCoeff_3[8];        /* COP - TH Filter Coefficients,      CODE=2, Part 3 */
 
-                       BYTE RingerImpendance_1[8];     // COP - Ringer Impendance Coefficients,  CODE=3, Part 1
+                       BYTE RingerImpendance_1[8];     /* COP - Ringer Impendance Coefficients,  CODE=3, Part 1 */
 
-                       BYTE IMFilterCoeff_1[8];        // COP - IM Filter Coefficients,      CODE=4, Part 1
+                       BYTE IMFilterCoeff_1[8];        /* COP - IM Filter Coefficients,      CODE=4, Part 1 */
 
-                       BYTE IMFilterCoeff_2[8];        // COP - IM Filter Coefficients,      CODE=5, Part 2
+                       BYTE IMFilterCoeff_2[8];        /* COP - IM Filter Coefficients,      CODE=5, Part 2 */
 
-                       BYTE RingerImpendance_2[8];     // COP - Ringer Impendance Coefficients,  CODE=6, Part 2
+                       BYTE RingerImpendance_2[8];     /* COP - Ringer Impendance Coefficients,  CODE=6, Part 2 */
 
-                       BYTE FRRFilterCoeff[8];         // COP - FRR Filter Coefficients,      CODE=7
+                       BYTE FRRFilterCoeff[8];         /* COP - FRR Filter Coefficients,      CODE=7 */
 
-                       BYTE FRXFilterCoeff[8];         // COP - FRX Filter Coefficients,      CODE=8
+                       BYTE FRXFilterCoeff[8];         /* COP - FRX Filter Coefficients,      CODE=8 */
 
-                       BYTE ARFilterCoeff[4];  // COP - AR Filter Coefficients,      CODE=9
+                       BYTE ARFilterCoeff[4];  /* COP - AR Filter Coefficients,      CODE=9 */
 
-                       BYTE AXFilterCoeff[4];  // COP - AX Filter Coefficients,      CODE=10 
+                       BYTE AXFilterCoeff[4];  /* COP - AX Filter Coefficients,      CODE=10  */
 
-                       BYTE Tone1Coeff[4];     // COP - Tone1 Coefficients,        CODE=11
+                       BYTE Tone1Coeff[4];     /* COP - Tone1 Coefficients,        CODE=11 */
 
-                       BYTE Tone2Coeff[4];     // COP - Tone2 Coefficients,        CODE=12
+                       BYTE Tone2Coeff[4];     /* COP - Tone2 Coefficients,        CODE=12 */
 
-                       BYTE LevelmeteringRinging[4];   // COP - Levelmetering Ringing,        CODE=13
+                       BYTE LevelmeteringRinging[4];   /* COP - Levelmetering Ringing,        CODE=13 */
 
-                       BYTE CallerID1stTone[8];        // COP - Caller ID 1st Tone,        CODE=14
+                       BYTE CallerID1stTone[8];        /* COP - Caller ID 1st Tone,        CODE=14 */
 
-                       BYTE CallerID2ndTone[8];        // COP - Caller ID 2nd Tone,        CODE=15
+                       BYTE CallerID2ndTone[8];        /* COP - Caller ID 2nd Tone,        CODE=15 */
 
                } COP;
 
@@ -938,49 +950,49 @@ typedef struct _DAA_REGS {
 
        } COP_REGS;
 
-       // DAA_REGS.COP_REGS.COP.XR7.Tone1Coeff[3]
-       // DAA_REGS.COP_REGS.COP.XR7.bitreg
-       // DAA_REGS.COP_REGS.COP.XR7.bitreg.Vdd0
-       // DAA_REGS.COP_REGS.ByteRegs[57]
+       /* DAA_REGS.COP_REGS.COP.XR7.Tone1Coeff[3] */
+       /* DAA_REGS.COP_REGS.COP.XR7.bitreg */
+       /* DAA_REGS.COP_REGS.COP.XR7.bitreg.Vdd0 */
+       /* DAA_REGS.COP_REGS.ByteRegs[57] */
 
-       //-----------------------------------------------
-       // CAO Registers
-       //
+       /*----------------------------------------------- */
+       /* CAO Registers */
+       /* */
        BYTE byCAO;
 
        union _CAO_REGS {
                struct _CAO {
-                       BYTE CallerID[512];     // CAO - Caller ID Bytes
+                       BYTE CallerID[512];     /* CAO - Caller ID Bytes */
 
                } CAO;
 
                BYTE ByteRegs[sizeof(struct _CAO)];
        } CAO_REGS;
 
-       union                   // XOP - XR0 Register - Write values
+       union                   /* XOP - XR0 Register - Write values */
         {
                BYTE reg;
                struct _XR0_BITREGSW {
-                       BYTE SO_0:1;    // XR1[0:0] - Write
+                       BYTE SO_0:1;    /* XR1[0:0] - Write */
 
-                       BYTE SO_1:1;    // XR1[1:1] - Write
+                       BYTE SO_1:1;    /* XR1[1:1] - Write */
 
-                       BYTE SO_2:1;    // XR1[2:2] - Write
+                       BYTE SO_2:1;    /* XR1[2:2] - Write */
 
-                       BYTE unused:5;  // XR1[3:7] - Write
+                       BYTE unused:5;  /* XR1[3:7] - Write */
 
                } bitreg;
        } XOP_xr0_W;
 
-       union                   // XOP - XR6 Register - Write values
+       union                   /* XOP - XR6 Register - Write values */
         {
                BYTE reg;
                struct _XR6_BITREGSW {
-                       BYTE unused1:4;         // XR6[0:3]
+                       BYTE unused1:4;         /* XR6[0:3] */
 
-                       BYTE CLK_OFF:1;         // XR6[4:4]
+                       BYTE CLK_OFF:1;         /* XR6[4:4] */
 
-                       BYTE unused2:3;         // XR6[5:7]
+                       BYTE unused2:3;         /* XR6[5:7] */
 
                } bitreg;
        } XOP_xr6_W;
@@ -990,35 +1002,36 @@ typedef struct _DAA_REGS {
 #define ALISDAA_ID_BYTE      0x81
 #define ALISDAA_CALLERID_SIZE  512
 
-//------------------------------
-//
-//  Misc definitions
-//
+/*------------------------------ */
+/* */
+/*  Misc definitions */
+/* */
 
-// Power Up Operation
+/* Power Up Operation */
 #define SOP_PU_SLEEP    0
 #define SOP_PU_RINGING    1
 #define SOP_PU_CONVERSATION  2
 #define SOP_PU_PULSEDIALING  3
+#define SOP_PU_RESET    4
 
 #define ALISDAA_CALLERID_SIZE 512
 
-#define PLAYBACK_MODE_COMPRESSED       0       //        Selects: Compressed modes, TrueSpeech 8.5-4.1, G.723.1, G.722, G.728, G.729
-#define PLAYBACK_MODE_TRUESPEECH_V40   0       //        Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps
-#define PLAYBACK_MODE_TRUESPEECH       8       //        Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps Version 5.1
-#define PLAYBACK_MODE_ULAW             2       //        Selects: 64 Kbit/sec MuA-law PCM
-#define PLAYBACK_MODE_ALAW             10      //        Selects: 64 Kbit/sec A-law PCM
-#define PLAYBACK_MODE_16LINEAR         6       //        Selects: 128 Kbit/sec 16-bit linear
-#define PLAYBACK_MODE_8LINEAR          4       //        Selects: 64 Kbit/sec 8-bit signed linear
-#define PLAYBACK_MODE_8LINEAR_WSS      5       //        Selects: 64 Kbit/sec WSS 8-bit unsigned linear
-
-#define RECORD_MODE_COMPRESSED         0       //        Selects: Compressed modes, TrueSpeech 8.5-4.1, G.723.1, G.722, G.728, G.729
-#define RECORD_MODE_TRUESPEECH         0       //        Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps
-#define RECORD_MODE_ULAW               4       //        Selects: 64 Kbit/sec Mu-law PCM
-#define RECORD_MODE_ALAW               12      //        Selects: 64 Kbit/sec A-law PCM
-#define RECORD_MODE_16LINEAR           5       //        Selects: 128 Kbit/sec 16-bit linear
-#define RECORD_MODE_8LINEAR            6       //        Selects: 64 Kbit/sec 8-bit signed linear
-#define RECORD_MODE_8LINEAR_WSS                7       //        Selects: 64 Kbit/sec WSS 8-bit unsigned linear
+#define PLAYBACK_MODE_COMPRESSED       0       /*        Selects: Compressed modes, TrueSpeech 8.5-4.1, G.723.1, G.722, G.728, G.729 */
+#define PLAYBACK_MODE_TRUESPEECH_V40   0       /*        Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps */
+#define PLAYBACK_MODE_TRUESPEECH       8       /*        Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps Version 5.1 */
+#define PLAYBACK_MODE_ULAW             2       /*        Selects: 64 Kbit/sec MuA-law PCM */
+#define PLAYBACK_MODE_ALAW             10      /*        Selects: 64 Kbit/sec A-law PCM */
+#define PLAYBACK_MODE_16LINEAR         6       /*        Selects: 128 Kbit/sec 16-bit linear */
+#define PLAYBACK_MODE_8LINEAR          4       /*        Selects: 64 Kbit/sec 8-bit signed linear */
+#define PLAYBACK_MODE_8LINEAR_WSS      5       /*        Selects: 64 Kbit/sec WSS 8-bit unsigned linear */
+
+#define RECORD_MODE_COMPRESSED         0       /*        Selects: Compressed modes, TrueSpeech 8.5-4.1, G.723.1, G.722, G.728, G.729 */
+#define RECORD_MODE_TRUESPEECH         0       /*        Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps */
+#define RECORD_MODE_ULAW               4       /*        Selects: 64 Kbit/sec Mu-law PCM */
+#define RECORD_MODE_ALAW               12      /*        Selects: 64 Kbit/sec A-law PCM */
+#define RECORD_MODE_16LINEAR           5       /*        Selects: 128 Kbit/sec 16-bit linear */
+#define RECORD_MODE_8LINEAR            6       /*        Selects: 64 Kbit/sec 8-bit signed linear */
+#define RECORD_MODE_8LINEAR_WSS                7       /*        Selects: 64 Kbit/sec WSS 8-bit unsigned linear */
 
 enum SLIC_STATES {
        PLD_SLIC_STATE_OC = 0,
@@ -1074,36 +1087,39 @@ typedef struct {
        char enable;
        char en_filter;
        unsigned int filter;
-       unsigned int state;     // State 0 when cadence has not started.
+       unsigned int state;     /* State 0 when cadence has not started. */
 
-       unsigned int on1;       // State 1
+       unsigned int on1;       /* State 1 */
 
-       unsigned long on1min;   // State 1 - 10% + jiffies
-       unsigned long on1dot;   // State 1 + jiffies
+       unsigned long on1min;   /* State 1 - 10% + jiffies */
+       unsigned long on1dot;   /* State 1 + jiffies */
 
-       unsigned long on1max;   // State 1 + 10% + jiffies
+       unsigned long on1max;   /* State 1 + 10% + jiffies */
 
-       unsigned int off1;      // State 2
+       unsigned int off1;      /* State 2 */
 
        unsigned long off1min;
+       unsigned long off1dot;  /* State 2 + jiffies */
        unsigned long off1max;
-       unsigned int on2;       // State 3
+       unsigned int on2;       /* State 3 */
 
        unsigned long on2min;
        unsigned long on2dot;
        unsigned long on2max;
-       unsigned int off2;      // State 4
+       unsigned int off2;      /* State 4 */
 
        unsigned long off2min;
+       unsigned long off2dot;  /* State 4 + jiffies */
        unsigned long off2max;
-       unsigned int on3;       // State 5
+       unsigned int on3;       /* State 5 */
 
        unsigned long on3min;
        unsigned long on3dot;
        unsigned long on3max;
-       unsigned int off3;      // State 6
+       unsigned int off3;      /* State 6 */
 
        unsigned long off3min;
+       unsigned long off3dot;  /* State 6 + jiffies */
        unsigned long off3max;
 } IXJ_CADENCE_F;
 
@@ -1122,68 +1138,92 @@ typedef struct {
        unsigned int pots_pstn:1;
        unsigned int g729_loaded:1;
        unsigned int ts85_loaded:1;
-       unsigned int dtmf_oob:1;        // DTMF Out-Of-Band
+       unsigned int dtmf_oob:1;        /* DTMF Out-Of-Band */
 
-       unsigned int pcmciascp:1;       // Smart Cable Present
+       unsigned int pcmciascp:1;       /* SmartCABLE Present */
 
-       unsigned int pcmciasct:2;       // Smart Cable Type
+       unsigned int pcmciasct:2;       /* SmartCABLE Type */
 
-       unsigned int pcmciastate:3;     // Smart Cable Init State
+       unsigned int pcmciastate:3;     /* SmartCABLE Init State */
 
-       unsigned int inwrite:1; // Currently writing
+       unsigned int inwrite:1; /* Currently writing */
 
-       unsigned int inread:1;  // Currently reading
+       unsigned int inread:1;  /* Currently reading */
 
-       unsigned int incheck:1; // Currently checking the smart cable
+       unsigned int incheck:1; /* Currently checking the SmartCABLE */
 
-       unsigned int cidplay:1; // Currently playing Caller ID
+       unsigned int cidplay:1; /* Currently playing Caller ID */
 
-       unsigned int cidring:1; // This is the ring for Caller ID
+       unsigned int cidring:1; /* This is the ring for Caller ID */
 
-       unsigned int cidsent:1; // Caller ID has been sent
+       unsigned int cidsent:1; /* Caller ID has been sent */
 
-       unsigned int cidcw_ack:1; // Caller ID CW ACK (from CPE)
-
-       unsigned int x:6;       // unsed bits
+       unsigned int cidcw_ack:1; /* Caller ID CW ACK (from CPE) */
+       unsigned int firstring:1; /* First ring cadence is complete */
+       unsigned int pstncheck:1;       /* Currently checking the PSTN Line */
+       unsigned int pstn_rmr:1;
+       unsigned int x:3;       /* unsed bits */
 
 } IXJ_FLAGS;
 
 /******************************************************************************
 *
-*  This structure represents the Internet PhoneJACK and Internet LineJACK
+*  This structure holds the state of all of the Quicknet cards
 *
 ******************************************************************************/
 
 typedef struct {
        struct phone_device p;
+       struct timer_list timer;
        unsigned int board;
        unsigned int DSPbase;
        unsigned int XILINXbase;
        unsigned int serial;
+       atomic_t DSPWrite;
        struct phone_capability caplist[30];
        unsigned int caps;
-       unsigned int country;
+#if LINUX_VERSION_CODE < 0x020400
+       struct pnp_dev *dev;
+#else
        struct pci_dev *dev;
+#endif
        unsigned int cardtype;
        unsigned int rec_codec;
+       unsigned int cid_rec_codec;
+       unsigned int cid_rec_volume;
+       unsigned char cid_rec_flag;
        char rec_mode;
        unsigned int play_codec;
        unsigned int cid_play_codec;
+       unsigned int cid_play_volume;
+       unsigned char cid_play_flag;
        char play_mode;
        IXJ_FLAGS flags;
+       unsigned int busyflags;
        unsigned int rec_frame_size;
        unsigned int play_frame_size;
+       unsigned int cid_play_frame_size;
        unsigned int cid_base_frame_size;
        unsigned long cidcw_wait;
        int aec_level;
+       int cid_play_aec_level;
        int readers, writers;
-       wait_queue_head_t poll_q;
-       wait_queue_head_t read_q;
+#if LINUX_VERSION_CODE < 0x020400
+       struct wait_queue *poll_q;
+       struct wait_queue *read_q;
+#else
+        wait_queue_head_t poll_q;
+        wait_queue_head_t read_q;
+#endif
        char *read_buffer, *read_buffer_end;
        char *read_convert_buffer;
        unsigned int read_buffer_size;
        unsigned int read_buffer_ready;
-       wait_queue_head_t write_q;
+#if LINUX_VERSION_CODE < 0x020400
+       struct wait_queue *write_q;
+#else
+        wait_queue_head_t write_q;
+#endif
        char *write_buffer, *write_buffer_end;
        char *write_convert_buffer;
        unsigned int write_buffer_size;
@@ -1200,8 +1240,9 @@ typedef struct {
        char tone_state;
        char maxrings;
        IXJ_CADENCE *cadence_t;
+       IXJ_CADENCE *cadence_r;
        int tone_cadence_state;
-       IXJ_CADENCE_F cadence_f[4];
+       IXJ_CADENCE_F cadence_f[6];
        DTMF dtmf;
        CPTF cptf;
        BYTES dsp;
@@ -1236,21 +1277,32 @@ typedef struct {
        int intercom;
        int m_hook;
        int r_hook;
+       int p_hook;
        char pstn_envelope;
        char pstn_cid_intr;
        unsigned char fskz;
        unsigned char fskphase;
        unsigned char fskcnt;
+        unsigned int cidsize;
+       unsigned int cidcnt;
        unsigned pstn_cid_received;
        PHONE_CID cid;
        PHONE_CID cid_send;
+       unsigned long pstn_ring_int;
        unsigned long pstn_ring_start;
        unsigned long pstn_ring_stop;
        unsigned long pstn_winkstart;
+       unsigned long pstn_last_rmr;
+       unsigned long pstn_prev_rmr;
+       unsigned long pots_winkstart;
        unsigned int winktime;
        unsigned long flash_end;
        char port;
+       char hookstate;
        union telephony_exception ex;
+       union telephony_exception ex_sig;
+       int ixj_signals[35];
+       IXJ_SIGDEF sigdef;
        char daa_mode;
        char daa_country;
        unsigned long pstn_sleeptil;
@@ -1268,13 +1320,23 @@ typedef struct {
        unsigned long timerchecks;
        unsigned long txreadycheck;
        unsigned long rxreadycheck;
+       unsigned long statuswait;
+       unsigned long statuswaitfail;
+       unsigned long pcontrolwait;
+       unsigned long pcontrolwaitfail;
+       unsigned long iscontrolready;
+       unsigned long iscontrolreadyfail;
+       unsigned long pstnstatecheck;
+#ifdef IXJ_DYN_ALLOC
+       short *fskdata;
+#else
        short fskdata[8000];
+#endif
+       int fsksize;
        int fskdcnt;
 } IXJ;
 
-int ixj_WriteDSPCommand(unsigned short, IXJ *);
-
 typedef int (*IXJ_REGFUNC) (IXJ * j, unsigned long arg);
 
-int ixj_register(int index, IXJ_REGFUNC regfunc);
-int ixj_unregister(int index);
+extern IXJ *ixj_pcmcia_probe(unsigned long, unsigned long);
+
diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c
new file mode 100644 (file)
index 0000000..51af1dc
--- /dev/null
@@ -0,0 +1,343 @@
+#include "ixj-ver.h"
+
+#include <linux/module.h>
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>      /* printk() */
+#include <linux/fs.h>          /* everything... */
+#include <linux/errno.h>       /* error codes */
+#include <linux/slab.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+
+#include "ixj.h"
+
+/*
+ *     PCMCIA service support for Quicknet cards
+ */
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+MODULE_PARM(pc_debug, "i");
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+#else
+#define DEBUG(n, args...)
+#endif
+
+typedef struct ixj_info_t {
+       int ndev;
+       dev_node_t node;
+       struct ixj *port;
+} ixj_info_t;
+
+static dev_link_t *ixj_attach(void);
+static void ixj_detach(dev_link_t *);
+static void ixj_config(dev_link_t * link);
+static void ixj_cs_release(u_long arg);
+static int ixj_event(event_t event, int priority, event_callback_args_t * args);
+static dev_info_t dev_info = "ixj_cs";
+static dev_link_t *dev_list = NULL;
+
+static void cs_error(client_handle_t handle, int func, int ret)
+{
+       error_info_t err =
+       {
+               func, ret
+       };
+       CardServices(ReportError, handle, &err);
+}
+
+static dev_link_t *ixj_attach(void)
+{
+       client_reg_t client_reg;
+       dev_link_t *link;
+       int ret;
+       DEBUG(0, "ixj_attach()\n");
+       /* Create new ixj device */
+       link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+       if (!link)
+               return NULL;
+       memset(link, 0, sizeof(struct dev_link_t));
+       link->release.function = &ixj_cs_release;
+       link->release.data = (u_long) link;
+       link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+       link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
+       link->io.IOAddrLines = 3;
+       link->conf.Vcc = 50;
+       link->conf.IntType = INT_MEMORY_AND_IO;
+       link->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL);
+       if (!link->priv)
+               return NULL;
+       memset(link->priv, 0, sizeof(struct ixj_info_t));
+       /* Register with Card Services */
+       link->next = dev_list;
+       dev_list = link;
+       client_reg.dev_info = &dev_info;
+       client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
+       client_reg.EventMask =
+           CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
+           CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
+           CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
+       client_reg.event_handler = &ixj_event;
+       client_reg.Version = 0x0210;
+       client_reg.event_callback_args.client_data = link;
+       ret = CardServices(RegisterClient, &link->handle, &client_reg);
+       if (ret != CS_SUCCESS) {
+               cs_error(link->handle, RegisterClient, ret);
+               ixj_detach(link);
+               return NULL;
+       }
+       return link;
+}
+
+static void ixj_detach(dev_link_t * link)
+{
+       dev_link_t **linkp;
+       long flags;
+       int ret;
+       DEBUG(0, "ixj_detach(0x%p)\n", link);
+       for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+               if (*linkp == link)
+                       break;
+       if (*linkp == NULL)
+               return;
+       save_flags(flags);
+       cli();
+       if (link->state & DEV_RELEASE_PENDING) {
+               del_timer(&link->release);
+               link->state &= ~DEV_RELEASE_PENDING;
+       }
+       restore_flags(flags);
+       if (link->state & DEV_CONFIG)
+               ixj_cs_release((u_long) link);
+       if (link->handle) {
+               ret = CardServices(DeregisterClient, link->handle);
+               if (ret != CS_SUCCESS)
+                       cs_error(link->handle, DeregisterClient, ret);
+       }
+       /* Unlink device structure, free bits */
+       *linkp = link->next;
+        kfree(link->priv);
+        kfree(link);
+}
+
+#define CS_CHECK(fn, args...) \
+while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
+
+#define CFG_CHECK(fn, args...) \
+if (CardServices(fn, args) != 0) goto next_entry
+
+static void ixj_get_serial(dev_link_t * link, IXJ * j)
+{
+       client_handle_t handle;
+       tuple_t tuple;
+       u_short buf[128];
+       char *str;
+       int last_ret, last_fn, i, place;
+       handle = link->handle;
+       DEBUG(0, "ixj_get_serial(0x%p)\n", link);
+       tuple.TupleData = (cisdata_t *) buf;
+       tuple.TupleOffset = 0;
+       tuple.TupleDataMax = 80;
+       tuple.Attributes = 0;
+       tuple.DesiredTuple = CISTPL_VERS_1;
+       CS_CHECK(GetFirstTuple, handle, &tuple);
+       CS_CHECK(GetTupleData, handle, &tuple);
+       str = (char *) buf;
+       printk("PCMCIA Version %d.%d\n", str[0], str[1]);
+       str += 2;
+       printk("%s", str);
+       str = str + strlen(str) + 1;
+       printk(" %s", str);
+       str = str + strlen(str) + 1;
+       place = 1;
+       for (i = strlen(str) - 1; i >= 0; i--) {
+               switch (str[i]) {
+               case '0':
+               case '1':
+               case '2':
+               case '3':
+               case '4':
+               case '5':
+               case '6':
+               case '7':
+               case '8':
+               case '9':
+                       j->serial += (str[i] - 48) * place;
+                       break;
+               case 'A':
+               case 'B':
+               case 'C':
+               case 'D':
+               case 'E':
+               case 'F':
+                       j->serial += (str[i] - 55) * place;
+                       break;
+               case 'a':
+               case 'b':
+               case 'c':
+               case 'd':
+               case 'e':
+               case 'f':
+                       j->serial += (str[i] - 87) * place;
+                       break;
+               }
+               place = place * 0x10;
+       }
+       str = str + strlen(str) + 1;
+       printk(" version %s\n", str);
+      cs_failed:
+       return;
+}
+
+static void ixj_config(dev_link_t * link)
+{
+       IXJ *j;
+       client_handle_t handle;
+       ixj_info_t *info;
+       tuple_t tuple;
+       u_short buf[128];
+       cisparse_t parse;
+       config_info_t conf;
+       cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
+       cistpl_cftable_entry_t dflt =
+       {
+               0
+       };
+       int last_ret, last_fn;
+       handle = link->handle;
+       info = link->priv;
+       DEBUG(0, "ixj_config(0x%p)\n", link);
+       tuple.TupleData = (cisdata_t *) buf;
+       tuple.TupleOffset = 0;
+       tuple.TupleDataMax = 255;
+       tuple.Attributes = 0;
+       tuple.DesiredTuple = CISTPL_CONFIG;
+       CS_CHECK(GetFirstTuple, handle, &tuple);
+       CS_CHECK(GetTupleData, handle, &tuple);
+       CS_CHECK(ParseTuple, handle, &tuple, &parse);
+       link->conf.ConfigBase = parse.config.base;
+       link->conf.Present = parse.config.rmask[0];
+       link->state |= DEV_CONFIG;
+       CS_CHECK(GetConfigurationInfo, handle, &conf);
+       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+       tuple.Attributes = 0;
+       CS_CHECK(GetFirstTuple, handle, &tuple);
+       while (1) {
+               CFG_CHECK(GetTupleData, handle, &tuple);
+               CFG_CHECK(ParseTuple, handle, &tuple, &parse);
+               if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+                       cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+                       link->conf.ConfigIndex = cfg->index;
+                       link->io.BasePort1 = io->win[0].base;
+                       link->io.NumPorts1 = io->win[0].len;
+                       if (io->nwin == 2) {
+                               link->io.BasePort2 = io->win[1].base;
+                               link->io.NumPorts2 = io->win[1].len;
+                       }
+                       CFG_CHECK(RequestIO, link->handle, &link->io);
+                       /* If we've got this far, we're done */
+                       break;
+               }
+             next_entry:
+               if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+                       dflt = *cfg;
+               CS_CHECK(GetNextTuple, handle, &tuple);
+       }
+
+       CS_CHECK(RequestConfiguration, handle, &link->conf);
+
+       /*
+        *      Register the card with the core.
+        */     
+       j=ixj_pcmcia_probe(link->io.BasePort1,link->io.BasePort1 + 0x10);
+
+       info->ndev = 1;
+       info->node.major = PHONE_MAJOR;
+       link->dev = &info->node;
+       ixj_get_serial(link, j);
+       link->state &= ~DEV_CONFIG_PENDING;
+       return;
+      cs_failed:
+       cs_error(link->handle, last_fn, last_ret);
+       ixj_cs_release((u_long) link);
+}
+
+static void ixj_cs_release(u_long arg)
+{
+       dev_link_t *link = (dev_link_t *) arg;
+       ixj_info_t *info = link->priv;
+       DEBUG(0, "ixj_cs_release(0x%p)\n", link);
+       info->ndev = 0;
+       link->dev = NULL;
+       CardServices(ReleaseConfiguration, link->handle);
+       CardServices(ReleaseIO, link->handle, &link->io);
+       link->state &= ~DEV_CONFIG;
+}
+
+static int ixj_event(event_t event, int priority, event_callback_args_t * args)
+{
+       dev_link_t *link = args->client_data;
+       DEBUG(1, "ixj_event(0x%06x)\n", event);
+       switch (event) {
+       case CS_EVENT_CARD_REMOVAL:
+               link->state &= ~DEV_PRESENT;
+               if (link->state & DEV_CONFIG) {
+                       link->release.expires = jiffies + (HZ / 20);
+                       link->state |= DEV_RELEASE_PENDING;
+                       add_timer(&link->release);
+               }
+               break;
+       case CS_EVENT_CARD_INSERTION:
+               link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+               ixj_config(link);
+               break;
+       case CS_EVENT_PM_SUSPEND:
+               link->state |= DEV_SUSPEND;
+               /* Fall through... */
+       case CS_EVENT_RESET_PHYSICAL:
+               if (link->state & DEV_CONFIG)
+                       CardServices(ReleaseConfiguration, link->handle);
+               break;
+       case CS_EVENT_PM_RESUME:
+               link->state &= ~DEV_SUSPEND;
+               /* Fall through... */
+       case CS_EVENT_CARD_RESET:
+               if (DEV_OK(link))
+                       CardServices(RequestConfiguration, link->handle, &link->conf);
+               break;
+       }
+       return 0;
+}
+
+int __init ixj_register_pcmcia(void)
+{
+       servinfo_t serv;
+       DEBUG(0, "%s\n", version);
+       CardServices(GetCardServicesInfo, &serv);
+       if (serv.Revision != CS_RELEASE_CODE) {
+               printk(KERN_NOTICE "ixj_cs: Card Services release does not match!\n");
+               return -EINVAL;
+       }
+       register_pcmcia_driver(&dev_info, &ixj_attach, &ixj_detach);
+       return 0;
+}
+
+static void ixj_pcmcia_unload(void)
+{
+       DEBUG(0, "ixj_cs: unloading\n");
+       unregister_pcmcia_driver(&dev_info);
+       while (dev_list != NULL)
+               ixj_detach(dev_list);
+}
+
+module_init(ixj_register_pcmcia);
+module_exit(ixj_pcmcia_unload);
+
+MODULE_LICENSE("GPL");
+
index 2e914ef5fa9290920c0fbc04bdade7be80e92211..0380ee2dfdc13e9c97fb6b7edfddbf23407b3853 100644 (file)
@@ -167,5 +167,7 @@ static void __exit telephony_exit(void)
 module_init(telephony_init);
 module_exit(telephony_exit);
 
+MODULE_LICENSE("GPL");
+
 EXPORT_SYMBOL(phone_register_device);
 EXPORT_SYMBOL(phone_unregister_device);
index 07b593e1ba48b6c74d459a2e855068f33393c3cb..ef4db5c5db7886d9e3e81d577ec5a3e905cffed0 100644 (file)
@@ -384,7 +384,7 @@ static ssize_t usb_device_dump(char **buffer, size_t *nbytes, loff_t *skip_bytes
        int chix;
        int ret, cnt = 0;
        int parent_devnum = 0;
-       char *pages_start, *data_end;
+       char *pages_start, *data_end, *speed;
        unsigned int length;
        ssize_t total_written = 0;
        
@@ -404,8 +404,21 @@ static ssize_t usb_device_dump(char **buffer, size_t *nbytes, loff_t *skip_bytes
         * So the root hub's parent is 0 and any device that is
         * plugged into the root hub has a parent of 0.
         */
-       data_end = pages_start + sprintf(pages_start, format_topo, bus->busnum, level, parent_devnum, index, count,
-                                       usbdev->devnum, usbdev->slow ? "1.5" : "12 ", usbdev->maxchild);
+       switch (usbdev->speed) {
+       case USB_SPEED_LOW:
+               speed = "1.5"; break;
+       case USB_SPEED_UNKNOWN:         /* usb 1.1 root hub code */
+       case USB_SPEED_FULL:
+               speed = "12 "; break;
+       case USB_SPEED_HIGH:
+               speed = "480"; break;
+       default:
+               speed = "?? ";
+       }
+       data_end = pages_start + sprintf(pages_start, format_topo,
+                       bus->busnum, level, parent_devnum,
+                       index, count, usbdev->devnum,
+                       speed, usbdev->maxchild);
        /*
         * level = topology-tier level;
         * parent_devnum = parent device number;
index 714449eb437ddcfd5d8116a438501f290b081c8e..0a89c09a6eff8ae652419b4e07db3478cfc5d20d 100644 (file)
@@ -684,7 +684,7 @@ static int proc_connectinfo(struct dev_state *ps, void *arg)
        struct usbdevfs_connectinfo ci;
 
        ci.devnum = ps->dev->devnum;
-       ci.slow = ps->dev->slow;
+       ci.slow = ps->dev->speed == USB_SPEED_LOW;
        if (copy_to_user(arg, &ci, sizeof(ci)))
                return -EFAULT;
        return 0;
index 1425049e23bf1bab608e2bfce6e063c008559347..f7c45338884377f1d82f2bd1da16bd8e1f1137cf 100644 (file)
@@ -39,6 +39,18 @@ static DECLARE_WAIT_QUEUE_HEAD(khubd_wait);
 static int khubd_pid = 0;                      /* PID of khubd */
 static DECLARE_COMPLETION(khubd_exited);
 
+#ifdef DEBUG
+static inline char *portspeed (int portstatus)
+{
+       if (portstatus & (1 << USB_PORT_FEAT_HIGHSPEED))
+               return "480 Mb/s";
+       else if (portstatus & (1 << USB_PORT_FEAT_LOWSPEED))
+               return "1.5 Mb/s";
+       else
+               return "12 Mb/s";
+}
+#endif
+
 static int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size)
 {
        return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
@@ -113,7 +125,7 @@ static void usb_hub_power_on(struct usb_hub *hub)
 
        /* Enable power to the ports */
        dbg("enabling power on all ports");
-       for (i = 0; i < hub->nports; i++)
+       for (i = 0; i < hub->descriptor->bNbrPorts; i++)
                usb_set_port_feature(hub->dev, i + 1, USB_PORT_FEAT_POWER);
 
        /* Wait for power to be enabled */
@@ -128,14 +140,14 @@ static int usb_hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor
        unsigned int pipe;
        int i, maxp, ret;
 
-       hub->descriptor = kmalloc(HUB_DESCRIPTOR_MAX_SIZE, GFP_KERNEL);
+       hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);
        if (!hub->descriptor) {
-               err("Unable to kmalloc %d bytes for hub descriptor", HUB_DESCRIPTOR_MAX_SIZE);
+               err("Unable to kmalloc %d bytes for hub descriptor", sizeof(*hub->descriptor));
                return -1;
        }
 
        /* Request the entire hub descriptor. */
-       ret = usb_get_hub_descriptor(dev, hub->descriptor, HUB_DESCRIPTOR_MAX_SIZE);
+       ret = usb_get_hub_descriptor(dev, hub->descriptor, sizeof(*hub->descriptor));
                /* <hub->descriptor> is large enough for a hub with 127 ports;
                 * the hub can/will return fewer bytes here. */
        if (ret < 0) {
@@ -144,10 +156,10 @@ static int usb_hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor
                return -1;
        }
 
-       le16_to_cpus(&hub->descriptor->wHubCharacteristics);
+       dev->maxchild = hub->descriptor->bNbrPorts;
+       info("%d port%s detected", hub->descriptor->bNbrPorts, (hub->descriptor->bNbrPorts == 1) ? "" : "s");
 
-       hub->nports = dev->maxchild = hub->descriptor->bNbrPorts;
-       info("%d port%s detected", hub->nports, (hub->nports == 1) ? "" : "s");
+       le16_to_cpus(&hub->descriptor->wHubCharacteristics);
 
        if (hub->descriptor->wHubCharacteristics & HUB_CHAR_COMPOUND)
                dbg("part of a compound device");
@@ -180,6 +192,40 @@ static int usb_hub_configure(struct usb_hub *hub, struct usb_endpoint_descriptor
                         break;
        }
 
+       switch (dev->descriptor.bDeviceProtocol) {
+               case 0:
+                       break;
+               case 1:
+                       dbg("Single TT");
+                       break;
+               case 2:
+                       dbg("Multiple TT");
+                       break;
+               default:
+                       dbg("Unrecognized hub protocol %d",
+                               dev->descriptor.bDeviceProtocol);
+                       break;
+       }
+
+       switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_TTTT) {
+               case 0x00:
+                       if (dev->descriptor.bDeviceProtocol != 0)
+                               dbg("TT requires at most 8 FS bit times");
+                       break;
+               case 0x20:
+                       dbg("TT requires at most 16 FS bit times");
+                       break;
+               case 0x40:
+                       dbg("TT requires at most 24 FS bit times");
+                       break;
+               case 0x60:
+                       dbg("TT requires at most 32 FS bit times");
+                       break;
+       }
+
+       dbg("Port indicators are %s supported", 
+           (hub->descriptor->wHubCharacteristics & HUB_CHAR_PORTIND) ? "" : "not");
+
        dbg("power on to power good time: %dms", hub->descriptor->bPwrOn2PwrGood * 2);
        dbg("hub controller current requirement: %dmA", hub->descriptor->bHubContrCurrent);
 
@@ -397,7 +443,7 @@ static int usb_hub_reset(struct usb_hub *hub)
        int i;
 
        /* Disconnect any attached devices */
-       for (i = 0; i < hub->nports; i++) {
+       for (i = 0; i < hub->descriptor->bNbrPorts; i++) {
                if (dev->children[i])
                        usb_disconnect(&dev->children[i]);
        }
@@ -444,6 +490,7 @@ static void usb_hub_disconnect(struct usb_device *dev)
 #define HUB_LONG_RESET_TIME    200
 #define HUB_RESET_TIMEOUT      500
 
+/* return: -1 on error, 0 on success, 1 on disconnect.  */
 static int usb_hub_port_wait_reset(struct usb_device *hub, int port,
                                struct usb_device *dev, unsigned int delay)
 {
@@ -465,18 +512,25 @@ static int usb_hub_port_wait_reset(struct usb_device *hub, int port,
                portstatus = le16_to_cpu(portsts.wPortStatus);
                portchange = le16_to_cpu(portsts.wPortChange);
                dbg("port %d, portstatus %x, change %x, %s", port + 1,
-                       portstatus, portchange,
-                       portstatus & (1 << USB_PORT_FEAT_LOWSPEED) ? "1.5 Mb/s" : "12 Mb/s");
+                       portstatus, portchange, portspeed (portstatus));
+
+               /* Device went away? */
+               if (!(portstatus & USB_PORT_STAT_CONNECTION))
+                       return 1;
 
                /* bomb out completely if something weird happened */
-               if ((portchange & USB_PORT_STAT_C_CONNECTION) ||
-                   !(portstatus & USB_PORT_STAT_CONNECTION))
+               if ((portchange & USB_PORT_STAT_C_CONNECTION))
                        return -1;
 
                /* if we`ve finished resetting, then break out of the loop */
                if (!(portstatus & USB_PORT_STAT_RESET) &&
                    (portstatus & USB_PORT_STAT_ENABLE)) {
-                       dev->slow = (portstatus & USB_PORT_STAT_LOW_SPEED) ? 1 : 0;
+                       if (portstatus & USB_PORT_STAT_HIGH_SPEED)
+                               dev->speed = USB_SPEED_HIGH;
+                       else if (portstatus & USB_PORT_STAT_LOW_SPEED)
+                               dev->speed = USB_SPEED_LOW;
+                       else
+                               dev->speed = USB_SPEED_FULL;
                        return 0;
                }
 
@@ -491,19 +545,21 @@ static int usb_hub_port_wait_reset(struct usb_device *hub, int port,
        return -1;
 }
 
+/* return: -1 on error, 0 on success, 1 on disconnect.  */
 static int usb_hub_port_reset(struct usb_device *hub, int port,
                                struct usb_device *dev, unsigned int delay)
 {
-       int i;
+       int i, status;
 
        /* Reset the port */
        for (i = 0; i < HUB_RESET_TRIES; i++) {
                usb_set_port_feature(hub, port + 1, USB_PORT_FEAT_RESET);
 
-               /* return success if the port reset OK */
-               if (!usb_hub_port_wait_reset(hub, port, dev, delay)) {
+               /* return on disconnect or reset */
+               status = usb_hub_port_wait_reset(hub, port, dev, delay);
+               if (status != -1) {
                        usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_RESET);
-                       return 0;
+                       return status;
                }
 
                dbg("port %d of hub %d not enabled, trying reset again...",
@@ -539,8 +595,8 @@ static void usb_hub_port_connect_change(struct usb_device *hub, int port,
 
        portstatus = le16_to_cpu(portsts->wPortStatus);
        portchange = le16_to_cpu(portsts->wPortChange);
-       dbg("port %d, portstatus %x, change %x, %s", port + 1, portstatus,
-               portchange, portstatus & (1 << USB_PORT_FEAT_LOWSPEED) ? "1.5 Mb/s" : "12 Mb/s");
+       dbg("port %d, portstatus %x, change %x, %s",
+               port + 1, portstatus, portchange, portspeed (portstatus));
 
        /* Clear the connection change status */
        usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_CONNECTION);
@@ -686,7 +742,7 @@ static void usb_hub_events(void)
                        hub->error = 0;
                }
 
-               for (i = 0; i < hub->nports; i++) {
+               for (i = 0; i < hub->descriptor->bNbrPorts; i++) {
                        struct usb_port_status portsts;
                        unsigned short portstatus, portchange;
 
index 724f3cee3304dbca00b51781b124496e23e1a066..dc1bc2986f3e42538229f5fdd428a56e9671ed12 100644 (file)
 #define USB_PORT_FEAT_RESET            4
 #define USB_PORT_FEAT_POWER            8
 #define USB_PORT_FEAT_LOWSPEED         9
+#define USB_PORT_FEAT_HIGHSPEED                10
 #define USB_PORT_FEAT_C_CONNECTION     16
 #define USB_PORT_FEAT_C_ENABLE         17
 #define USB_PORT_FEAT_C_SUSPEND                18
 #define USB_PORT_FEAT_C_OVER_CURRENT   19
 #define USB_PORT_FEAT_C_RESET          20
+#define USB_PORT_FEAT_TEST              21
+#define USB_PORT_FEAT_INDICATOR         22
 
+/* 
+ * Hub Status and Hub Change results
+ * See USB 2.0 spec Table 11-19 and Table 11-20
+ */
 struct usb_port_status {
        __u16 wPortStatus;
        __u16 wPortChange;      
 } __attribute__ ((packed));
 
-/* wPortStatus bits */
+/* 
+ * wPortStatus bit field
+ * See USB 2.0 spec Table 11-21
+ */
 #define USB_PORT_STAT_CONNECTION       0x0001
 #define USB_PORT_STAT_ENABLE           0x0002
 #define USB_PORT_STAT_SUSPEND          0x0004
 #define USB_PORT_STAT_OVERCURRENT      0x0008
 #define USB_PORT_STAT_RESET            0x0010
+/* bits 5 for 7 are reserved */
 #define USB_PORT_STAT_POWER            0x0100
 #define USB_PORT_STAT_LOW_SPEED                0x0200
-
-/* wPortChange bits */
+#define USB_PORT_STAT_HIGH_SPEED        0x0400
+#define USB_PORT_STAT_TEST              0x0800
+#define USB_PORT_STAT_INDICATOR         0x1000
+/* bits 13 to 15 are reserved */
+
+/* 
+ * wPortChange bit field
+ * See USB 2.0 spec Table 11-22
+ * Bits 0 to 4 shown, bits 5 to 15 are reserved
+ */
 #define USB_PORT_STAT_C_CONNECTION     0x0001
 #define USB_PORT_STAT_C_ENABLE         0x0002
 #define USB_PORT_STAT_C_SUSPEND                0x0004
 #define USB_PORT_STAT_C_OVERCURRENT    0x0008
 #define USB_PORT_STAT_C_RESET          0x0010
 
-/* wHubCharacteristics (masks) */
-#define HUB_CHAR_LPSM          0x0003
-#define HUB_CHAR_COMPOUND      0x0004
-#define HUB_CHAR_OCPM          0x0018
+/*
+ * wHubCharacteristics (masks) 
+ * See USB 2.0 spec Table 11-13, offset 3
+ */
+#define HUB_CHAR_LPSM          0x0003 /* D1 .. D0 */
+#define HUB_CHAR_COMPOUND      0x0004 /* D2       */
+#define HUB_CHAR_OCPM          0x0018 /* D4 .. D3 */
+#define HUB_CHAR_TTTT           0x0060 /* D6 .. D5 */
+#define HUB_CHAR_PORTIND        0x0080 /* D7       */
 
 struct usb_hub_status {
        __u16 wHubStatus;
@@ -64,28 +88,28 @@ struct usb_hub_status {
 } __attribute__ ((packed));
 
 /*
- *Hub Status & Hub Change bit masks
+ * Hub Status & Hub Change bit masks
+ * See USB 2.0 spec Table 11-19 and Table 11-20
+ * Bits 0 and 1 for wHubStatus and wHubChange
+ * Bits 2 to 15 are reserved for both
  */
 #define HUB_STATUS_LOCAL_POWER 0x0001
 #define HUB_STATUS_OVERCURRENT 0x0002
-
 #define HUB_CHANGE_LOCAL_POWER 0x0001
 #define HUB_CHANGE_OVERCURRENT 0x0002
 
-#define HUB_DESCRIPTOR_MAX_SIZE        39      /* enough for 127 ports on a hub */
 
 /* Hub descriptor */
 struct usb_hub_descriptor {
-       __u8  bLength;
+       __u8  bDescLength;
        __u8  bDescriptorType;
        __u8  bNbrPorts;
        __u16 wHubCharacteristics;
        __u8  bPwrOn2PwrGood;
        __u8  bHubContrCurrent;
-
        /* DeviceRemovable and PortPwrCtrlMask want to be variable-length 
           bitmaps that hold max 256 entries, but for now they're ignored */
-       __u8  bitmap[0];
+       __u8  bitmap[2 * ((USB_MAXCHILDREN + 1 + 7) / 8)];
 } __attribute__ ((packed));
 
 struct usb_device;
@@ -104,9 +128,6 @@ struct usb_hub {
 
        struct list_head event_list;
 
-       /* Number of ports on the hub */
-       int nports;
-
        struct usb_hub_descriptor *descriptor;
 
        atomic_t refcnt;
index 958b9ac2ed1e2f3b90699f414c4d31f455d03932..43de3063a1ce2b571ab1f9f795121768430cbd0a 100644 (file)
@@ -312,13 +312,13 @@ static int pwc_allocate_buffers(struct pwc_device *pdev)
        /* create frame buffers, and make circular ring */
        for (i = 0; i < default_fbufs; i++) {
                if (pdev->fbuf[i].data == NULL) {
-                       kbuf = vmalloc(FRAME_SIZE); /* need vmalloc since frame buffer > 128K */
+                       kbuf = vmalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */
                        if (kbuf == NULL) {
                                Err("Failed to allocate frame buffer %d.\n", i);
                                return -ENOMEM;
                        }
                        pdev->fbuf[i].data = kbuf;
-                       memset(kbuf, 0, FRAME_SIZE);
+                       memset(kbuf, 0, PWC_FRAME_SIZE);
                }
        }
        
@@ -1807,6 +1807,7 @@ MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompres
 
 MODULE_DESCRIPTION("Philips USB webcam driver");
 MODULE_AUTHOR("Nemosoft Unv. <nemosoft@smcc.demon.nl>");
+MODULE_LICENSE("GPL");
 
 static int __init usb_pwc_init(void)
 {
index 1a97f091582741696371b0aa9514576a6046123a..b6dc4719f47e692b20bd14f7d9d11a0e34040ac3 100644 (file)
@@ -77,7 +77,7 @@
 /* Frame buffers: contains compressed or uncompressed video data. */
 #define MAX_FRAMES             5
 /* Maximum size after decompression is 640x480 YUV data, 1.5 * 640 * 480 */
-#define FRAME_SIZE             (460800 + TOUCAM_HEADER_SIZE + TOUCAM_TRAILER_SIZE)
+#define PWC_FRAME_SIZE                 (460800 + TOUCAM_HEADER_SIZE + TOUCAM_TRAILER_SIZE)
 
 /* Absolute maximum number of buffers available for mmap() */
 #define MAX_IMAGES             4
index 322064a11eb14569879bb9cb49ec856c0067132a..a0e7a9698dd9aa6a65f6cae817f702708e4749ec 100644 (file)
@@ -25,7 +25,7 @@
  *     - Jeroen Vreeken
  */
 
-static const char version[] = "0.22";
+static const char version[] = "0.23";
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -1034,8 +1034,8 @@ static int se401_newframe(struct usb_se401 *se401, int framenr)
                        }
                }
        }
-       
-       if (se401->frame[framenr].grabstate==FRAME_DONE) 
+
+       if (se401->frame[framenr].grabstate==FRAME_DONE)
                if (se401->enhance)
                        enhance_picture(se401->frame[framenr].data, se401->cheight*se401->cwidth*3);
        return 0;
@@ -1054,32 +1054,27 @@ static int se401_open(struct video_device *dev, int flags)
        struct usb_se401 *se401 = (struct usb_se401 *)dev;
        int err = 0;
 
+       /* we are called with the BKL held */
        MOD_INC_USE_COUNT;
-       down(&se401->lock);
 
+       se401->user=1;
        se401->fbuf=rvmalloc(se401->maxframesize * SE401_NUMFRAMES);
        if(!se401->fbuf) err=-ENOMEM;
 
         if (err) {
                MOD_DEC_USE_COUNT;
-               up(&se401->lock);
-               return err;
+               se401->user = 0;
        }
-       
-       se401->user=1;
 
-       up(&se401->lock);
-       
-       return 0;
+       return err;
 }
 
 static void se401_close(struct video_device *dev)
 {
+       /* called with BKL held */
         struct usb_se401 *se401 = (struct usb_se401 *)dev;
        int i;
 
-       down(&se401->lock);
-
        for (i=0; i<SE401_NUMFRAMES; i++)
                se401->frame[i].grabstate=FRAME_UNUSED;
        if (se401->streaming)
@@ -1087,9 +1082,8 @@ static void se401_close(struct video_device *dev)
 
        rvfree(se401->fbuf, se401->maxframesize * SE401_NUMFRAMES);
        se401->user=0;
-       up(&se401->lock);
 
-        if (!se401->dev) {
+        if (se401->removed) {
                 video_unregister_device(&se401->vdev);
                kfree(se401->width);
                kfree(se401->height);
@@ -1205,7 +1199,7 @@ static int se401_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
                        return -EINVAL;
                if (se401_set_size(se401, vw.width, vw.height))
                        return -EINVAL;
-               
+
                return 0;
         }
        case VIDIOCGWIN:
@@ -1280,7 +1274,7 @@ static int se401_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
 
                if(frame <0 || frame >= SE401_NUMFRAMES)
                        return -EINVAL;
-                       
+
                ret=se401_newframe(se401, frame);
                se401->frame[frame].grabstate=FRAME_UNUSED;
                return ret;
@@ -1350,12 +1344,12 @@ static long se401_read(struct video_device *dev, char *buf, unsigned long count,
 
        ret=se401_newframe(se401, 0);
 
-       if (!ret) {
-               copy_to_user(buf, se401->frame[0].data, realcount);
-       } else {
-               realcount=ret;
-       }
        se401->frame[0].grabstate=FRAME_UNUSED;
+       if (ret)
+               return ret;     
+       if (copy_to_user(buf, se401->frame[0].data, realcount))
+               return -EFAULT;
+       return realcount;
 
        return realcount;
 }
@@ -1368,7 +1362,7 @@ static int se401_mmap(struct video_device *dev, const char *adr,
        unsigned long page, pos;
 
        down(&se401->lock);
-       
+
        if (se401->dev == NULL) {
                up(&se401->lock);
                return -EIO;
@@ -1487,7 +1481,7 @@ static int se401_init(struct usb_se401 *se401)
                info("int urb burned down");
                return 1;
        }
-       
+
         /* Flash the led */
         se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
         se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
@@ -1555,33 +1549,45 @@ static void* __devinit se401_probe(struct usb_device *dev, unsigned int ifnum,
 
        info("firmware version: %02x", dev->descriptor.bcdDevice & 255);
 
-        if (se401_init(se401))
+        if (se401_init(se401)) {
+               kfree(se401);
                return NULL;
+       }
+
        memcpy(&se401->vdev, &se401_template, sizeof(se401_template));
        memcpy(se401->vdev.name, se401->camera_name, strlen(se401->camera_name));
+       init_waitqueue_head(&se401->wq);
+       init_MUTEX(&se401->lock);
+       wmb();
+
        if (video_register_device(&se401->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
+               kfree(se401);
                err("video_register_device failed");
                return NULL;
        }
        info("registered new video device: video%d", se401->vdev.minor);
 
-       init_waitqueue_head(&se401->wq);
-       init_MUTEX(&se401->lock);
-
         return se401;
 }
 
 static void se401_disconnect(struct usb_device *dev, void *ptr)
 {
-       int i;
        struct usb_se401 *se401 = (struct usb_se401 *) ptr;
 
+       lock_kernel();
        /* We don't want people trying to open up the device */
-       if (!se401->user)
-              video_unregister_device(&se401->vdev);
+       if (!se401->user){
+               video_unregister_device(&se401->vdev);
+               usb_se401_remove_disconnected(se401);
+       } else {
+               se401->removed = 1;
+       }
+       unlock_kernel();
+}
 
-        usb_driver_release_interface(&se401_driver,
-                &se401->dev->actconfig->interface[se401->iface]);
+static inline void usb_se401_remove_disconnected (struct usb_se401 *se401)
+{
+       int i;
 
         se401->dev = NULL;
         se401->frame[0].grabstate = FRAME_ERROR;
@@ -1589,8 +1595,7 @@ static void se401_disconnect(struct usb_device *dev, void *ptr)
 
        se401->streaming = 0;
 
-       if (waitqueue_active(&se401->wq))
-                wake_up_interruptible(&se401->wq);
+       wake_up_interruptible(&se401->wq);
 
        for (i=0; i<SE401_NUMSBUF; i++) if (se401->urb[i]) {
                se401->urb[i]->next = NULL;
@@ -1613,15 +1618,11 @@ static void se401_disconnect(struct usb_device *dev, void *ptr)
 #endif
 
         /* Free the memory */
-        if (!se401->user) {
-               kfree(se401->width);
-               kfree(se401->height);
-                kfree(se401);
-                se401 = NULL;
-        }
+       kfree(se401->width);
+       kfree(se401->height);
+       kfree(se401);
 }
 
-
 static struct usb_driver se401_driver = {
         name:          "se401",
 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 3, 0)
index 97dae91df75675c735391894cabd0e1c8663be57..e1fd7d2417b5dbb109a2df04579886204505c50a 100644 (file)
@@ -191,6 +191,7 @@ struct usb_se401 {
 
        struct semaphore lock;
        int user;               /* user count for exclusive use */
+       int removed;            /* device disconnected */
 
        int streaming;          /* Are we streaming video? */
 
@@ -229,6 +230,8 @@ struct usb_se401 {
        int nullpackets;
 };
 
+static inline void usb_se401_remove_disconnected (struct usb_se401 *se401);
+
 
 #endif
 
index e0b95620e4f6c3491cce93cf5d150c309babf8ad..87a32f0b7db830611cd36bffe677d94beee70f21 100644 (file)
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
+ * 2001_Aug_30 gkh
+ *     fixed oops in write_bulk_callback.
+ *
+ * 2001_Aug_28 gkh
+ *     reworked buffer logic to be like other usb-serial drivers.  Hopefully
+ *     removing some reported problems.
+ *
  * 2001_Jun_06 gkh
  *     finished porting to 2.4 format.
  * 
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v0.5"
+#define DRIVER_VERSION "v0.7"
 #define DRIVER_DESC "Prolific PL2303 USB to serial adaptor driver"
 
 
-#ifndef MIN
-#define MIN(a,b)        ((a) < (b) ? (a) : (b))
-#endif
-
-
-#define        PL2303_LOCK(port,flags)                                 \
-               do {                                            \
-               spin_lock_irqsave(&((struct pl2303_private *)(port->private))->lock, flags);    \
-               } while (0)
-
-#define        PL2303_UNLOCK(port,flags)                               \
-               do {                                            \
-               spin_unlock_irqrestore(&((struct pl2303_private *)(port->private))->lock, flags);       \
-               } while (0)
-
-
 
 static __devinitdata struct usb_device_id id_table [] = {
        { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID) },
@@ -75,33 +66,20 @@ static __devinitdata struct usb_device_id id_table [] = {
 
 MODULE_DEVICE_TABLE (usb, id_table);
 
-struct pl2303_private {
-       spinlock_t      lock;
-       unsigned char   *xmit_buf;
-       int             xmit_head;
-       int             xmit_tail;
-       int             xmit_cnt;
-};
 
 /* function prototypes for a PL2303 serial converter */
-static int pl2303_startup (struct usb_serial *serial);
 static int pl2303_open (struct usb_serial_port *port, struct file *filp);
 static void pl2303_close (struct usb_serial_port *port, struct file *filp);
 static void pl2303_set_termios (struct usb_serial_port *port,
                                struct termios *old);
 static int pl2303_ioctl (struct usb_serial_port *port, struct file *file,
                         unsigned int cmd, unsigned long arg);
-static void pl2303_throttle (struct usb_serial_port *port);
-static void pl2303_unthrottle (struct usb_serial_port *port);
 static void pl2303_read_int_callback (struct urb *urb);
 static void pl2303_read_bulk_callback (struct urb *urb);
 static void pl2303_write_bulk_callback (struct urb *urb);
 static int pl2303_write (struct usb_serial_port *port, int from_user,
                         const unsigned char *buf, int count);
-static int pl2303_write_room(struct usb_serial_port *port);
-static int pl2303_chars_in_buffer(struct usb_serial_port *port);
 static void pl2303_break_ctl(struct usb_serial_port *port,int break_state);
-static void start_xmit (struct usb_serial_port *port);
 
 
 /* All of the device info needed for the PL2303 SIO serial converter */
@@ -117,172 +95,54 @@ static struct usb_serial_device_type pl2303_device = {
        num_ports:              1,
        open:                   pl2303_open,
        close:                  pl2303_close,
-       throttle:               pl2303_throttle,
-       unthrottle:             pl2303_unthrottle,
        write:                  pl2303_write,
        ioctl:                  pl2303_ioctl,
-       write_room:             pl2303_write_room,
-       chars_in_buffer:        pl2303_chars_in_buffer,
        break_ctl:              pl2303_break_ctl,
        set_termios:            pl2303_set_termios,
        read_bulk_callback:     pl2303_read_bulk_callback,
        read_int_callback:      pl2303_read_int_callback,
        write_bulk_callback:    pl2303_write_bulk_callback,
-       startup:                pl2303_startup,
 };
 
 
-#define WDR_TIMEOUT (HZ * 5 )   /* default urb timeout */
-
-static unsigned char *tmp_buf;
-static DECLARE_MUTEX (tmp_buf_sem);
-
 
+static int pl2303_write (struct usb_serial_port *port, int from_user,  const unsigned char *buf, int count)
+{
+       int result;
 
-static int
-pl2303_write (struct usb_serial_port *port, int from_user,
-             const unsigned char *buf, int count)
-{                              /* pl2303_write */
-       struct pl2303_private *info = (struct pl2303_private *)port->private;
-       unsigned long flags;
-       int c,ret=0;
-       struct tty_struct *tty=port->tty;
-
-       dbg ("pl2303_write port %d, %d bytes", port->number, count);
+       dbg (__FUNCTION__ " - port %d, %d bytes", port->number, count);
 
-       if (!info) {
-               return -ENODEV;
+       if (!port->tty) {
+               err (__FUNCTION__ " - no tty???");
+               return 0;
        }
 
-       if (!tty || !info->xmit_buf || !tmp_buf) {
+       if (port->write_urb->status == -EINPROGRESS) {
+               dbg (__FUNCTION__ " - already writing");
                return 0;
        }
 
-
-       PL2303_LOCK(port,flags);
-
-
+       count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
        if (from_user) {
-               down(&tmp_buf_sem);
-               while (1) {
-                       c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
-                                          SERIAL_XMIT_SIZE - info->xmit_head));
-                       if (c <= 0)
-                               break;
-
-                       c -= copy_from_user(tmp_buf, buf, c);
-                       if (!c) {
-                               if (!ret) {
-                                       ret = -EFAULT;
-                               }
-                               break;
-                       }
-                       c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
-                                      SERIAL_XMIT_SIZE - info->xmit_head));
-                       memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
-                       info->xmit_head = ((info->xmit_head + c) & (SERIAL_XMIT_SIZE-1));
-                       info->xmit_cnt += c;
-                       buf += c;
-                       count -= c;
-                       ret += c;
-               }
-               up(&tmp_buf_sem);
+               if (copy_from_user (port->write_urb->transfer_buffer, buf, count))
+                       return -EFAULT;
        } else {
-               while (1) {
-                       c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, 
-                                          SERIAL_XMIT_SIZE - info->xmit_head));
-                       if (c <= 0) {
-                               break;
-                       }
-                       memcpy(info->xmit_buf + info->xmit_head, buf, c);
-                       info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
-                       info->xmit_cnt += c;
-                       buf += c;
-                       count -= c;
-                       ret += c;
-               }
+               memcpy (port->write_urb->transfer_buffer, buf, count);
        }
-       PL2303_UNLOCK(port, flags);
-
-       if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
-               start_xmit(port);
-       }
-       return ret;
-}
-
-static int pl2303_write_room(struct usb_serial_port *port)
-{
-       struct pl2303_private *info = (struct pl2303_private *)port->private;
-       int     ret;
-
-       if (!info)
-               return 0;
-
-       ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
-       if (ret < 0)
-               ret = 0;
-       return ret;
+       
+       usb_serial_debug_data (__FILE__, __FUNCTION__, count, port->write_urb->transfer_buffer);
+
+       port->write_urb->transfer_buffer_length = count;
+       port->write_urb->dev = port->serial->dev;
+       result = usb_submit_urb (port->write_urb);
+       if (result)
+               err(__FUNCTION__ " - failed submitting write urb, error %d", result);
+       else
+               result = count;
+
+       return result;
 }
 
-static int pl2303_chars_in_buffer(struct usb_serial_port *port)
-{
-       struct pl2303_private *info = (struct pl2303_private *)port->private;
-
-       if (!info)
-               return 0;
-
-       return info->xmit_cnt;
-}
-
-static void pl2303_throttle(struct usb_serial_port *port)
-{
-#if 0
-       //struct usb_serial *serial = port->serial;
-       struct tty_struct *tty=port->tty;
-       unsigned long flags;
-
-
-       char    buf[64];
-
-       dbg("throttle %s: %d....", tty_name(tty, buf),
-           tty->ldisc.chars_in_buffer(tty));
-
-//FIXME FIXME FIXME    
-       if (I_IXOFF(tty))
-               rs_send_xchar(tty, STOP_CHAR(tty));
-
-       PL2303_LOCK(port,flags);
-       //Should remove read request if one is present
-       PL2303_UNLOCK(port,flags);
-#endif
-}
-
-static void pl2303_unthrottle(struct usb_serial_port *port)
-{
-#if 0
-       //struct usb_serial *serial = port->serial;
-       struct tty_struct *tty=port->tty;
-       unsigned long flags;
-
-
-       char    buf[64];
-
-       dbg("unthrottle %s: %d....", tty_name(tty, buf),
-           tty->ldisc.chars_in_buffer(tty));
-
-       //FIXME FIXME FIXME FIXME FIXME
-       if (I_IXOFF(tty)) {
-               if (info->x_char)
-                       info->x_char = 0;
-               else
-                       rs_send_xchar(tty, START_CHAR(tty));
-       }
-
-       PL2303_LOCK(port,flags);
-       //Should add read request if one is not present
-       PL2303_UNLOCK(fport,flags);
-#endif
-}
 
 
 static void
@@ -314,6 +174,10 @@ pl2303_set_termios (struct usb_serial_port *port, struct termios *old_termios)
 
        if (cflag & CSIZE) {
                switch (cflag & CSIZE) {
+                       case CS5:
+                               buf[6] = 5;
+                               dbg ("Setting CS5");
+                               break;
                        case CS6:
                                buf[6] = 6;
                                dbg ("Setting CS6");
@@ -327,47 +191,29 @@ pl2303_set_termios (struct usb_serial_port *port, struct termios *old_termios)
                                dbg ("Setting CS8");
                                break;
                        default:
-                               err ("CSIZE was set but not CS6-CS8");
+                               err ("CSIZE was set but not CS5-CS8");
                }
        }
 
        baud = 0;
        switch (cflag & CBAUD) {
-               case B0:
-                       err ("Can't do B0 yet");  //FIXME
-                       break;
-               case B300:
-                       baud = 300;
-                       break;
-               case B600:
-                       baud = 600;
-                       break;
-               case B1200:
-                       baud = 1200;
-                       break;
-               case B2400:
-                       baud = 2400;
-                       break;
-               case B4800:
-                       baud = 4800;
-                       break;
-               case B9600:
-                       baud = 9600;
-                       break;
-               case B19200:
-                       baud = 19200;
-                       break;
-               case B38400:
-                       baud = 38400;
-                       break;
-               case B57600:
-                       baud = 57600;
-                       break;
-               case B115200:
-                       baud = 115200;
-                       break;
+               case B75:       baud = 75;      break;
+               case B150:      baud = 150;     break;
+               case B300:      baud = 300;     break;
+               case B600:      baud = 600;     break;
+               case B1200:     baud = 1200;    break;
+               case B1800:     baud = 1800;    break;
+               case B2400:     baud = 2400;    break;
+               case B4800:     baud = 4800;    break;
+               case B9600:     baud = 9600;    break;
+               case B19200:    baud = 19200;   break;
+               case B38400:    baud = 38400;   break;
+               case B57600:    baud = 57600;   break;
+               case B115200:   baud = 115200;  break;
+               case B230400:   baud = 230400;  break;
+               case B460800:   baud = 460800;  break;
                default:
-                       dbg ("pl2303 driver does not support the baudrate requested (fix it)");
+                       err ("pl2303 driver does not support the baudrate requested (fix it)");
                        break;
        }
 
@@ -379,7 +225,9 @@ pl2303_set_termios (struct usb_serial_port *port, struct termios *old_termios)
        }
 
 
+       /* For reference buf[4]=0 is 1 stop bits */
        /* For reference buf[4]=1 is 1.5 stop bits */
+       /* For reference buf[4]=2 is 2 stop bits */
 
        if (cflag & CSTOPB) {
                buf[4] = 2;
@@ -387,6 +235,9 @@ pl2303_set_termios (struct usb_serial_port *port, struct termios *old_termios)
 
 
        if (cflag & PARENB) {
+               /* For reference buf[5]=0 is none parity */
+               /* For reference buf[5]=1 is odd parity */
+               /* For reference buf[5]=2 is even parity */
                /* For reference buf[5]=3 is mark parity */
                /* For reference buf[5]=4 is space parity */
                if (cflag & PARODD) {
@@ -433,169 +284,108 @@ pl2303_set_termios (struct usb_serial_port *port, struct termios *old_termios)
 }       
 
 
-static int
-pl2303_open (struct usb_serial_port *port, struct file *filp)
-{                              /* pl2303_open */
+static int pl2303_open (struct usb_serial_port *port, struct file *filp)
+{
        struct termios tmp_termios;
        struct usb_serial *serial = port->serial;
        unsigned char buf[10];
-       int i;
-
-       dbg ("pl2303_open port %d", port->number);
+       int result;
 
-       port->active++;
-
-#define FISH(a,b,c,d) \
-       i=usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev,0), \
-                   b, a,c  , d, buf, 1, 100); \
-       dbg("0x%x:0x%x:0x%x:0x%x  %d - %x",a,b,c,d,i,buf[0]);
-
-#define SOUP(a,b,c,d) \
-       i=usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev,0), \
-                   b, a,c  , d, NULL, 0, 100); \
-       dbg("0x%x:0x%x:0x%x:0x%x  %d",a,b,c,d,i);
-
-
-       FISH (0xc0, 1, 0x8484, 0);
-       SOUP (0x40, 1, 0x0404, 0);
-       FISH (0xc0, 1, 0x8484, 0);
-       FISH (0xc0, 1, 0x8383, 0);
-       FISH (0xc0, 1, 0x8484, 0);
-       SOUP (0x40, 1, 0x0404, 1);
-       FISH (0xc0, 1, 0x8484, 0);
-       FISH (0xc0, 1, 0x8383, 0);
-       SOUP (0x40, 1, 0, 1);
-       SOUP (0x40, 1, 1, 0xc0);
-       SOUP (0x40, 1, 2, 4);
-
-       /* Setup termios */
-
-       if (port->active == 1) {
+       if (port_paranoia_check (port, __FUNCTION__))
+               return -ENODEV;
+               
+       dbg (__FUNCTION__ "-  port %d", port->number);
+
+       down (&port->sem);
+
+       ++port->open_count;
+       MOD_INC_USE_COUNT;
+
+       if (!port->active) {
+               port->active = 1;
+
+#define FISH(a,b,c,d)                                                                  \
+               result=usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev,0),     \
+                                      b, a, c, d, buf, 1, 100);                        \
+               dbg("0x%x:0x%x:0x%x:0x%x  %d - %x",a,b,c,d,result,buf[0]);
+
+#define SOUP(a,b,c,d)                                                                  \
+               result=usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev,0),     \
+                                      b, a, c , d, NULL, 0, 100);                      \
+               dbg("0x%x:0x%x:0x%x:0x%x  %d",a,b,c,d,result);
+
+               FISH (0xc0, 1, 0x8484, 0);
+               SOUP (0x40, 1, 0x0404, 0);
+               FISH (0xc0, 1, 0x8484, 0);
+               FISH (0xc0, 1, 0x8383, 0);
+               FISH (0xc0, 1, 0x8484, 0);
+               SOUP (0x40, 1, 0x0404, 1);
+               FISH (0xc0, 1, 0x8484, 0);
+               FISH (0xc0, 1, 0x8383, 0);
+               SOUP (0x40, 1, 0, 1);
+               SOUP (0x40, 1, 1, 0xc0);
+               SOUP (0x40, 1, 2, 4);
+
+               /* Setup termios */
                *(port->tty->termios) = tty_std_termios;
                port->tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-       }
-
 
-       pl2303_set_termios (port, &tmp_termios);
+               pl2303_set_termios (port, &tmp_termios);
 
-       //FIXME: need to assert RTS and DTR if CRTSCTS off
+               //FIXME: need to assert RTS and DTR if CRTSCTS off
 
-
-       if (port->active == 1) {
-               struct pl2303_private *info;
-               unsigned long flags,page;
-               int i;
-
-               info = (struct pl2303_private *)kmalloc (sizeof(struct pl2303_private), GFP_KERNEL);
-               if (info == NULL) {
-                       err(__FUNCTION__ " - out of memory");
-                       pl2303_close (port, NULL);
-                       return -ENOMEM;
-               }
-               spin_lock_init(&info->lock);
-               port->private = info;
-
-
-               page = get_free_page(GFP_KERNEL);
-               if (!page) {
-                       pl2303_close (port, NULL);
-                       return -ENOMEM;
-               }
-
-               PL2303_LOCK(port,flags);
-
-               info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-
-               if (tmp_buf)
-                       free_page(page);
-               else
-                       tmp_buf = (unsigned char *) page;
-
-               PL2303_UNLOCK(port,flags);
-
-               page = get_free_page(GFP_KERNEL);
-               if (!page) {
-                       pl2303_close (port, NULL);
-                       return -ENOMEM;
-               }
-
-               PL2303_LOCK(port,flags);
-
-               if (info->xmit_buf)
-                       free_page(page);
-               else
-                       info->xmit_buf=(unsigned char *) page;
-
-               PL2303_UNLOCK(port,flags);
-
-
-               if ((i = usb_submit_urb (port->read_urb))) {
-                       err ("usb_submit_urb(read bulk 1) failed");
-                       dbg ("i=%d", i);
+               port->read_urb->dev = serial->dev;
+               result = usb_submit_urb (port->read_urb);
+               if (result) {
+                       err(__FUNCTION__ " - failed submitting read urb, error %d", result);
+                       up (&port->sem);
                        pl2303_close (port, NULL);
                        return -EPROTO;
-
                }
 
-               if ((i = usb_submit_urb (port->interrupt_in_urb))) {
-                       err ("usb_submit_urb(interrupt ink) failed");
-                       dbg ("i=%d", i);
+               port->interrupt_in_urb->dev = serial->dev;
+               result = usb_submit_urb (port->interrupt_in_urb);
+               if (result) {
+                       err(__FUNCTION__ " - failed submitting interrupt urb, error %d", result);
+                       up (&port->sem);
                        pl2303_close (port, NULL);
-
                        return -EPROTO;
                }
        }
+       up (&port->sem);
+       return 0;
+}
 
-       return(0);
-}                              /* pl2303_open */
 
+static void pl2303_close (struct usb_serial_port *port, struct file *filp)
+{
+       unsigned int c_cflag;
 
-static void
-pl2303_close (struct usb_serial_port *port, struct file *filp)
-{                              /* pl2303_close */
-       struct pl2303_private *info;
-       unsigned int c_cflag = port->tty->termios->c_cflag;
-       unsigned long flags;
+       if (port_paranoia_check (port, __FUNCTION__))
+               return;
 
-       dbg ("pl2303_close port %d", port->number);
+       dbg (__FUNCTION__ " - port %d", port->number);
 
-       /* shutdown our bulk reads and writes */
-       if (port->active == 1) {
+       down (&port->sem);
 
+       --port->open_count;
+       if (port->open_count <= 0) {
+               c_cflag = port->tty->termios->c_cflag;
                if (c_cflag & HUPCL) {
                        //FIXME: Do drop DTR
                        //FIXME: Do drop RTS
                }
 
+               /* shutdown our urbs */
                usb_unlink_urb (port->write_urb);
                usb_unlink_urb (port->read_urb);
                usb_unlink_urb (port->interrupt_in_urb);
 
-               info = (struct pl2303_private *)port->private;
-               if (info) {
-                       PL2303_LOCK(port,flags);
-                       if (info->xmit_buf) {
-                               unsigned char * temp;
-                               temp = info->xmit_buf;
-                               info->xmit_buf = 0;
-                               free_page((unsigned long) temp);
-                       }
-                       PL2303_UNLOCK(port,flags);
-               }
-
-               //FIXME: tmp_buf memory leak
-
-
+               port->active = 0;
+               port->open_count = 0;
        }
-       port->active--;
-}                              /* pl2303_close */
-
 
-/* do some startup allocations not currently performed by usb_serial_probe() */
-static int
-pl2303_startup (struct usb_serial *serial)
-{
-       return(0);
+       up (&port->sem);
 }
 
 
@@ -664,166 +454,105 @@ pl2303_read_int_callback (struct urb *urb)
                return;
        }
 
-
+       usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, urb->transfer_buffer);
 #if 0
 //FIXME need to update state of terminal lines variable
-       if (urb->actual_length) {
-               printk (KERN_DEBUG __FILE__ ": INT data read - length = %d, data = ",
-                       urb->actual_length);
-               for (i = 0; i < urb->actual_length; ++i) {
-                       printk ("%.2x ", data[i]);
-               }
-               printk ("\n");
-       }
 #endif
 
        return;
 }
 
-static void
-pl2303_read_bulk_callback (struct urb *urb)
+
+static void pl2303_read_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
-       struct usb_serial *serial = get_usb_serial (port, "pl2303_read_bulk_callback");
+       struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
        struct tty_struct *tty;
        unsigned char *data = urb->transfer_buffer;
        int i;
+       int result;
+
+       if (port_paranoia_check (port, __FUNCTION__))
+               return;
+
+       dbg(__FUNCTION__ " - port %d", port->number);
 
        if (!serial) {
+               dbg(__FUNCTION__ " - bad serial pointer, exiting");
                return;
        }
 
-// PL2303 mysteriously fails with -EPROTO reschedule the read
+       /* PL2303 mysteriously fails with -EPROTO reschedule the read */
        if (urb->status) {
                urb->status = 0;
-               if (usb_submit_urb (urb))
-                       dbg ("failed resubmitting read bulk urb");
+               urb->dev = serial->dev;
+               result = usb_submit_urb(urb);
+               if (result)
+                       err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
                return;
        }
 
-       if (debug) {
-               if (urb->actual_length) {
-                       printk (KERN_DEBUG __FILE__ ": BULK data read - length = %d, data = ",
-                               urb->actual_length);
-                       for (i = 0; i < urb->actual_length; ++i) {
-                               printk ("%.2x ", data[i]);
-                       }
-                       printk ("\n");
-               }
-       }
+       usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
 
        tty = port->tty;
        if (urb->actual_length) {
                for (i = 0; i < urb->actual_length; ++i) {
                        if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-                               dbg ("ARGH ------------ Flip buffer overrun...");
-
-                               break;
+                               tty_flip_buffer_push(tty);
                        }
                        tty_insert_flip_char (tty, data[i], 0);
                }
                tty_flip_buffer_push (tty);
        }
 
-
        /* Schedule the next read*/
-       if (usb_submit_urb (urb))
-               dbg ("failed submitting read bulk urb");
+       urb->dev = serial->dev;
+       result = usb_submit_urb(urb);
+       if (result)
+               err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
 
        return;
 }
 
 
 
-static void
-pl2303_write_bulk_callback (struct urb *urb)
+static void pl2303_write_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
-       struct usb_serial *serial;
-       struct tty_struct *tty = port->tty;
-
-       dbg ("pl2303_write_bulk_callback");
-
-
-       if (port_paranoia_check (port, "pl2303_write_bulk_callback")) {
-               return;
-       }
+       int result;
 
-       serial = port->serial;
-       if (serial_paranoia_check (serial, "pl2303_write_bulk_callback")) {
+       if (port_paranoia_check (port, __FUNCTION__))
                return;
-       }
-
-
+       
+       dbg(__FUNCTION__ " - port %d", port->number);
+       
        if (urb->status) {
-               dbg ("Overflow in write");
-               dbg ("nonzero write bulk status received: %d", urb->status);
-               //need to resubmit frame;
-
+               /* error in the urb, so we have to resubmit it */
+               if (serial_paranoia_check (port->serial, __FUNCTION__)) {
+                       return;
+               }
+               dbg (__FUNCTION__ " - Overflow in write");
+               dbg (__FUNCTION__ " - nonzero write bulk status received: %d", urb->status);
                port->write_urb->transfer_buffer_length = 1;
-
-               //Resubmit ourselves
-
-               if (usb_submit_urb (port->write_urb))
-                       err ("usb_submit_urb(write bulk) failed");
+               port->write_urb->dev = port->serial->dev;
+               result = usb_submit_urb (port->write_urb);
+               if (result)
+                       err(__FUNCTION__ " - failed resubmitting write urb, error %d", result);
 
                return;
        }
 
-       wake_up_interruptible (&port->write_wait);
-
-       if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
-               (tty->ldisc.write_wakeup) (tty);
-
-       wake_up_interruptible (&tty->write_wait);
-
-       start_xmit(port);
+       queue_task(&port->tqueue, &tq_immediate);
+       mark_bh(IMMEDIATE_BH);
 
        return;
 }
 
 
-
-static void
-start_xmit (struct usb_serial_port *port)
-{
-       struct usb_serial *serial;
-       struct pl2303_private *info;
-       unsigned long flags;
-
-       serial = port->serial;
-       info = (struct pl2303_private *)port->private;
-
-       if (info) {
-               PL2303_LOCK(port,flags);
-
-               if (port->write_urb->status != -EINPROGRESS) {
-                       if (info->xmit_tail != info->xmit_head) {
-
-                               memcpy (port->write_urb->transfer_buffer, &info->xmit_buf[info->xmit_tail],1);
-                               info->xmit_cnt--;
-                               info->xmit_tail = (info->xmit_tail + 1) & (SERIAL_XMIT_SIZE - 1);
-
-
-                               port->write_urb->transfer_buffer_length = 1;
-
-
-                               if (usb_submit_urb (port->write_urb))
-                                       err ("usb_submit_urb(write bulk) failed");
-
-
-                       }
-               }
-
-               PL2303_UNLOCK(port,flags);
-       }
-}
-
-
 static int __init pl2303_init (void)
 {
        usb_serial_register (&pl2303_device);
-       info(DRIVER_VERSION " : " DRIVER_DESC);
+       info(DRIVER_DESC " " DRIVER_VERSION);
        return 0;
 }
 
index cc23d93d6bb4c9c1a55fda32651d1b979e7c9a52..13d2693b4cbaa5fbbb7578d96d6955698cea75f2 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * USB HandSpring Visor driver
+ * USB HandSpring Visor, Palm m50x, and Sony Clie driver
+ * (supports all of the Palm OS USB devices)
  *
  *     Copyright (C) 1999 - 2001
  *         Greg Kroah-Hartman (greg@kroah.com)
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  * 
+ * (08/30/2001) gkh
+ *     Added support for the Clie devices, both the 3.5 and 4.0 os versions.
+ *     Many thanks to Daniel Burke, and Bryan Payne for helping with this.
+ *
  * (08/23/2001) gkh
  *     fixed a few potential bugs pointed out by Oliver Neukum.
  *
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.3"
+#define DRIVER_VERSION "v1.4"
 #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
-#define DRIVER_DESC "USB HandSpring Visor driver"
+#define DRIVER_DESC "USB HandSpring Visor, Palm m50x, Sony Clie driver"
 
 /* function prototypes for a handspring visor */
 static int  visor_open         (struct usb_serial_port *port, struct file *filp);
@@ -153,8 +158,13 @@ static __devinitdata struct usb_device_id palm_m505_id_table [] = {
        { }                                     /* Terminating entry */
 };
 
-static __devinitdata struct usb_device_id clie_id_table [] = {
-       { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_ID) },
+static __devinitdata struct usb_device_id clie_id_3_5_table [] = {
+       { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) },
+       { }                                     /* Terminating entry */
+};
+
+static __devinitdata struct usb_device_id clie_id_4_0_table [] = {
+       { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) },
        { }                                     /* Terminating entry */
 };
 
@@ -162,7 +172,8 @@ static __devinitdata struct usb_device_id id_table [] = {
        { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },
        { USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) },
        { USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) },
-       { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_ID) },
+       { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) },
+       { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) },
        { }                                     /* Terminating entry */
 };
 
@@ -248,10 +259,10 @@ struct usb_serial_device_type palm_m505_device = {
        read_bulk_callback:     visor_read_bulk_callback,
 };
 
-/* device info for the Sony Clie */
-static struct usb_serial_device_type clie_device = {
-       name:                   "Sony Clie",
-       id_table:               clie_id_table,
+/* device info for the Sony Clie OS version 3.5 */
+static struct usb_serial_device_type clie_3_5_device = {
+       name:                   "Sony Clie 3.5",
+       id_table:               clie_id_3_5_table,
        needs_interrupt_in:     MUST_HAVE_NOT,          /* this device must not have an interrupt in endpoint */
        needs_bulk_in:          MUST_HAVE,              /* this device must have a bulk in endpoint */
        needs_bulk_out:         MUST_HAVE,              /* this device must have a bulk out endpoint */
@@ -263,6 +274,31 @@ static struct usb_serial_device_type clie_device = {
        close:                  visor_close,
        throttle:               visor_throttle,
        unthrottle:             visor_unthrottle,
+       ioctl:                  visor_ioctl,
+       set_termios:            visor_set_termios,
+       write:                  visor_write,
+       write_room:             visor_write_room,
+       chars_in_buffer:        visor_chars_in_buffer,
+       write_bulk_callback:    visor_write_bulk_callback,
+       read_bulk_callback:     visor_read_bulk_callback,
+};
+
+/* device info for the Sony Clie OS version 4.0 */
+static struct usb_serial_device_type clie_4_0_device = {
+       name:                   "Sony Clie 4.0",
+       id_table:               clie_id_4_0_table,
+       needs_interrupt_in:     MUST_HAVE_NOT,          /* this device must not have an interrupt in endpoint */
+       needs_bulk_in:          MUST_HAVE,              /* this device must have a bulk in endpoint */
+       needs_bulk_out:         MUST_HAVE,              /* this device must have a bulk out endpoint */
+       num_interrupt_in:       0,
+       num_bulk_in:            2,
+       num_bulk_out:           2,
+       num_ports:              2,
+       open:                   visor_open,
+       close:                  visor_close,
+       throttle:               visor_throttle,
+       unthrottle:             visor_unthrottle,
+       startup:                visor_startup,
        shutdown:               visor_shutdown,
        ioctl:                  visor_ioctl,
        set_termios:            visor_set_termios,
@@ -605,10 +641,6 @@ static int  visor_startup (struct usb_serial *serial)
                return -ENOMEM;
        }
 
-       /* force debugging on for the palm devices for now */
-       if (serial->dev->descriptor.idVendor == PALM_VENDOR_ID)
-               debug = 1;
-
        dbg(__FUNCTION__);
 
        dbg(__FUNCTION__ " - Set config to 1");
@@ -650,8 +682,9 @@ static int  visor_startup (struct usb_serial *serial)
                }
        }
 
-       if (serial->dev->descriptor.idVendor == PALM_VENDOR_ID) {
-               /* Palm USB Hack */
+       if ((serial->dev->descriptor.idVendor == PALM_VENDOR_ID) ||
+           (serial->dev->descriptor.idVendor == SONY_VENDOR_ID)) {
+               /* Palm OS 4.0 Hack */
                response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), 
                                            PALM_GET_SOME_UNKNOWN_INFORMATION,
                                            0xc2, 0x0000, 0x0000, transfer_buffer, 
@@ -783,7 +816,8 @@ static int __init visor_init (void)
        usb_serial_register (&handspring_device);
        usb_serial_register (&palm_m500_device);
        usb_serial_register (&palm_m505_device);
-       usb_serial_register (&clie_device);
+       usb_serial_register (&clie_3_5_device);
+       usb_serial_register (&clie_4_0_device);
        
        /* create our write urb pool and transfer buffers */ 
        spin_lock_init (&write_urb_pool_lock);
@@ -817,7 +851,8 @@ static void __exit visor_exit (void)
        usb_serial_deregister (&handspring_device);
        usb_serial_deregister (&palm_m500_device);
        usb_serial_deregister (&palm_m505_device);
-       usb_serial_deregister (&clie_device);
+       usb_serial_deregister (&clie_3_5_device);
+       usb_serial_deregister (&clie_4_0_device);
 
        spin_lock_irqsave (&write_urb_pool_lock, flags);
 
index 37f896514869a4f202d93fffb2f015370998846b..c96b7823a94674908b7bbf8ff689a1bae84c02b6 100644 (file)
@@ -25,8 +25,8 @@
 #define PALM_M505_ID                   0x0002
 
 #define SONY_VENDOR_ID                 0x054C
-#define SONY_CLIE_ID                   0x0038
-#define SONY_CLIE_320_ID               0x0066
+#define SONY_CLIE_3_5_ID               0x0038
+#define SONY_CLIE_4_0_ID               0x0066
 
 /****************************************************************************
  * Handspring Visor Vendor specific request codes (bRequest values)
index 1e5c554f64432c0d00e1b2022a282745497a5c7b..4657eba0bf8129cb7ca833ce3c5831f7439422f0 100644 (file)
@@ -16,7 +16,7 @@
  * (C) Copyright 1999 Randy Dunlap
  * (C) Copyright 1999 Gregory P. Smith
  *
- * $Id: usb-uhci.c,v 1.267 2001/08/28 16:45:00 acher Exp $
+ * $Id: usb-uhci.c,v 1.268 2001/08/29 14:08:43 acher Exp $
  */
 
 #include <linux/config.h>
@@ -52,7 +52,7 @@
 /* This enables an extra UHCI slab for memory debugging */
 #define DEBUG_SLAB
 
-#define VERSTR "$Revision: 1.267 $ time " __TIME__ " " __DATE__
+#define VERSTR "$Revision: 1.268 $ time " __TIME__ " " __DATE__
 
 #include <linux/usb.h>
 #include "usb-uhci.h"
@@ -61,7 +61,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.267"
+#define DRIVER_VERSION "v1.268"
 #define DRIVER_AUTHOR "Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber"
 #define DRIVER_DESC "USB Universal Host Controller Interface driver"
 
@@ -1173,19 +1173,15 @@ _static int uhci_unlink_urb_sync (uhci_t *s, urb_t *urb)
 
        spin_lock_irqsave (&s->urb_list_lock, flags);
 
-       if (!in_interrupt())            // shouldn't be called from interrupt at all...
-               spin_lock(&urb->lock); 
-       
        if (urb->status == -EINPROGRESS) {
 
                // move descriptors out the the running chains, dequeue urb
                uhci_unlink_urb_async(s, urb, UNLINK_ASYNC_DONT_STORE);
 
-               if (!in_interrupt())    
-                       spin_unlock(&urb->lock); 
-               
                urb_priv = urb->hcpriv;
-
+               urb->status = -ENOENT;  // prevent from double deletion after unlock            
+               spin_unlock_irqrestore (&s->urb_list_lock, flags);
+               
                // cleanup the rest
                switch (usb_pipetype (urb->pipe)) {
 
@@ -1200,12 +1196,9 @@ _static int uhci_unlink_urb_sync (uhci_t *s, urb_t *urb)
                        uhci_clean_transfer(s, urb, qh, CLEAN_TRANSFER_DELETION_MARK);
                        uhci_wait_ms(1);
                }
-
-               spin_unlock_irqrestore (&s->urb_list_lock, flags);
-                               
-               uhci_urb_dma_unmap(s, urb, urb->hcpriv);
-
                urb->status = -ENOENT;  // mark urb as killed           
+                                       
+               uhci_urb_dma_unmap(s, urb, urb->hcpriv);
 
 #ifdef DEBUG_SLAB
                kmem_cache_free (urb_priv_kmem, urb->hcpriv);
@@ -1220,11 +1213,8 @@ _static int uhci_unlink_urb_sync (uhci_t *s, urb_t *urb)
                }
                usb_dec_dev_use (usb_dev);
        }
-       else {
-               if (!in_interrupt())    
-                       spin_unlock(&urb->lock); 
+       else
                spin_unlock_irqrestore (&s->urb_list_lock, flags);
-       }
 
        return 0;
 }
@@ -1334,22 +1324,12 @@ _static int uhci_unlink_urb (urb_t *urb)
 
        if (urb->transfer_flags & USB_ASYNC_UNLINK) {
                int ret;
-
                        spin_lock_irqsave (&s->urb_list_lock, flags);
-
-               // The URB needs to be locked if called outside completion context
-
-               if (!in_interrupt())
-                       spin_lock(&urb->lock);
-
+                       
                uhci_release_bandwidth(urb);
                ret = uhci_unlink_urb_async(s, urb, UNLINK_ASYNC_STORE_URB);
 
-               if (!in_interrupt())
-                       spin_unlock(&urb->lock);
-
                spin_unlock_irqrestore (&s->urb_list_lock, flags);      
-
                return ret;
        }
        else
@@ -1455,7 +1435,7 @@ _static int uhci_submit_int_urb (urb_t *urb)
 {
        uhci_t *s = (uhci_t*) urb->dev->bus->hcpriv;
        urb_priv_t *urb_priv = urb->hcpriv;
-       int nint, n, ret;
+       int nint, n;
        uhci_desc_t *td;
        int status, destination;
        int info;
@@ -2683,9 +2663,7 @@ _static int process_urb (uhci_t *s, struct list_head *p)
 
                                if (next_urb == urb)
                                        is_ring=1;
-                       }
-                       
-                       spin_lock(&urb->lock);
+                       }                       
 
                        // Submit idle/non-killed URBs linked with urb->next
                        // Stop before the current URB                          
@@ -2729,9 +2707,7 @@ _static int process_urb (uhci_t *s, struct list_head *p)
                                if (is_ring && !was_unlinked && !contains_killed) {
                                        urb->dev=usb_dev;
                                        uhci_submit_urb (urb);
-
                                }
-                               spin_unlock(&urb->lock);                
                                spin_lock(&s->urb_list_lock);
                        }
                        
diff --git a/drivers/usb/usbvideo.c b/drivers/usb/usbvideo.c
new file mode 100644 (file)
index 0000000..bed9911
--- /dev/null
@@ -0,0 +1,2474 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#define        __NO_VERSION__          /* Temporary: usbvideo is not a module yet */
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/smp_lock.h>
+#include <linux/vmalloc.h>
+#include <linux/wrapper.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+
+#include <asm/io.h>
+
+#include "usbvideo.h"
+
+#if defined(MAP_NR)
+#define        virt_to_page(v) MAP_NR(v)       /* Kernels 2.2.x */
+#endif
+
+static int video_nr = -1;
+MODULE_PARM(video_nr, "i");
+
+/*
+ * Local prototypes.
+ */
+#if USES_PROC_FS
+static void usbvideo_procfs_level1_create(usbvideo_t *ut);
+static void usbvideo_procfs_level1_destroy(usbvideo_t *ut);
+static void usbvideo_procfs_level2_create(uvd_t *uvd);
+static void usbvideo_procfs_level2_destroy(uvd_t *uvd);
+static int usbvideo_default_procfs_read_proc(
+       char *page, char **start, off_t off, int count,
+       int *eof, void *data);
+static int usbvideo_default_procfs_write_proc(
+       struct file *file, const char *buffer, 
+       unsigned long count, void *data);
+#endif
+
+/*******************************/
+/* Memory management functions */
+/*******************************/
+
+#define MDEBUG(x)      do { } while(0)         /* Debug memory management */
+
+/* Given PGD from the address space's page table, return the kernel
+ * virtual mapping of the physical memory mapped at ADR.
+ */
+unsigned long usbvideo_uvirt_to_kva(pgd_t *pgd, unsigned long adr)
+{
+       unsigned long ret = 0UL;
+       pmd_t *pmd;
+       pte_t *ptep, pte;
+
+       if (!pgd_none(*pgd)) {
+               pmd = pmd_offset(pgd, adr);
+               if (!pmd_none(*pmd)) {
+                       ptep = pte_offset(pmd, adr);
+                       pte = *ptep;
+                       if (pte_present(pte)) {
+                               ret = (unsigned long) page_address(pte_page(pte));
+                               ret |= (adr & (PAGE_SIZE-1));
+                       }
+               }
+       }
+       MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret));
+       return ret;
+}
+
+unsigned long usbvideo_uvirt_to_bus(unsigned long adr)
+{
+       unsigned long kva, ret;
+
+       kva = usbvideo_uvirt_to_kva(pgd_offset(current->mm, adr), adr);
+       ret = virt_to_bus((void *)kva);
+       MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret));
+       return ret;
+}
+
+unsigned long usbvideo_kvirt_to_bus(unsigned long adr)
+{
+       unsigned long va, kva, ret;
+
+       va = VMALLOC_VMADDR(adr);
+       kva = usbvideo_uvirt_to_kva(pgd_offset_k(va), va);
+       ret = virt_to_bus((void *)kva);
+       MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret));
+       return ret;
+}
+
+/*
+ * Here we want the physical address of the memory.
+ * This is used when initializing the contents of the
+ * area and marking the pages as reserved.
+ */
+unsigned long usbvideo_kvirt_to_pa(unsigned long adr)
+{
+       unsigned long va, kva, ret;
+
+       va = VMALLOC_VMADDR(adr);
+       kva = usbvideo_uvirt_to_kva(pgd_offset_k(va), va);
+       ret = __pa(kva);
+       MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));
+       return ret;
+}
+
+void *usbvideo_rvmalloc(unsigned long size)
+{
+       void *mem;
+       unsigned long adr, page;
+
+       /* Round it off to PAGE_SIZE */
+       size += (PAGE_SIZE - 1);
+       size &= ~(PAGE_SIZE - 1);
+
+       mem = vmalloc_32(size);
+       if (!mem)
+               return NULL;
+
+       memset(mem, 0, size); /* Clear the ram out, no junk to the user */
+       adr = (unsigned long) mem;
+       while (size > 0) {
+               page = usbvideo_kvirt_to_pa(adr);
+               mem_map_reserve(virt_to_page(__va(page)));
+               adr += PAGE_SIZE;
+               if (size > PAGE_SIZE)
+                       size -= PAGE_SIZE;
+               else
+                       size = 0;
+       }
+
+       return mem;
+}
+
+void usbvideo_rvfree(void *mem, unsigned long size)
+{
+       unsigned long adr, page;
+
+       if (!mem)
+               return;
+
+       size += (PAGE_SIZE - 1);
+       size &= ~(PAGE_SIZE - 1);
+
+       adr=(unsigned long) mem;
+       while (size > 0) {
+               page = usbvideo_kvirt_to_pa(adr);
+               mem_map_unreserve(virt_to_page(__va(page)));
+               adr += PAGE_SIZE;
+               if (size > PAGE_SIZE)
+                       size -= PAGE_SIZE;
+               else
+                       size = 0;
+       }
+       vfree(mem);
+}
+
+void RingQueue_Initialize(RingQueue_t *rq)
+{
+       assert(rq != NULL);
+       init_waitqueue_head(&rq->wqh);
+}
+
+void RingQueue_Allocate(RingQueue_t *rq, int rqLen)
+{
+       assert(rq != NULL);
+       assert(rqLen > 0);
+       rq->length = rqLen;
+       rq->queue = usbvideo_rvmalloc(rq->length);
+       assert(rq->queue != NULL);
+}
+
+int RingQueue_IsAllocated(const RingQueue_t *rq)
+{
+       if (rq == NULL)
+               return 0;
+       return (rq->queue != NULL) && (rq->length > 0);
+}
+
+void RingQueue_Free(RingQueue_t *rq)
+{
+       assert(rq != NULL);
+       if (RingQueue_IsAllocated(rq)) {
+               usbvideo_rvfree(rq->queue, rq->length);
+               rq->queue = NULL;
+               rq->length = 0;
+       }
+}
+
+int RingQueue_Dequeue(RingQueue_t *rq, unsigned char *dst, int len)
+{
+       int i;
+       assert(rq != NULL);
+       assert(dst != NULL);
+       for (i=0; i < len; i++) {
+               dst[i] = rq->queue[rq->ri];
+               RING_QUEUE_DEQUEUE_BYTES(rq,1);
+       }
+       return len;
+}
+
+int RingQueue_Enqueue(RingQueue_t *rq, const unsigned char *cdata, int n)
+{
+       int enqueued = 0;
+
+       assert(rq != NULL);
+       assert(cdata != NULL);
+       assert(rq->length > 0);
+       while (n > 0) {
+               int m, q_avail;
+
+               /* Calculate the largest chunk that fits the tail of the ring */
+               q_avail = rq->length - rq->wi;
+               if (q_avail <= 0) {
+                       rq->wi = 0;
+                       q_avail = rq->length;
+               }
+               m = n;
+               assert(q_avail > 0);
+               if (m > q_avail)
+                       m = q_avail;
+
+               memmove(rq->queue + rq->wi, cdata, m);
+               RING_QUEUE_ADVANCE_INDEX(rq, wi, m);
+               cdata += m;
+               enqueued += m;
+               n -= m;
+       }
+       return enqueued;
+}
+
+int RingQueue_GetLength(const RingQueue_t *rq)
+{
+       int ri, wi;
+
+       assert(rq != NULL);
+
+       ri = rq->ri;
+       wi = rq->wi;
+       if (ri == wi)
+               return 0;
+       else if (ri < wi)
+               return wi - ri;
+       else
+               return wi + (rq->length - ri);
+}
+
+void RingQueue_InterruptibleSleepOn(RingQueue_t *rq)
+{
+       assert(rq != NULL);
+       interruptible_sleep_on(&rq->wqh);
+}
+
+void RingQueue_WakeUpInterruptible(RingQueue_t *rq)
+{
+       assert(rq != NULL);
+       if (waitqueue_active(&rq->wqh))
+               wake_up_interruptible(&rq->wqh);
+}
+
+/*
+ * usbvideo_VideosizeToString()
+ *
+ * This procedure converts given videosize value to readable string.
+ *
+ * History:
+ * 07-Aug-2000 Created.
+ * 19-Oct-2000 Reworked for usbvideo module.
+ */
+void usbvideo_VideosizeToString(char *buf, int bufLen, videosize_t vs)
+{
+       char tmp[40];
+       int n;
+
+       n = 1 + sprintf(tmp, "%ldx%ld", VIDEOSIZE_X(vs), VIDEOSIZE_Y(vs));
+       assert(n < sizeof(tmp));
+       if ((buf == NULL) || (bufLen < n))
+               err("usbvideo_VideosizeToString: buffer is too small.");
+       else
+               memmove(buf, tmp, n);
+}
+
+/*
+ * usbvideo_OverlayChar()
+ *
+ * History:
+ * 01-Feb-2000 Created.
+ */
+void usbvideo_OverlayChar(uvd_t *uvd, usbvideo_frame_t *frame,
+                         int x, int y, int ch)
+{
+       static const unsigned short digits[16] = {
+               0xF6DE, /* 0 */
+               0x2492, /* 1 */
+               0xE7CE, /* 2 */
+               0xE79E, /* 3 */
+               0xB792, /* 4 */
+               0xF39E, /* 5 */
+               0xF3DE, /* 6 */
+               0xF492, /* 7 */
+               0xF7DE, /* 8 */
+               0xF79E, /* 9 */
+               0x77DA, /* a */
+               0xD75C, /* b */
+               0xF24E, /* c */
+               0xD6DC, /* d */
+               0xF34E, /* e */
+               0xF348  /* f */
+       };
+       unsigned short digit;
+       int ix, iy;
+
+       if ((uvd == NULL) || (frame == NULL))
+               return;
+
+       if (ch >= '0' && ch <= '9')
+               ch -= '0';
+       else if (ch >= 'A' && ch <= 'F')
+               ch = 10 + (ch - 'A');
+       else if (ch >= 'a' && ch <= 'f')
+               ch = 10 + (ch - 'a');
+       else
+               return;
+       digit = digits[ch];
+
+       for (iy=0; iy < 5; iy++) {
+               for (ix=0; ix < 3; ix++) {
+                       if (digit & 0x8000) {
+                               if (uvd->paletteBits & (1L << VIDEO_PALETTE_RGB24)) {
+/* TODO */                             RGB24_PUTPIXEL(frame, x+ix, y+iy, 0xFF, 0xFF, 0xFF);
+                               }
+                       }
+                       digit = digit << 1;
+               }
+       }
+}
+
+/*
+ * usbvideo_OverlayString()
+ *
+ * History:
+ * 01-Feb-2000 Created.
+ */
+void usbvideo_OverlayString(uvd_t *uvd, usbvideo_frame_t *frame,
+                           int x, int y, const char *str)
+{
+       while (*str) {
+               usbvideo_OverlayChar(uvd, frame, x, y, *str);
+               str++;
+               x += 4; /* 3 pixels character + 1 space */
+       }
+}
+
+/*
+ * usbvideo_OverlayStats()
+ *
+ * Overlays important debugging information.
+ *
+ * History:
+ * 01-Feb-2000 Created.
+ */
+void usbvideo_OverlayStats(uvd_t *uvd, usbvideo_frame_t *frame)
+{
+       const int y_diff = 8;
+       char tmp[16];
+       int x = 10, y=10;
+       long i, j, barLength;
+       const int qi_x1 = 60, qi_y1 = 10;
+       const int qi_x2 = VIDEOSIZE_X(frame->request) - 10, qi_h = 10;
+
+       /* Call the user callback, see if we may proceed after that */
+       if (VALID_CALLBACK(uvd, overlayHook)) {
+               if (GET_CALLBACK(uvd, overlayHook)(uvd, frame) < 0)
+                       return;
+       }
+
+       /*
+        * We draw a (mostly) hollow rectangle with qi_xxx coordinates.
+        * Left edge symbolizes the queue index 0; right edge symbolizes
+        * the full capacity of the queue.
+        */
+       barLength = qi_x2 - qi_x1 - 2;
+       if ((barLength > 10) && (uvd->paletteBits & (1L << VIDEO_PALETTE_RGB24))) {
+/* TODO */     long u_lo, u_hi, q_used;
+               long m_ri, m_wi, m_lo, m_hi;
+
+               /*
+                * Determine fill zones (used areas of the queue):
+                * 0 xxxxxxx u_lo ...... uvd->dp.ri xxxxxxxx u_hi ..... uvd->dp.length
+                *
+                * if u_lo < 0 then there is no first filler.
+                */
+
+               q_used = RingQueue_GetLength(&uvd->dp);
+               if ((uvd->dp.ri + q_used) >= uvd->dp.length) {
+                       u_hi = uvd->dp.length;
+                       u_lo = (q_used + uvd->dp.ri) % uvd->dp.length;
+               } else {
+                       u_hi = (q_used + uvd->dp.ri);
+                       u_lo = -1;
+               }
+
+               /* Convert byte indices into screen units */
+               m_ri = qi_x1 + ((barLength * uvd->dp.ri) / uvd->dp.length);
+               m_wi = qi_x1 + ((barLength * uvd->dp.wi) / uvd->dp.length);
+               m_lo = (u_lo > 0) ? (qi_x1 + ((barLength * u_lo) / uvd->dp.length)) : -1;
+               m_hi = qi_x1 + ((barLength * u_hi) / uvd->dp.length);
+
+               for (j=qi_y1; j < (qi_y1 + qi_h); j++) {
+                       for (i=qi_x1; i < qi_x2; i++) {
+                               /* Draw border lines */
+                               if ((j == qi_y1) || (j == (qi_y1 + qi_h - 1)) ||
+                                   (i == qi_x1) || (i == (qi_x2 - 1))) {
+                                       RGB24_PUTPIXEL(frame, i, j, 0xFF, 0xFF, 0xFF);
+                                       continue;
+                               }
+                               /* For all other points the Y coordinate does not matter */
+                               if ((i >= m_ri) && (i <= (m_ri + 3))) {
+                                       RGB24_PUTPIXEL(frame, i, j, 0x00, 0xFF, 0x00);
+                               } else if ((i >= m_wi) && (i <= (m_wi + 3))) {
+                                       RGB24_PUTPIXEL(frame, i, j, 0xFF, 0x00, 0x00);
+                               } else if ((i < m_lo) || ((i > m_ri) && (i < m_hi)))
+                                       RGB24_PUTPIXEL(frame, i, j, 0x00, 0x00, 0xFF);
+                       }
+               }
+       }
+
+       sprintf(tmp, "%8lx", uvd->stats.frame_num);
+       usbvideo_OverlayString(uvd, frame, x, y, tmp);
+       y += y_diff;
+
+       sprintf(tmp, "%8lx", uvd->stats.urb_count);
+       usbvideo_OverlayString(uvd, frame, x, y, tmp);
+       y += y_diff;
+
+       sprintf(tmp, "%8lx", uvd->stats.urb_length);
+       usbvideo_OverlayString(uvd, frame, x, y, tmp);
+       y += y_diff;
+
+       sprintf(tmp, "%8lx", uvd->stats.data_count);
+       usbvideo_OverlayString(uvd, frame, x, y, tmp);
+       y += y_diff;
+
+       sprintf(tmp, "%8lx", uvd->stats.header_count);
+       usbvideo_OverlayString(uvd, frame, x, y, tmp);
+       y += y_diff;
+
+       sprintf(tmp, "%8lx", uvd->stats.iso_skip_count);
+       usbvideo_OverlayString(uvd, frame, x, y, tmp);
+       y += y_diff;
+
+       sprintf(tmp, "%8lx", uvd->stats.iso_err_count);
+       usbvideo_OverlayString(uvd, frame, x, y, tmp);
+       y += y_diff;
+
+       sprintf(tmp, "%8x", uvd->vpic.colour);
+       usbvideo_OverlayString(uvd, frame, x, y, tmp);
+       y += y_diff;
+
+       sprintf(tmp, "%8x", uvd->vpic.hue);
+       usbvideo_OverlayString(uvd, frame, x, y, tmp);
+       y += y_diff;
+
+       sprintf(tmp, "%8x", uvd->vpic.brightness >> 8);
+       usbvideo_OverlayString(uvd, frame, x, y, tmp);
+       y += y_diff;
+
+       sprintf(tmp, "%8x", uvd->vpic.contrast >> 12);
+       usbvideo_OverlayString(uvd, frame, x, y, tmp);
+       y += y_diff;
+
+       sprintf(tmp, "%8d", uvd->vpic.whiteness >> 8);
+       usbvideo_OverlayString(uvd, frame, x, y, tmp);
+       y += y_diff;
+}
+
+/*
+ * usbvideo_ReportStatistics()
+ *
+ * This procedure prints packet and transfer statistics.
+ *
+ * History:
+ * 14-Jan-2000 Corrected default multiplier.
+ */
+void usbvideo_ReportStatistics(const uvd_t *uvd)
+{
+       if ((uvd != NULL) && (uvd->stats.urb_count > 0)) {
+               unsigned long allPackets, badPackets, goodPackets, percent;
+               allPackets = uvd->stats.urb_count * CAMERA_URB_FRAMES;
+               badPackets = uvd->stats.iso_skip_count + uvd->stats.iso_err_count;
+               goodPackets = allPackets - badPackets;
+               /* Calculate percentage wisely, remember integer limits */
+               assert(allPackets != 0);
+               if (goodPackets < (((unsigned long)-1)/100))
+                       percent = (100 * goodPackets) / allPackets;
+               else
+                       percent = goodPackets / (allPackets / 100);
+               info("Packet Statistics: Total=%lu. Empty=%lu. Usage=%lu%%",
+                    allPackets, badPackets, percent);
+               if (uvd->iso_packet_len > 0) {
+                       unsigned long allBytes, xferBytes;
+                       char multiplier = ' ';
+                       allBytes = allPackets * uvd->iso_packet_len;
+                       xferBytes = uvd->stats.data_count;
+                       assert(allBytes != 0);
+                       if (xferBytes < (((unsigned long)-1)/100))
+                               percent = (100 * xferBytes) / allBytes;
+                       else
+                               percent = xferBytes / (allBytes / 100);
+                       /* Scale xferBytes for easy reading */
+                       if (xferBytes > 10*1024) {
+                               xferBytes /= 1024;
+                               multiplier = 'K';
+                               if (xferBytes > 10*1024) {
+                                       xferBytes /= 1024;
+                                       multiplier = 'M';
+                                       if (xferBytes > 10*1024) {
+                                               xferBytes /= 1024;
+                                               multiplier = 'G';
+                                               if (xferBytes > 10*1024) {
+                                                       xferBytes /= 1024;
+                                                       multiplier = 'T';
+                                               }
+                                       }
+                               }
+                       }
+                       info("Transfer Statistics: Transferred=%lu%cB Usage=%lu%%",
+                            xferBytes, multiplier, percent);
+               }
+       }
+}
+
+/*
+ * usbvideo_DrawLine()
+ *
+ * A standard implementation of Bresenham's line drawing algorithm.
+ * This procedure is provided primarily for debugging or demo
+ * purposes.
+ */
+void usbvideo_DrawLine(
+       usbvideo_frame_t *frame,
+       int x1, int y1,
+       int x2, int y2,
+       unsigned char cr, unsigned char cg, unsigned char cb)
+{
+       int i, dx, dy, np, d;
+       int dinc1, dinc2, x, xinc1, xinc2, y, yinc1, yinc2;
+
+       if ((dx = x2 - x1) < 0)
+               dx = -dx;
+       if ((dy = y2 - y1) < 0)
+               dy = -dy;
+       if (dx >= dy) {
+               np = dx + 1;
+               d = (2 * dy) - dx;
+               dinc1 = dy << 1;
+               dinc2 = (dy - dx) << 1;
+               xinc1 = 1;
+               xinc2 = 1;
+               yinc1 = 0;
+               yinc2 = 1;
+       } else {
+               np = dy + 1;
+               d = (2 * dx) - dy;
+               dinc1 = dx << 1;
+               dinc2 = (dx - dy) << 1;
+               xinc1 = 0;
+               xinc2 = 1;
+               yinc1 = 1;
+               yinc2 = 1;
+       }
+       /* Make sure x and y move in the right directions */
+       if (x1 > x2) {
+               xinc1 = -xinc1;
+               xinc2 = -xinc2;
+       }
+       if (y1 > y2) {
+               yinc1 = -yinc1;
+               yinc2 = -yinc2;
+       }
+       for (i=0, x=x1, y=y1; i < np; i++) {
+               if (frame->palette == VIDEO_PALETTE_RGB24) {
+/* TODO */             RGB24_PUTPIXEL(frame, x, y, cr, cg, cb);
+               }
+               if (d < 0) {
+                       d += dinc1;
+                       x += xinc1;
+                       y += yinc1;
+               } else {
+                       d += dinc2;
+                       x += xinc2;
+                       y += yinc2;
+               }
+       }
+}
+
+/*
+ * usbvideo_TestPattern()
+ *
+ * Procedure forms a test pattern (yellow grid on blue background).
+ *
+ * Parameters:
+ * fullframe: if TRUE then entire frame is filled, otherwise the procedure
+ *           continues from the current scanline.
+ * pmode      0: fill the frame with solid blue color (like on VCR or TV)
+ *           1: Draw a colored grid
+ *
+ * History:
+ * 01-Feb-2000 Created.
+ */
+void usbvideo_TestPattern(uvd_t *uvd, int fullframe, int pmode)
+{
+       static const char proc[] = "usbvideo_TestPattern";
+       usbvideo_frame_t *frame;
+       int num_cell = 0;
+       int scan_length = 0;
+       static int num_pass = 0;
+
+       if (uvd == NULL) {
+               err("%s: uvd == NULL", proc);
+               return;
+       }
+       if ((uvd->curframe < 0) || (uvd->curframe >= USBVIDEO_NUMFRAMES)) {
+               err("%s: uvd->curframe=%d.", proc, uvd->curframe);
+               return;
+       }
+
+       /* Grab the current frame */
+       frame = &uvd->frame[uvd->curframe];
+
+       /* Optionally start at the beginning */
+       if (fullframe) {
+               frame->curline = 0;
+               frame->seqRead_Length = 0;
+       }
+#if 0
+       {       /* For debugging purposes only */
+               char tmp[20];
+               usbvideo_VideosizeToString(tmp, sizeof(tmp), frame->request);
+               info("testpattern: frame=%s", tmp);
+       }
+#endif
+       /* Form every scan line */
+       for (; frame->curline < VIDEOSIZE_Y(frame->request); frame->curline++) {
+               int i;
+               unsigned char *f = frame->data +
+                       (VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL * frame->curline);
+               for (i=0; i < VIDEOSIZE_X(frame->request); i++) {
+                       unsigned char cb=0x80;
+                       unsigned char cg = 0;
+                       unsigned char cr = 0;
+
+                       if (pmode == 1) {
+                               if (frame->curline % 32 == 0)
+                                       cb = 0, cg = cr = 0xFF;
+                               else if (i % 32 == 0) {
+                                       if (frame->curline % 32 == 1)
+                                               num_cell++;
+                                       cb = 0, cg = cr = 0xFF;
+                               } else {
+                                       cb = ((num_cell*7) + num_pass) & 0xFF;
+                                       cg = ((num_cell*5) + num_pass*2) & 0xFF;
+                                       cr = ((num_cell*3) + num_pass*3) & 0xFF;
+                               }
+                       } else {
+                               /* Just the blue screen */
+                       }
+                               
+                       *f++ = cb;
+                       *f++ = cg;
+                       *f++ = cr;
+                       scan_length += 3;
+               }
+       }
+
+       frame->frameState = FrameState_Done;
+       frame->seqRead_Length += scan_length;
+       ++num_pass;
+
+       /* We do this unconditionally, regardless of FLAGS_OVERLAY_STATS */
+       usbvideo_OverlayStats(uvd, frame);
+}
+
+/*
+ * usbvideo_HexDump()
+ *
+ * A debugging tool. Prints hex dumps.
+ *
+ * History:
+ * 29-Jul-2000 Added printing of offsets.
+ */
+void usbvideo_HexDump(const unsigned char *data, int len)
+{
+       const int bytes_per_line = 32;
+       char tmp[128]; /* 32*3 + 5 */
+       int i, k;
+
+       for (i=k=0; len > 0; i++, len--) {
+               if (i > 0 && ((i % bytes_per_line) == 0)) {
+                       printk("%s\n", tmp);
+                       k=0;
+               }
+               if ((i % bytes_per_line) == 0)
+                       k += sprintf(&tmp[k], "%04x: ", i);
+               k += sprintf(&tmp[k], "%02x ", data[i]);
+       }
+       if (k > 0)
+               printk("%s\n", tmp);
+}
+
+/* Debugging aid */
+void usbvideo_SayAndWait(const char *what)
+{
+       wait_queue_head_t wq;
+       init_waitqueue_head(&wq);
+       info("Say: %s", what);
+       interruptible_sleep_on_timeout (&wq, HZ*3); /* Timeout */
+}
+
+/* ******************************************************************** */
+
+static void usbvideo_ClientIncModCount(uvd_t *uvd)
+{
+       static const char proc[] = "usbvideo_ClientIncModCount";
+       if (uvd == NULL) {
+               err("%s: uvd == NULL", proc);
+               return;
+       }
+       if (uvd->handle == NULL) {
+               err("%s: uvd->handle == NULL", proc);
+               return;
+       }
+       if (uvd->handle->md_module == NULL) {
+               err("%s: uvd->handle->md_module == NULL", proc);
+               return;
+       }
+       __MOD_INC_USE_COUNT(uvd->handle->md_module);
+}
+
+static void usbvideo_ClientDecModCount(uvd_t *uvd)
+{
+       static const char proc[] = "usbvideo_ClientDecModCount";
+       if (uvd == NULL) {
+               err("%s: uvd == NULL", proc);
+               return;
+       }
+       if (uvd->handle == NULL) {
+               err("%s: uvd->handle == NULL", proc);
+               return;
+       }
+       if (uvd->handle->md_module == NULL) {
+               err("%s: uvd->handle->md_module == NULL", proc);
+               return;
+       }
+       __MOD_DEC_USE_COUNT(uvd->handle->md_module);
+}
+
+int usbvideo_register(
+       usbvideo_t **pCams,
+       const int num_cams,
+       const int num_extra,
+       const char *driverName,
+       const usbvideo_cb_t *cbTbl,
+       struct module *md )
+{
+       static const char proc[] = "usbvideo_register";
+       usbvideo_t *cams;
+       int i, base_size;
+
+       /* Check parameters for sanity */
+       if ((num_cams <= 0) || (pCams == NULL) || (cbTbl == NULL)) {
+               err("%s: Illegal call", proc);
+               return -EINVAL;
+       }
+
+       /* Check registration callback - must be set! */
+       if (cbTbl->probe == NULL) {
+               err("%s: probe() is required!", proc);
+               return -EINVAL;
+       }
+
+       base_size = num_cams * sizeof(uvd_t) + sizeof(usbvideo_t);
+       cams = (usbvideo_t *) kmalloc(base_size, GFP_KERNEL);
+       if (cams == NULL) {
+               err("Failed to allocate %d. bytes for usbvideo_t", base_size);
+               return -ENOMEM;
+       }
+       dbg("%s: Allocated $%p (%d. bytes) for %d. cameras",
+           proc, cams, base_size, num_cams);
+       memset(cams, 0, base_size);
+
+       /* Copy callbacks, apply defaults for those that are not set */
+       memmove(&cams->cb, cbTbl, sizeof(cams->cb));
+       if (cams->cb.getFrame == NULL)
+               cams->cb.getFrame = usbvideo_GetFrame;
+       if (cams->cb.disconnect == NULL)
+               cams->cb.disconnect = usbvideo_Disconnect;
+#if USES_PROC_FS
+       /*
+        * If both /proc fs callbacks are NULL then we assume that the driver
+        * does not need procfs services at all. Leave them NULL.
+        */
+       cams->uses_procfs = (cams->cb.procfs_read != NULL) || (cams->cb.procfs_write == NULL);
+       if (cams->uses_procfs) {
+               if (cams->cb.procfs_read == NULL)
+                       cams->cb.procfs_read = usbvideo_default_procfs_read_proc;
+               if (cams->cb.procfs_write == NULL)
+                       cams->cb.procfs_write = usbvideo_default_procfs_write_proc;
+       }
+#else /* !USES_PROC_FS */
+       /* Report a warning so that user knows why there is no /proc entries */
+       if ((cams->cb.procfs_read != NULL) || (cams->cb.procfs_write == NULL)) {
+               dbg("%s: /proc fs support requested but not configured!", proc);
+       }
+#endif
+       cams->num_cameras = num_cams;
+       cams->cam = (uvd_t *) &cams[1];
+       cams->md_module = md;
+       if (cams->md_module == NULL)
+               warn("%s: module == NULL!", proc);
+       init_MUTEX(&cams->lock);        /* to 1 == available */
+
+       for (i = 0; i < num_cams; i++) {
+               uvd_t *up = &cams->cam[i];
+
+               up->handle = cams;
+
+               /* Allocate user_data separately because of kmalloc's limits */
+               if (num_extra > 0) {
+                       up->user_size = num_cams * num_extra;
+                       up->user_data = (char *) kmalloc(up->user_size, GFP_KERNEL);
+                       if (up->user_data == NULL) {
+                               up->user_size = 0;
+                               err("%s: Failed to allocate user_data (%d. bytes)",
+                                   proc, up->user_size);
+                               return -ENOMEM;
+                       }
+                       dbg("%s: Allocated cams[%d].user_data=$%p (%d. bytes)",
+                            proc, i, up->user_data, up->user_size);
+               }
+       }
+
+       /*
+        * Register ourselves with USB stack.
+        */
+       strcpy(cams->drvName, (driverName != NULL) ? driverName : "Unknown");
+       cams->usbdrv.name = cams->drvName;
+       cams->usbdrv.probe = cams->cb.probe;
+       cams->usbdrv.disconnect = cams->cb.disconnect;
+
+#if USES_PROC_FS
+       if (cams->uses_procfs) {
+               dbg("%s: Creating /proc filesystem entries.", proc);
+               usbvideo_procfs_level1_create(cams);
+       }
+#endif
+
+       /*
+        * Update global handle to usbvideo. This is very important
+        * because probe() can be called before usb_register() returns.
+        * If the handle is not yet updated then the probe() will fail.
+        */
+       *pCams = cams;
+       usb_register(&cams->usbdrv);
+
+       return 0;
+}
+
+/*
+ * usbvideo_Deregister()
+ *
+ * Procedure frees all usbvideo and user data structures. Be warned that
+ * if you had some dynamically allocated components in ->user field then
+ * you should free them before calling here.
+ */
+void usbvideo_Deregister(usbvideo_t **pCams)
+{
+       static const char proc[] = "usbvideo_deregister";
+       usbvideo_t *cams;
+       int i;
+
+       if (pCams == NULL) {
+               err("%s: pCams == NULL", proc);
+               return;
+       }
+       cams = *pCams;
+       if (cams == NULL) {
+               err("%s: cams == NULL", proc);
+               return;
+       }
+
+#if USES_PROC_FS
+       if (cams->uses_procfs) {
+               dbg("%s: Deregistering filesystem entries.", proc);
+               usbvideo_procfs_level1_destroy(cams);
+       }
+#endif
+
+       dbg("%s: Deregistering %s driver.", proc, cams->drvName);
+       usb_deregister(&cams->usbdrv);
+
+       dbg("%s: Deallocating cams=$%p (%d. cameras)", proc, cams, cams->num_cameras);
+       for (i=0; i < cams->num_cameras; i++) {
+               uvd_t *up = &cams->cam[i];
+               int warning = 0;
+
+               if (up->user_data != NULL) {
+                       if (up->user_size <= 0)
+                               ++warning;
+               } else {
+                       if (up->user_size > 0)
+                               ++warning;
+               }
+               if (warning) {
+                       err("%s: Warning: user_data=$%p user_size=%d.",
+                           proc, up->user_data, up->user_size);
+               } else {
+                       dbg("%s: Freeing %d. $%p->user_data=$%p",
+                           proc, i, up, up->user_data);
+                       kfree(up->user_data);
+               }
+       }
+       /* Whole array was allocated in one chunk */
+       dbg("%s: Freed %d uvd_t structures",
+           proc, cams->num_cameras);
+       kfree(cams);
+       *pCams = NULL;
+}
+
+/*
+ * usbvideo_Disconnect()
+ *
+ * This procedure stops all driver activity. Deallocation of
+ * the interface-private structure (pointed by 'ptr') is done now
+ * (if we don't have any open files) or later, when those files
+ * are closed. After that driver should be removable.
+ *
+ * This code handles surprise removal. The uvd->user is a counter which
+ * increments on open() and decrements on close(). If we see here that
+ * this counter is not 0 then we have a client who still has us opened.
+ * We set uvd->remove_pending flag as early as possible, and after that
+ * all access to the camera will gracefully fail. These failures should
+ * prompt client to (eventually) close the video device, and then - in
+ * usbvideo_v4l_close() - we decrement uvd->uvd_used and usage counter.
+ *
+ * History:
+ * 22-Jan-2000 Added polling of MOD_IN_USE to delay removal until all users gone.
+ * 27-Jan-2000 Reworked to allow pending disconnects; see xxx_close()
+ * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT).
+ * 19-Oct-2000 Moved to usbvideo module.
+ */
+void usbvideo_Disconnect(struct usb_device *dev, void *ptr)
+{
+       static const char proc[] = "usbvideo_Disconnect";
+       uvd_t *uvd = (uvd_t *) ptr;
+       int i;
+
+       if ((dev == NULL) || (uvd == NULL)) {
+               err("%s($%p,$%p): Illegal call.", proc, dev, ptr);
+               return;
+       }
+       usbvideo_ClientIncModCount(uvd);
+       if (uvd->debug > 0)
+               info("%s(%p,%p.)", proc, dev, ptr);
+
+       down(&uvd->lock);
+       uvd->remove_pending = 1; /* Now all ISO data will be ignored */
+
+       /* At this time we ask to cancel outstanding URBs */
+       usbvideo_StopDataPump(uvd);
+
+       for (i=0; i < USBVIDEO_NUMSBUF; i++)
+               usb_free_urb(uvd->sbuf[i].urb);
+
+       usb_dec_dev_use(uvd->dev);
+       uvd->dev = NULL;            /* USB device is no more */
+
+       if (uvd->user)
+               info("%s: In use, disconnect pending.", proc);
+       else
+               usbvideo_CameraRelease(uvd);
+       up(&uvd->lock);
+       info("USB camera disconnected.");
+
+       usbvideo_ClientDecModCount(uvd);
+}
+
+/*
+ * usbvideo_CameraRelease()
+ *
+ * This code does final release of uvd_t. This happens
+ * after the device is disconnected -and- all clients
+ * closed their files.
+ *
+ * History:
+ * 27-Jan-2000 Created.
+ */
+void usbvideo_CameraRelease(uvd_t *uvd)
+{
+       static const char proc[] = "usbvideo_CameraRelease";
+       if (uvd == NULL) {
+               err("%s: Illegal call", proc);
+               return;
+       }
+       video_unregister_device(&uvd->vdev);
+       if (uvd->debug > 0)
+               info("%s: Video unregistered.", proc);
+
+#if USES_PROC_FS
+       assert(uvd->handle != NULL);
+       if (uvd->handle->uses_procfs) {
+               dbg("%s: Removing /proc/%s/ filesystem entries.", proc, uvd->handle->drvName);
+               usbvideo_procfs_level2_destroy(uvd);
+       }
+#endif
+
+       RingQueue_Free(&uvd->dp);
+       if (VALID_CALLBACK(uvd, userFree))
+               GET_CALLBACK(uvd, userFree)(uvd);
+       uvd->uvd_used = 0;      /* This is atomic, no need to take mutex */
+}
+
+/*
+ * usbvideo_find_struct()
+ *
+ * This code searches the array of preallocated (static) structures
+ * and returns index of the first one that isn't in use. Returns -1
+ * if there are no free structures.
+ *
+ * History:
+ * 27-Jan-2000 Created.
+ */
+static int usbvideo_find_struct(usbvideo_t *cams)
+{
+       int u, rv = -1;
+
+       if (cams == NULL) {
+               err("No usbvideo_t handle?");
+               return -1;
+       }
+       down(&cams->lock);
+       for (u = 0; u < cams->num_cameras; u++) {
+               uvd_t *uvd = &cams->cam[u];
+               if (!uvd->uvd_used) /* This one is free */
+               {
+                       uvd->uvd_used = 1;      /* In use now */
+                       init_MUTEX(&uvd->lock); /* to 1 == available */
+                       uvd->dev = NULL;
+                       rv = u;
+                       break;
+               }
+       }
+       up(&cams->lock);
+       return rv;
+}
+
+uvd_t *usbvideo_AllocateDevice(usbvideo_t *cams)
+{
+       int i, devnum;
+       uvd_t *uvd = NULL;
+
+       if (cams == NULL) {
+               err("No usbvideo_t handle?");
+               return NULL;
+       }
+
+       devnum = usbvideo_find_struct(cams);
+       if (devnum == -1) {
+               err("IBM USB camera driver: Too many devices!");
+               return NULL;
+       }
+       uvd = &cams->cam[devnum];
+       dbg("Device entry #%d. at $%p", devnum, uvd);
+
+       /* Not relying upon caller we increase module counter ourselves */
+       usbvideo_ClientIncModCount(uvd);
+
+       down(&uvd->lock);
+       for (i=0; i < USBVIDEO_NUMSBUF; i++) {
+               uvd->sbuf[i].urb = usb_alloc_urb(FRAMES_PER_DESC);
+               if (uvd->sbuf[i].urb == NULL) {
+                       err("usb_alloc_urb(%d.) failed.", FRAMES_PER_DESC);
+                       uvd->uvd_used = 0;
+                       uvd = NULL;
+                       goto allocate_done;
+               }
+       }
+       uvd->user=0;
+       uvd->remove_pending = 0;
+       uvd->last_error = 0;
+       RingQueue_Initialize(&uvd->dp);
+
+       /* Initialize video device structure */
+       memset(&uvd->vdev, 0, sizeof(uvd->vdev));
+       i = sprintf(uvd->vdev.name, "%s USB Camera", cams->drvName);
+       if (i >= sizeof(uvd->vdev.name)) {
+               err("Wrote too much into uvd->vdev.name, expect trouble!");
+       }
+       uvd->vdev.type = VID_TYPE_CAPTURE;
+       uvd->vdev.hardware = VID_HARDWARE_CPIA;
+       uvd->vdev.open = usbvideo_v4l_open;
+       uvd->vdev.close = usbvideo_v4l_close;
+       uvd->vdev.read = usbvideo_v4l_read;
+       uvd->vdev.write = usbvideo_v4l_write;
+       uvd->vdev.ioctl = usbvideo_v4l_ioctl;
+       uvd->vdev.mmap = usbvideo_v4l_mmap;
+       uvd->vdev.initialize = usbvideo_v4l_initialize;
+       /*
+        * The client is free to overwrite those because we
+        * return control to the client's probe function right now.
+        */
+allocate_done:
+       up (&uvd->lock);
+       usbvideo_ClientDecModCount(uvd);
+       return uvd;
+}
+
+int usbvideo_RegisterVideoDevice(uvd_t *uvd)
+{
+       static const char proc[] = "usbvideo_RegisterVideoDevice";
+       char tmp1[20], tmp2[20];        /* Buffers for printing */
+
+       if (uvd == NULL) {
+               err("%s: Illegal call.", proc);
+               return -EINVAL;
+       }
+       if (uvd->video_endp == 0) {
+               info("%s: No video endpoint specified; data pump disabled.", proc);
+       }
+       if (uvd->paletteBits == 0) {
+               err("%s: No palettes specified!", proc);
+               return -EINVAL;
+       }
+       if (uvd->defaultPalette == 0) {
+               info("%s: No default palette!", proc);
+       }
+
+       uvd->max_frame_size = VIDEOSIZE_X(uvd->canvas) *
+               VIDEOSIZE_Y(uvd->canvas) * V4L_BYTES_PER_PIXEL;
+       usbvideo_VideosizeToString(tmp1, sizeof(tmp1), uvd->videosize);
+       usbvideo_VideosizeToString(tmp2, sizeof(tmp2), uvd->canvas);
+
+       if (uvd->debug > 0) {
+               info("%s: iface=%d. endpoint=$%02x paletteBits=$%08lx",
+                    proc, uvd->iface, uvd->video_endp, uvd->paletteBits);
+       }
+       if (video_register_device(&uvd->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
+               err("%s: video_register_device failed", proc);
+               return -EPIPE;
+       }
+       if (uvd->debug > 1) {
+               info("%s: video_register_device() successful", proc);
+       }
+       if (uvd->dev == NULL) {
+               err("%s: uvd->dev == NULL", proc);
+               return -EINVAL;
+       }
+
+       info("%s on /dev/video%d: canvas=%s videosize=%s",
+            (uvd->handle != NULL) ? uvd->handle->drvName : "???",
+            uvd->vdev.minor, tmp2, tmp1);
+
+#if USES_PROC_FS
+       assert(uvd->handle != NULL);
+       if (uvd->handle->uses_procfs) {
+               if (uvd->debug > 0) {
+                       info("%s: Creating /proc/%s/ filesystem entries.",
+                            proc, uvd->handle->drvName);
+               }
+               usbvideo_procfs_level2_create(uvd);
+       }
+#endif
+
+       usb_inc_dev_use(uvd->dev);
+       return 0;
+}
+
+/* ******************************************************************** */
+
+int usbvideo_v4l_initialize(struct video_device *dev)
+{
+       return 0;
+}
+
+long usbvideo_v4l_write(struct video_device *dev, const char *buf,
+                       unsigned long count, int noblock)
+{
+       return -EINVAL;
+}
+
+int usbvideo_v4l_mmap(struct video_device *dev, const char *adr, unsigned long size)
+{
+       uvd_t *uvd = (uvd_t *) dev;
+       unsigned long start = (unsigned long) adr;
+       unsigned long page, pos;
+
+       if (!CAMERA_IS_OPERATIONAL(uvd))
+               return -EFAULT;
+
+       if (size > (((2 * uvd->max_frame_size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
+               return -EINVAL;
+
+       pos = (unsigned long) uvd->fbuf;
+       while (size > 0) {
+               page = usbvideo_kvirt_to_pa(pos);
+               if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
+                       return -EAGAIN;
+
+               start += PAGE_SIZE;
+               pos += PAGE_SIZE;
+               if (size > PAGE_SIZE)
+                       size -= PAGE_SIZE;
+               else
+                       size = 0;
+       }
+
+       return 0;
+}
+
+/*
+ * usbvideo_v4l_open()
+ *
+ * This is part of Video 4 Linux API. The driver can be opened by one
+ * client only (checks internal counter 'uvdser'). The procedure
+ * then allocates buffers needed for video processing.
+ *
+ * History:
+ * 22-Jan-2000 Rewrote, moved scratch buffer allocation here. Now the
+ *             camera is also initialized here (once per connect), at
+ *             expense of V4L client (it waits on open() call).
+ * 27-Jan-2000 Used USBVIDEO_NUMSBUF as number of URB buffers.
+ * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT).
+ */
+int usbvideo_v4l_open(struct video_device *dev, int flags)
+{
+       static const char proc[] = "usbvideo_v4l_open";
+       uvd_t *uvd = (uvd_t *) dev;
+       const int sb_size = FRAMES_PER_DESC * uvd->iso_packet_len;
+       int i, errCode = 0;
+
+       if (uvd->debug > 1)
+               info("%s($%p,$%08x", proc, dev, flags);
+
+       usbvideo_ClientIncModCount(uvd);
+       down(&uvd->lock);
+
+       if (uvd->user) {
+               err("%s: Someone tried to open an already opened device!", proc);
+               errCode = -EBUSY;
+       } else {
+               /* Clear statistics */
+               memset(&uvd->stats, 0, sizeof(uvd->stats));
+
+               /* Clean pointers so we know if we allocated something */
+               for (i=0; i < USBVIDEO_NUMSBUF; i++)
+                       uvd->sbuf[i].data = NULL;
+
+               /* Allocate memory for the frame buffers */
+               uvd->fbuf_size = USBVIDEO_NUMFRAMES * uvd->max_frame_size;
+               uvd->fbuf = usbvideo_rvmalloc(uvd->fbuf_size);
+               RingQueue_Allocate(&uvd->dp, 128*1024); /* FIXME #define */
+               if ((uvd->fbuf == NULL) ||
+                   (!RingQueue_IsAllocated(&uvd->dp))) {
+                       err("%s: Failed to allocate fbuf or dp", proc);
+                       errCode = -ENOMEM;
+               } else {
+                       /* Allocate all buffers */
+                       for (i=0; i < USBVIDEO_NUMFRAMES; i++) {
+                               uvd->frame[i].frameState = FrameState_Unused;
+                               uvd->frame[i].data = uvd->fbuf + i*(uvd->max_frame_size);
+                               /*
+                                * Set default sizes in case IOCTL (VIDIOCMCAPTURE)
+                                * is not used (using read() instead).
+                                */
+                               uvd->frame[i].canvas = uvd->canvas;
+                               uvd->frame[i].seqRead_Index = 0;
+                       }
+                       for (i=0; i < USBVIDEO_NUMSBUF; i++) {
+                               uvd->sbuf[i].data = kmalloc(sb_size, GFP_KERNEL);
+                               if (uvd->sbuf[i].data == NULL) {
+                                       errCode = -ENOMEM;
+                                       break;
+                               }
+                       }
+               }
+               if (errCode != 0) {
+                       /* Have to free all that memory */
+                       if (uvd->fbuf != NULL) {
+                               usbvideo_rvfree(uvd->fbuf, uvd->fbuf_size);
+                               uvd->fbuf = NULL;
+                       }
+                       RingQueue_Free(&uvd->dp);
+                       for (i=0; i < USBVIDEO_NUMSBUF; i++) {
+                               if (uvd->sbuf[i].data != NULL) {
+                                       kfree (uvd->sbuf[i].data);
+                                       uvd->sbuf[i].data = NULL;
+                               }
+                       }
+               }
+       }
+
+       /* If so far no errors then we shall start the camera */
+       if (errCode == 0) {
+               /* Start data pump if we have valid endpoint */
+               if (uvd->video_endp != 0)
+                       errCode = usbvideo_StartDataPump(uvd);
+               if (errCode == 0) {
+                       if (VALID_CALLBACK(uvd, setupOnOpen)) {
+                               if (uvd->debug > 1)
+                                       info("%s: setupOnOpen callback", proc);
+                               errCode = GET_CALLBACK(uvd, setupOnOpen)(uvd);
+                               if (errCode < 0) {
+                                       err("%s: setupOnOpen callback failed (%d.).",
+                                           proc, errCode);
+                               } else if (uvd->debug > 1) {
+                                       info("%s: setupOnOpen callback successful", proc);
+                               }
+                       }
+                       if (errCode == 0) {
+                               uvd->settingsAdjusted = 0;
+                               if (uvd->debug > 1)
+                                       info("%s: Open succeeded.", proc);
+                               uvd->user++;
+                       }
+               }
+       }
+       up(&uvd->lock);
+       if (errCode != 0)
+               usbvideo_ClientDecModCount(uvd);
+       if (uvd->debug > 0)
+               info("%s: Returning %d.", proc, errCode);
+       return errCode;
+}
+
+/*
+ * usbvideo_v4l_close()
+ *
+ * This is part of Video 4 Linux API. The procedure
+ * stops streaming and deallocates all buffers that were earlier
+ * allocated in usbvideo_v4l_open().
+ *
+ * History:
+ * 22-Jan-2000 Moved scratch buffer deallocation here.
+ * 27-Jan-2000 Used USBVIDEO_NUMSBUF as number of URB buffers.
+ * 24-May-2000 Moved MOD_DEC_USE_COUNT outside of code that can sleep.
+ */
+void usbvideo_v4l_close(struct video_device *dev)
+{
+       static const char proc[] = "usbvideo_v4l_close";
+       uvd_t *uvd = (uvd_t *)dev;
+       int i;
+
+       if (uvd->debug > 1)
+               info("%s($%p)", proc, dev);
+
+       down(&uvd->lock);       
+       usbvideo_StopDataPump(uvd);
+       usbvideo_rvfree(uvd->fbuf, uvd->fbuf_size);
+       uvd->fbuf = NULL;
+       RingQueue_Free(&uvd->dp);
+
+       for (i=0; i < USBVIDEO_NUMSBUF; i++) {
+               kfree(uvd->sbuf[i].data);
+               uvd->sbuf[i].data = NULL;
+       }
+
+#if USBVIDEO_REPORT_STATS
+       usbvideo_ReportStatistics(uvd);
+#endif    
+
+       uvd->user--;
+       if (uvd->remove_pending) {
+               if (uvd->debug > 0)
+                       info("usbvideo_v4l_close: Final disconnect.");
+               usbvideo_CameraRelease(uvd);
+       }
+       up(&uvd->lock);
+       usbvideo_ClientDecModCount(uvd);
+
+       if (uvd->debug > 1)
+               info("%s: Completed.", proc);
+}
+
+/*
+ * usbvideo_v4l_ioctl()
+ *
+ * This is part of Video 4 Linux API. The procedure handles ioctl() calls.
+ *
+ * History:
+ * 22-Jan-2000 Corrected VIDIOCSPICT to reject unsupported settings.
+ */
+int usbvideo_v4l_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
+{
+       uvd_t *uvd = (uvd_t *)dev;
+
+       if (!CAMERA_IS_OPERATIONAL(uvd))
+               return -EFAULT;
+
+       switch (cmd) {
+               case VIDIOCGCAP:
+               {
+                       if (copy_to_user(arg, &uvd->vcap, sizeof(uvd->vcap)))
+                               return -EFAULT;
+                       return 0;
+               }
+               case VIDIOCGCHAN:
+               {
+                       if (copy_to_user(arg, &uvd->vchan, sizeof(uvd->vchan)))
+                               return -EFAULT;
+                       return 0;
+               }
+               case VIDIOCSCHAN:
+               {       /* Not used but we return success */
+                       int v;
+                       if (copy_from_user(&v, arg, sizeof(v)))
+                               return -EFAULT;
+                       return 0;
+               }
+               case VIDIOCGPICT:
+               {
+                       if (copy_to_user(arg, &uvd->vpic, sizeof(uvd->vpic)))
+                               return -EFAULT;
+                       return 0;
+               }
+               case VIDIOCSPICT:
+               {
+                       struct video_picture tmp;
+                       /*
+                        * Use temporary 'video_picture' structure to preserve our
+                        * own settings (such as color depth, palette) that we
+                        * aren't allowing everyone (V4L client) to change.
+                        */
+                       if (copy_from_user(&tmp, arg, sizeof(tmp)))
+                               return -EFAULT;
+                       uvd->vpic.brightness = tmp.brightness;
+                       uvd->vpic.hue = tmp.hue;
+                       uvd->vpic.colour = tmp.colour;
+                       uvd->vpic.contrast = tmp.contrast;
+                       uvd->settingsAdjusted = 0;      /* Will force new settings */
+                       return 0;
+               }
+               case VIDIOCSWIN:
+               {
+                       struct video_window vw;
+
+                       if (copy_from_user(&vw, arg, sizeof(vw)))
+                               return -EFAULT;
+                       if (vw.flags)
+                               return -EINVAL;
+                       if (vw.clipcount)
+                               return -EINVAL;
+                       if (vw.width != VIDEOSIZE_X(uvd->canvas))
+                               return -EINVAL;
+                       if (vw.height != VIDEOSIZE_Y(uvd->canvas))
+                               return -EINVAL;
+
+                       return 0;
+               }
+               case VIDIOCGWIN:
+               {
+                       struct video_window vw;
+
+                       vw.x = 0;
+                       vw.y = 0;
+                       vw.width = VIDEOSIZE_X(uvd->canvas);
+                       vw.height = VIDEOSIZE_Y(uvd->canvas);
+                       vw.chromakey = 0;
+                       if (VALID_CALLBACK(uvd, getFPS))
+                               vw.flags = GET_CALLBACK(uvd, getFPS)(uvd);
+                       else 
+                               vw.flags = 10; /* FIXME: do better! */
+
+                       if (copy_to_user(arg, &vw, sizeof(vw)))
+                               return -EFAULT;
+
+                       return 0;
+               }
+               case VIDIOCGMBUF:
+               {
+                       struct video_mbuf vm;
+
+                       memset(&vm, 0, sizeof(vm));
+                       vm.size = uvd->max_frame_size * 2;
+                       vm.frames = 2;
+                       vm.offsets[0] = 0;
+                       vm.offsets[1] = uvd->max_frame_size;
+
+                       if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
+                               return -EFAULT;
+
+                       return 0;
+               }
+               case VIDIOCMCAPTURE:
+               {
+                       struct video_mmap vm;
+
+                       if (copy_from_user((void *)&vm, (void *)arg, sizeof(vm))) {
+                               err("VIDIOCMCAPTURE: copy_from_user() failed.");
+                               return -EFAULT;
+                       }
+                       if (uvd->debug >= 1) {
+                               info("VIDIOCMCAPTURE: frame=%d. size=%dx%d, format=%d.",
+                                   vm.frame, vm.width, vm.height, vm.format);
+                       }
+                       /*
+                        * Check if the requested size is supported. If the requestor
+                        * requests too big a frame then we may be tricked into accessing
+                        * outside of own preallocated frame buffer (in uvd->frame).
+                        * This will cause oops or a security hole. Theoretically, we
+                        * could only clamp the size down to acceptable bounds, but then
+                        * we'd need to figure out how to insert our smaller buffer into
+                        * larger caller's buffer... this is not an easy question. So we
+                        * here just flatly reject too large requests, assuming that the
+                        * caller will resubmit with smaller size. Callers should know
+                        * what size we support (returned by VIDIOCGCAP). However vidcat,
+                        * for one, does not care and allows to ask for any size.
+                        */
+                       if ((vm.width > VIDEOSIZE_X(uvd->canvas)) ||
+                           (vm.height > VIDEOSIZE_Y(uvd->canvas))) {
+                               if (uvd->debug > 0) {
+                                       info("VIDIOCMCAPTURE: Size=%dx%d too large; "
+                                            "allowed only up to %ldx%ld", vm.width, vm.height,
+                                            VIDEOSIZE_X(uvd->canvas), VIDEOSIZE_Y(uvd->canvas));
+                               }
+                               return -EINVAL;
+                       }
+                       /* Check if the palette is supported */
+                       if (((1L << vm.format) & uvd->paletteBits) == 0) {
+                               if (uvd->debug > 0) {
+                                       info("VIDIOCMCAPTURE: format=%d. not supported"
+                                            " (paletteBits=$%08lx)",
+                                            vm.format, uvd->paletteBits);
+                               }
+                               return -EINVAL;
+                       }
+                       if ((vm.frame != 0) && (vm.frame != 1)) {
+                               err("VIDIOCMCAPTURE: vm.frame=%d. !E [0,1]", vm.frame);
+                               return -EINVAL;
+                       }
+                       if (uvd->frame[vm.frame].frameState == FrameState_Grabbing) {
+                               /* Not an error - can happen */
+                       }
+                       uvd->frame[vm.frame].request = VIDEOSIZE(vm.width, vm.height);
+                       uvd->frame[vm.frame].palette = vm.format;
+
+                       /* Mark it as ready */
+                       uvd->frame[vm.frame].frameState = FrameState_Ready;
+
+                       return usbvideo_NewFrame(uvd, vm.frame);
+               }
+               case VIDIOCSYNC:
+               {
+                       int frameNum, ret;
+
+                       if (copy_from_user((void *)&frameNum, arg, sizeof(frameNum))) {
+                               err("VIDIOCSYNC: copy_from_user() failed.");
+                               return -EFAULT;
+                       }
+                       if(frameNum < 0 || frameNum >= USBVIDEO_NUMFRAMES)
+                               return -EINVAL;
+                               
+                       if (uvd->debug >= 1)
+                               info("VIDIOCSYNC: syncing to frame %d.", frameNum);
+                       if (uvd->flags & FLAGS_NO_DECODING)
+                               ret = usbvideo_GetFrame(uvd, frameNum);
+                       else if (VALID_CALLBACK(uvd, getFrame)) {
+                               ret = GET_CALLBACK(uvd, getFrame)(uvd, frameNum);
+                               if ((ret < 0) && (uvd->debug >= 1)) {
+                                       err("VIDIOCSYNC: getFrame() returned %d.", ret);
+                               }
+                       } else {
+                               err("VIDIOCSYNC: getFrame is not set");
+                               ret = -EFAULT;
+                       }
+
+                       /*
+                        * The frame is in FrameState_Done_Hold state. Release it
+                        * right now because its data is already mapped into
+                        * the user space and it's up to the application to
+                        * make use of it until it asks for another frame.
+                        */
+                       uvd->frame[frameNum].frameState = FrameState_Unused;
+                       return ret;
+               }
+               case VIDIOCGFBUF:
+               {
+                       struct video_buffer vb;
+
+                       memset(&vb, 0, sizeof(vb));
+                       vb.base = NULL; /* frame buffer not supported, not used */
+
+                       if (copy_to_user((void *)arg, (void *)&vb, sizeof(vb)))
+                               return -EFAULT;
+
+                       return 0;
+               }
+               case VIDIOCKEY:
+                       return 0;
+
+               case VIDIOCCAPTURE:
+                       return -EINVAL;
+
+               case VIDIOCSFBUF:
+
+               case VIDIOCGTUNER:
+               case VIDIOCSTUNER:
+
+               case VIDIOCGFREQ:
+               case VIDIOCSFREQ:
+
+               case VIDIOCGAUDIO:
+               case VIDIOCSAUDIO:
+                       return -EINVAL;
+
+               default:
+                       return -ENOIOCTLCMD;
+       }
+       return 0;
+}
+
+/*
+ * usbvideo_v4l_read()
+ *
+ * This is mostly boring stuff. We simply ask for a frame and when it
+ * arrives copy all the video data from it into user space. There is
+ * no obvious need to override this method.
+ *
+ * History:
+ * 20-Oct-2000 Created.
+ * 01-Nov-2000 Added mutex (uvd->lock).
+ */
+long usbvideo_v4l_read(struct video_device *dev, char *buf, unsigned long count, int noblock)
+{
+       static const char proc[] = "usbvideo_v4l_read";
+       uvd_t *uvd = (uvd_t *) dev;
+       int frmx = -1;
+       usbvideo_frame_t *frame;
+
+       if (!CAMERA_IS_OPERATIONAL(uvd) || (buf == NULL))
+               return -EFAULT;
+
+       if (uvd->debug >= 1)
+               info("%s: %ld. bytes, noblock=%d.", proc, count, noblock);
+
+       down(&uvd->lock);       
+
+       /* See if a frame is completed, then use it. */
+       if ((uvd->frame[0].frameState == FrameState_Done) ||
+           (uvd->frame[0].frameState == FrameState_Done_Hold) ||
+           (uvd->frame[0].frameState == FrameState_Error)) {
+               frmx = 0;
+       } else if ((uvd->frame[1].frameState >= FrameState_Done) ||
+                  (uvd->frame[1].frameState == FrameState_Done_Hold) ||
+                  (uvd->frame[1].frameState >= FrameState_Done)) {
+               frmx = 1;
+       }
+
+       /* FIXME: If we don't start a frame here then who ever does? */
+       if (noblock && (frmx == -1)) {
+               count = -EAGAIN;
+               goto read_done;
+       }
+
+       /*
+        * If no FrameState_Done, look for a FrameState_Grabbing state.
+        * See if a frame is in process (grabbing), then use it.
+        * We will need to wait until it becomes cooked, of course.
+        */
+       if (frmx == -1) {
+               if (uvd->frame[0].frameState == FrameState_Grabbing)
+                       frmx = 0;
+               else if (uvd->frame[1].frameState == FrameState_Grabbing)
+                       frmx = 1;
+       }
+
+       /*
+        * If no frame is active, start one. We don't care which one
+        * it will be, so #0 is as good as any.
+        * In read access mode we don't have convenience of VIDIOCMCAPTURE
+        * to specify the requested palette (video format) on per-frame
+        * basis. This means that we have to return data in -some- format
+        * and just hope that the client knows what to do with it.
+        * The default format is configured in uvd->defaultPalette field
+        * as one of VIDEO_PALETTE_xxx values. We stuff it into the new
+        * frame and initiate the frame filling process.
+        */
+       if (frmx == -1) {
+               if (uvd->defaultPalette == 0) {
+                       err("%s: No default palette; don't know what to do!", proc);
+                       count = -EFAULT;
+                       goto read_done;
+               }
+               frmx = 0;
+               /*
+                * We have no per-frame control over video size.
+                * Therefore we only can use whatever size was
+                * specified as default.
+                */
+               uvd->frame[frmx].request = uvd->videosize;
+               uvd->frame[frmx].palette = uvd->defaultPalette;
+               uvd->frame[frmx].frameState = FrameState_Ready;
+               usbvideo_NewFrame(uvd, frmx);
+               /* Now frame 0 is supposed to start filling... */
+       }
+
+       /*
+        * Get a pointer to the active frame. It is either previously
+        * completed frame or frame in progress but not completed yet.
+        */
+       frame = &uvd->frame[frmx];
+
+       /*
+        * Sit back & wait until the frame gets filled and postprocessed.
+        * If we fail to get the picture [in time] then return the error.
+        * In this call we specify that we want the frame to be waited for,
+        * postprocessed and switched into FrameState_Done_Hold state. This
+        * state is used to hold the frame as "fully completed" between
+        * subsequent partial reads of the same frame.
+        */
+       if (frame->frameState != FrameState_Done_Hold) {
+               long rv = -EFAULT;
+               if (uvd->flags & FLAGS_NO_DECODING)
+                       rv = usbvideo_GetFrame(uvd, frmx);
+               else if (VALID_CALLBACK(uvd, getFrame))
+                       rv = GET_CALLBACK(uvd, getFrame)(uvd, frmx);
+               else
+                       err("getFrame is not set");
+               if ((rv != 0) || (frame->frameState != FrameState_Done_Hold)) {
+                       count = rv;
+                       goto read_done;
+               }
+       }
+
+       /*
+        * Copy bytes to user space. We allow for partial reads, which
+        * means that the user application can request read less than
+        * the full frame size. It is up to the application to issue
+        * subsequent calls until entire frame is read.
+        *
+        * First things first, make sure we don't copy more than we
+        * have - even if the application wants more. That would be
+        * a big security embarassment!
+        */
+       if ((count + frame->seqRead_Index) > frame->seqRead_Length)
+               count = frame->seqRead_Length - frame->seqRead_Index;
+
+       /*
+        * Copy requested amount of data to user space. We start
+        * copying from the position where we last left it, which
+        * will be zero for a new frame (not read before).
+        */
+       if (copy_to_user(buf, frame->data + frame->seqRead_Index, count)) {
+               count = -EFAULT;
+               goto read_done;
+       }
+
+       /* Update last read position */
+       frame->seqRead_Index += count;
+       if (uvd->debug >= 1) {
+               err("%s: {copy} count used=%ld, new seqRead_Index=%ld",
+                       proc, count, frame->seqRead_Index);
+       }
+
+       /* Finally check if the frame is done with and "release" it */
+       if (frame->seqRead_Index >= frame->seqRead_Length) {
+               /* All data has been read */
+               frame->seqRead_Index = 0;
+
+               /* Mark it as available to be used again. */
+               uvd->frame[frmx].frameState = FrameState_Unused;
+               if (usbvideo_NewFrame(uvd, frmx ? 0 : 1)) {
+                       err("%s: usbvideo_NewFrame failed.", proc);
+               }
+       }
+read_done:
+       up(&uvd->lock); 
+       return count;
+}
+
+/*
+ * Make all of the blocks of data contiguous
+ */
+static int usbvideo_CompressIsochronous(uvd_t *uvd, urb_t *urb)
+{
+       char *cdata;
+       int i, totlen = 0;
+
+       for (i = 0; i < urb->number_of_packets; i++) {
+               int n = urb->iso_frame_desc[i].actual_length;
+               int st = urb->iso_frame_desc[i].status;
+
+               cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
+
+               /* Detect and ignore errored packets */
+               if (st < 0) {
+                       if (uvd->debug >= 1)
+                               err("Data error: packet=%d. len=%d. status=%d.", i, n, st);
+                       uvd->stats.iso_err_count++;
+                       continue;
+               }
+
+               /* Detect and ignore empty packets */
+               if (n <= 0) {
+                       uvd->stats.iso_skip_count++;
+                       continue;
+               }
+               totlen += n;    /* Little local accounting */
+               RingQueue_Enqueue(&uvd->dp, cdata, n);
+       }
+       return totlen;
+}
+
+static void usbvideo_IsocIrq(struct urb *urb)
+{
+       int i, len;
+       uvd_t *uvd = urb->context;
+
+       /* We don't want to do anything if we are about to be removed! */
+       if (!CAMERA_IS_OPERATIONAL(uvd))
+               return;
+#if 0
+       if (urb->actual_length > 0) {
+               info("urb=$%p status=%d. errcount=%d. length=%d.",
+                    urb, urb->status, urb->error_count, urb->actual_length);
+       } else {
+               static int c = 0;
+               if (c++ % 100 == 0)
+                       info("No Isoc data");
+       }
+#endif
+
+       if (!uvd->streaming) {
+               if (uvd->debug >= 1)
+                       info("Not streaming, but interrupt!");
+               return;
+       }
+       
+       uvd->stats.urb_count++;
+       if (urb->actual_length <= 0)
+               goto urb_done_with;
+
+       /* Copy the data received into ring queue */
+       len = usbvideo_CompressIsochronous(uvd, urb);
+       uvd->stats.urb_length = len;
+       if (len <= 0)
+               goto urb_done_with;
+
+       /* Here we got some data */
+       uvd->stats.data_count += len;
+       RingQueue_WakeUpInterruptible(&uvd->dp);
+
+urb_done_with:
+       for (i = 0; i < FRAMES_PER_DESC; i++) {
+               urb->iso_frame_desc[i].status = 0;
+               urb->iso_frame_desc[i].actual_length = 0;
+       }
+       return;
+}
+
+/*
+ * usbvideo_StartDataPump()
+ *
+ * History:
+ * 27-Jan-2000 Used ibmcam->iface, ibmcam->ifaceAltActive instead
+ *             of hardcoded values. Simplified by using for loop,
+ *             allowed any number of URBs.
+ */
+int usbvideo_StartDataPump(uvd_t *uvd)
+{
+       static const char proc[] = "usbvideo_StartDataPump";
+       struct usb_device *dev = uvd->dev;
+       int i, errFlag;
+
+       if (uvd->debug > 1)
+               info("%s($%p)", proc, uvd);
+
+       if (!CAMERA_IS_OPERATIONAL(uvd)) {
+               err("%s: Camera is not operational",proc);
+               return -EFAULT;
+       }
+       uvd->curframe = -1;
+
+       /* Alternate interface 1 is is the biggest frame size */
+       i = usb_set_interface(dev, uvd->iface, uvd->ifaceAltActive);
+       if (i < 0) {
+               err("%s: usb_set_interface error", proc);
+               uvd->last_error = i;
+               return -EBUSY;
+       }
+       if (VALID_CALLBACK(uvd, videoStart))
+               GET_CALLBACK(uvd, videoStart)(uvd);
+       else 
+               err("%s: videoStart not set", proc);
+
+       /* We double buffer the Iso lists */
+       for (i=0; i < USBVIDEO_NUMSBUF; i++) {
+               int j, k;
+               urb_t *urb = uvd->sbuf[i].urb;
+               urb->dev = dev;
+               urb->context = uvd;
+               urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp);
+               urb->transfer_flags = USB_ISO_ASAP;
+               urb->transfer_buffer = uvd->sbuf[i].data;
+               urb->complete = usbvideo_IsocIrq;
+               urb->number_of_packets = FRAMES_PER_DESC;
+               urb->transfer_buffer_length = uvd->iso_packet_len * FRAMES_PER_DESC;
+               for (j=k=0; j < FRAMES_PER_DESC; j++, k += uvd->iso_packet_len) {
+                       urb->iso_frame_desc[j].offset = k;
+                       urb->iso_frame_desc[j].length = uvd->iso_packet_len;
+               }
+       }
+
+       /* Link URBs into a ring so that they invoke each other infinitely */
+       for (i=0; i < USBVIDEO_NUMSBUF; i++) {
+               if ((i+1) < USBVIDEO_NUMSBUF)
+                       uvd->sbuf[i].urb->next = uvd->sbuf[i+1].urb;
+               else
+                       uvd->sbuf[i].urb->next = uvd->sbuf[0].urb;
+       }
+
+       /* Submit all URBs */
+       for (i=0; i < USBVIDEO_NUMSBUF; i++) {
+               errFlag = usb_submit_urb(uvd->sbuf[i].urb);
+               if (errFlag)
+                       err("%s: usb_submit_isoc(%d) ret %d", proc, i, errFlag);
+       }
+
+       uvd->streaming = 1;
+       if (uvd->debug > 1)
+               info("%s: streaming=1 video_endp=$%02x", proc, uvd->video_endp);
+       return 0;
+}
+
+/*
+ * usbvideo_StopDataPump()
+ *
+ * This procedure stops streaming and deallocates URBs. Then it
+ * activates zero-bandwidth alt. setting of the video interface.
+ *
+ * History:
+ * 22-Jan-2000 Corrected order of actions to work after surprise removal.
+ * 27-Jan-2000 Used uvd->iface, uvd->ifaceAltInactive instead of hardcoded values.
+ */
+void usbvideo_StopDataPump(uvd_t *uvd)
+{
+       static const char proc[] = "usbvideo_StopDataPump";
+       int i, j;
+
+       if (uvd->debug > 1)
+               info("%s($%p)", proc, uvd);
+
+       if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL))
+               return;
+
+       /* Unschedule all of the iso td's */
+       for (i=0; i < USBVIDEO_NUMSBUF; i++) {
+               j = usb_unlink_urb(uvd->sbuf[i].urb);
+               if (j < 0)
+                       err("%s: usb_unlink_urb() error %d.", proc, j);
+       }
+       if (uvd->debug > 1)
+               info("%s: streaming=0", proc);
+       uvd->streaming = 0;
+
+       if (!uvd->remove_pending) {
+               /* Invoke minidriver's magic to stop the camera */
+               if (VALID_CALLBACK(uvd, videoStop))
+                       GET_CALLBACK(uvd, videoStop)(uvd);
+               else 
+                       err("%s: videoStop not set" ,proc);
+
+               /* Set packet size to 0 */
+               j = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltInactive);
+               if (j < 0) {
+                       err("%s: usb_set_interface() error %d.", proc, j);
+                       uvd->last_error = j;
+               }
+       }
+}
+
+/*
+ * usbvideo_NewFrame()
+ *
+ * History:
+ * 29-Mar-00 Added copying of previous frame into the current one.
+ * 6-Aug-00  Added model 3 video sizes, removed redundant width, height.
+ */
+int usbvideo_NewFrame(uvd_t *uvd, int framenum)
+{
+       usbvideo_frame_t *frame;
+       int n;
+
+       if (uvd->debug > 1)
+               info("usbvideo_NewFrame($%p,%d.)", uvd, framenum);
+
+       /* If we're not grabbing a frame right now and the other frame is */
+       /*  ready to be grabbed into, then use it instead */
+       if (uvd->curframe != -1)
+               return 0;
+
+       /* If necessary we adjust picture settings between frames */
+       if (!uvd->settingsAdjusted) {
+               if (VALID_CALLBACK(uvd, adjustPicture))
+                       GET_CALLBACK(uvd, adjustPicture)(uvd);
+               uvd->settingsAdjusted = 1;
+       }
+
+       n = (framenum - 1 + USBVIDEO_NUMFRAMES) % USBVIDEO_NUMFRAMES;
+       if (uvd->frame[n].frameState == FrameState_Ready)
+               framenum = n;
+
+       frame = &uvd->frame[framenum];
+
+       frame->frameState = FrameState_Grabbing;
+       frame->scanstate = ScanState_Scanning;
+       frame->seqRead_Length = 0;      /* Accumulated in xxx_parse_data() */
+       frame->deinterlace = Deinterlace_None;
+       frame->flags = 0; /* No flags yet, up to minidriver (or us) to set them */
+       uvd->curframe = framenum;
+
+       /*
+        * Normally we would want to copy previous frame into the current one
+        * before we even start filling it with data; this allows us to stop
+        * filling at any moment; top portion of the frame will be new and
+        * bottom portion will stay as it was in previous frame. If we don't
+        * do that then missing chunks of video stream will result in flickering
+        * portions of old data whatever it was before.
+        *
+        * If we choose not to copy previous frame (to, for example, save few
+        * bus cycles - the frame can be pretty large!) then we have an option
+        * to clear the frame before using. If we experience losses in this
+        * mode then missing picture will be black (no flickering).
+        *
+        * Finally, if user chooses not to clean the current frame before
+        * filling it with data then the old data will be visible if we fail
+        * to refill entire frame with new data.
+        */
+       if (!(uvd->flags & FLAGS_SEPARATE_FRAMES)) {
+               /* This copies previous frame into this one to mask losses */
+               memmove(frame->data, uvd->frame[1-framenum].data, uvd->max_frame_size);
+       } else {
+               if (uvd->flags & FLAGS_CLEAN_FRAMES) {
+                       /* This provides a "clean" frame but slows things down */
+                       memset(frame->data, 0, uvd->max_frame_size);
+               }
+       }
+       return 0;
+}
+
+/*
+ * usbvideo_CollectRawData()
+ *
+ * This procedure can be used instead of 'processData' callback if you
+ * only want to dump the raw data from the camera into the output
+ * device (frame buffer). You can look at it with V4L client, but the
+ * image will be unwatchable. The main purpose of this code and of the
+ * mode FLAGS_NO_DECODING is debugging and capturing of datastreams from
+ * new, unknown cameras. This procedure will be automatically invoked
+ * instead of the specified callback handler when uvd->flags has bit
+ * FLAGS_NO_DECODING set. Therefore, any regular build of any driver
+ * based on usbvideo can use this feature at any time.
+ */
+void usbvideo_CollectRawData(uvd_t *uvd, usbvideo_frame_t *frame)
+{
+       int n;
+
+       assert(uvd != NULL);
+       assert(frame != NULL);
+
+       /* Try to move data from queue into frame buffer */
+       n = RingQueue_GetLength(&uvd->dp);
+       if (n > 0) {
+               int m;
+               /* See how much space we have left */
+               m = uvd->max_frame_size - frame->seqRead_Length;
+               if (n > m)
+                       n = m;
+               /* Now move that much data into frame buffer */
+               RingQueue_Dequeue(
+                       &uvd->dp,
+                       frame->data + frame->seqRead_Length,
+                       m);
+               frame->seqRead_Length += m;
+       }
+       /* See if we filled the frame */
+       if (frame->seqRead_Length >= uvd->max_frame_size) {
+               frame->frameState = FrameState_Done;
+               uvd->curframe = -1;
+               uvd->stats.frame_num++;
+       }
+}
+
+int usbvideo_GetFrame(uvd_t *uvd, int frameNum)
+{
+       static const char proc[] = "usbvideo_GetFrame";
+       usbvideo_frame_t *frame = &uvd->frame[frameNum];
+
+       if (uvd->debug >= 2)
+               info("%s($%p,%d.)", proc, uvd, frameNum);
+
+       switch (frame->frameState) {
+        case FrameState_Unused:
+               if (uvd->debug >= 2)
+                       info("%s: FrameState_Unused", proc);
+               return -EINVAL;
+        case FrameState_Ready:
+        case FrameState_Grabbing:
+        case FrameState_Error:
+        {
+               int ntries, signalPending;
+       redo:
+               if (!CAMERA_IS_OPERATIONAL(uvd)) {
+                       if (uvd->debug >= 2)
+                               info("%s: Camera is not operational (1)", proc);
+                       return -EIO;
+               }
+               ntries = 0; 
+               do {
+                       RingQueue_InterruptibleSleepOn(&uvd->dp);
+                       signalPending = signal_pending(current);
+                       if (!CAMERA_IS_OPERATIONAL(uvd)) {
+                               if (uvd->debug >= 2)
+                                       info("%s: Camera is not operational (2)", proc);
+                               return -EIO;
+                       }
+                       assert(uvd->fbuf != NULL);
+                       if (signalPending) {
+                               if (uvd->debug >= 2)
+                                       info("%s: Signal=$%08x", proc, signalPending);
+                               if (uvd->flags & FLAGS_RETRY_VIDIOCSYNC) {
+                                       usbvideo_TestPattern(uvd, 1, 0);
+                                       uvd->curframe = -1;
+                                       uvd->stats.frame_num++;
+                                       if (uvd->debug >= 2)
+                                               info("%s: Forced test pattern screen", proc);
+                                       return 0;
+                               } else {
+                                       /* Standard answer: Interrupted! */
+                                       if (uvd->debug >= 2)
+                                               info("%s: Interrupted!", proc);
+                                       return -EINTR;
+                               }
+                       } else {
+                               /* No signals - we just got new data in dp queue */
+                               if (uvd->flags & FLAGS_NO_DECODING)
+                                       usbvideo_CollectRawData(uvd, frame);
+                               else if (VALID_CALLBACK(uvd, processData))
+                                       GET_CALLBACK(uvd, processData)(uvd, frame);
+                               else 
+                                       err("%s: processData not set", proc);
+                       }
+               } while (frame->frameState == FrameState_Grabbing);
+               if (uvd->debug >= 2) {
+                       info("%s: Grabbing done; state=%d. (%lu. bytes)",
+                            proc, frame->frameState, frame->seqRead_Length);
+               }
+               if (frame->frameState == FrameState_Error) {
+                       int ret = usbvideo_NewFrame(uvd, frameNum);
+                       if (ret < 0) {
+                               err("%s: usbvideo_NewFrame() failed (%d.)", proc, ret);
+                               return ret;
+                       }
+                       goto redo;
+               }
+               /* Note that we fall through to meet our destiny below */
+        }
+        case FrameState_Done:
+               /*
+                * Do all necessary postprocessing of data prepared in
+                * "interrupt" code and the collecting code above. The
+                * frame gets marked as FrameState_Done by queue parsing code.
+                * This status means that we collected enough data and
+                * most likely processed it as we went through. However
+                * the data may need postprocessing, such as deinterlacing
+                * or picture adjustments implemented in software (horror!)
+                *
+                * As soon as the frame becomes "final" it gets promoted to
+                * FrameState_Done_Hold status where it will remain until the
+                * caller consumed all the video data from the frame. Then
+                * the empty shell of ex-frame is thrown out for dogs to eat.
+                * But we, worried about pets, will recycle the frame!
+                */
+               uvd->stats.frame_num++;
+               if ((uvd->flags & FLAGS_NO_DECODING) == 0) {
+                       if (VALID_CALLBACK(uvd, postProcess))
+                               GET_CALLBACK(uvd, postProcess)(uvd, frame);
+                       if (frame->flags & USBVIDEO_FRAME_FLAG_SOFTWARE_CONTRAST)
+                               usbvideo_SoftwareContrastAdjustment(uvd, frame);
+               }
+               frame->frameState = FrameState_Done_Hold;
+               if (uvd->debug >= 2)
+                       info("%s: Entered FrameState_Done_Hold state.", proc);
+               return 0;
+
+       case FrameState_Done_Hold:
+               /*
+                * We stay in this state indefinitely until someone external,
+                * like ioctl() or read() call finishes digesting the frame
+                * data. Then it will mark the frame as FrameState_Unused and
+                * it will be released back into the wild to roam freely.
+                */
+               if (uvd->debug >= 2)
+                       info("%s: FrameState_Done_Hold state.", proc);
+               return 0;
+       }
+
+       /* Catch-all for other cases. We shall not be here. */
+       err("%s: Invalid state %d.", proc, frame->frameState);
+       frame->frameState = FrameState_Unused;
+       return 0;
+}
+
+/*
+ * usbvideo_DeinterlaceFrame()
+ *
+ * This procedure deinterlaces the given frame. Some cameras produce
+ * only half of scanlines - sometimes only even lines, sometimes only
+ * odd lines. The deinterlacing method is stored in frame->deinterlace
+ * variable.
+ *
+ * Here we scan the frame vertically and replace missing scanlines with
+ * average between surrounding ones - before and after. If we have no
+ * line above then we just copy next line. Similarly, if we need to
+ * create a last line then preceding line is used.
+ */
+void usbvideo_DeinterlaceFrame(uvd_t *uvd, usbvideo_frame_t *frame)
+{
+       if ((uvd == NULL) || (frame == NULL))
+               return;
+
+       if ((frame->deinterlace == Deinterlace_FillEvenLines) ||
+           (frame->deinterlace == Deinterlace_FillOddLines))
+       {
+               const int v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
+               int i = (frame->deinterlace == Deinterlace_FillEvenLines) ? 0 : 1;
+
+               for (; i < VIDEOSIZE_Y(frame->request); i += 2) {
+                       const unsigned char *fs1, *fs2;
+                       unsigned char *fd;
+                       int ip, in, j;  /* Previous and next lines */
+
+                       /*
+                        * Need to average lines before and after 'i'.
+                        * If we go out of bounds seeking those lines then
+                        * we point back to existing line.
+                        */
+                       ip = i - 1;     /* First, get rough numbers */
+                       in = i + 1;
+
+                       /* Now validate */
+                       if (ip < 0)
+                               ip = in;
+                       if (in >= VIDEOSIZE_Y(frame->request))
+                               in = ip;
+
+                       /* Sanity check */
+                       if ((ip < 0) || (in < 0) ||
+                           (ip >= VIDEOSIZE_Y(frame->request)) ||
+                           (in >= VIDEOSIZE_Y(frame->request)))
+                       {
+                               err("Error: ip=%d. in=%d. req.height=%ld.",
+                                   ip, in, VIDEOSIZE_Y(frame->request));
+                               break;
+                       }
+
+                       /* Now we need to average lines 'ip' and 'in' to produce line 'i' */
+                       fs1 = frame->data + (v4l_linesize * ip);
+                       fs2 = frame->data + (v4l_linesize * in);
+                       fd = frame->data + (v4l_linesize * i);
+
+                       /* Average lines around destination */
+                       for (j=0; j < v4l_linesize; j++) {
+                               fd[j] = (unsigned char)((((unsigned) fs1[j]) +
+                                                        ((unsigned)fs2[j])) >> 1);
+                       }
+               }
+       }
+
+       /* Optionally display statistics on the screen */
+       if (uvd->flags & FLAGS_OVERLAY_STATS)
+               usbvideo_OverlayStats(uvd, frame);
+}
+
+/*
+ * usbvideo_SoftwareContrastAdjustment()
+ *
+ * This code adjusts the contrast of the frame, assuming RGB24 format.
+ * As most software image processing, this job is CPU-intensive.
+ * Get a camera that supports hardware adjustment!
+ *
+ * History:
+ * 09-Feb-2001  Created.
+ */
+void usbvideo_SoftwareContrastAdjustment(uvd_t *uvd, usbvideo_frame_t *frame)
+{
+       static const char proc[] = "usbvideo_SoftwareContrastAdjustment";
+       int i, j, v4l_linesize;
+       signed long adj;
+       const int ccm = 128; /* Color correction median - see below */
+
+       if ((uvd == NULL) || (frame == NULL)) {
+               err("%s: Illegal call.", proc);
+               return;
+       }
+       adj = (uvd->vpic.contrast - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/
+       RESTRICT_TO_RANGE(adj, -ccm, ccm+1);
+       if (adj == 0) {
+               /* In rare case of no adjustment */
+               return;
+       }
+       v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
+       for (i=0; i < VIDEOSIZE_Y(frame->request); i++) {
+               unsigned char *fd = frame->data + (v4l_linesize * i);
+               for (j=0; j < v4l_linesize; j++) {
+                       signed long v = (signed long) fd[j];
+                       /* Magnify up to 2 times, reduce down to zero */
+                       v = 128 + ((ccm + adj) * (v - 128)) / ccm;
+                       RESTRICT_TO_RANGE(v, 0, 0xFF); /* Must flatten tails */
+                       fd[j] = (unsigned char) v;
+               }
+       }
+}
+
+/*
+ * /proc interface
+ *
+ * We will be creating directories and entries under /proc/video using
+ * external 'video_proc_entry' directory which is exported by videodev.o
+ * module. Within that directory we will create $driver/ directory to
+ * uniquely and uniformly refer to our specific $driver. Within that
+ * directory we will finally create an entry that is named after the
+ * video device node - video3, for example. The format of that file
+ * is determined by callbacks that the minidriver may provide. If no
+ * callbacks are provided (neither read nor write) then we don't create
+ * the entry.
+ *
+ * Here is a sample directory entry: /proc/video/ibmcam/video3
+ *
+ * The "file" video3 (in example above) is readable and writeable, in
+ * theory. If the minidriver provides callbacks to do reading and
+ * writing then both those procedures are supported. However if the
+ * driver leaves callbacks in default (NULL) state the default
+ * read and write handlers are used. The default read handler reports
+ * that the driver does not support /proc fs. The default write handler
+ * returns error code on any write attempt.
+ */
+
+#if USES_PROC_FS
+
+extern struct proc_dir_entry *video_proc_entry;
+
+static void usbvideo_procfs_level1_create(usbvideo_t *ut)
+{
+       static const char proc[] = "usbvideo_procfs_level1_create";
+
+       if (ut == NULL) {
+               err("%s: ut == NULL", proc);
+               return;
+       }
+       if (video_proc_entry == NULL) {
+               err("%s: /proc/video/ doesn't exist.", proc);
+               return;
+       }
+       ut->procfs_dEntry = create_proc_entry(ut->drvName, S_IFDIR, video_proc_entry);
+       if (ut->procfs_dEntry != NULL) {
+               if (ut->md_module != NULL)
+                       ut->procfs_dEntry->owner = ut->md_module;
+       } else {
+               err("%s: Unable to initialize /proc/video/%s", proc, ut->drvName);
+       }
+}
+
+static void usbvideo_procfs_level1_destroy(usbvideo_t *ut)
+{
+       static const char proc[] = "usbvideo_procfs_level1_destroy";
+
+       if (ut == NULL) {
+               err("%s: ut == NULL", proc);
+               return;
+       }
+       if (ut->procfs_dEntry != NULL) {
+               remove_proc_entry(ut->drvName, video_proc_entry);
+               ut->procfs_dEntry = NULL;
+       }
+}
+
+static void usbvideo_procfs_level2_create(uvd_t *uvd)
+{
+       static const char proc[] = "usbvideo_procfs_level2_create";
+
+       if (uvd == NULL) {
+               err("%s: uvd == NULL", proc);
+               return;
+       }
+       assert(uvd->handle != NULL);
+       if (uvd->handle->procfs_dEntry == NULL) {
+               err("%s: uvd->handle->procfs_dEntry == NULL", proc);
+               return;
+       }
+
+       sprintf(uvd->videoName, "video%d", uvd->vdev.minor);
+       uvd->procfs_vEntry = create_proc_entry(
+               uvd->videoName,
+               S_IFREG | S_IRUGO | S_IWUSR,
+               uvd->handle->procfs_dEntry);
+       if (uvd->procfs_vEntry != NULL) {
+               uvd->procfs_vEntry->data = uvd;
+               uvd->procfs_vEntry->read_proc = uvd->handle->cb.procfs_read;
+               uvd->procfs_vEntry->write_proc = uvd->handle->cb.procfs_write;
+       } else {
+               err("%s: Failed to create entry \"%s\"", proc, uvd->videoName);
+       }
+}
+
+static void usbvideo_procfs_level2_destroy(uvd_t *uvd)
+{
+       static const char proc[] = "usbvideo_procfs_level2_destroy";
+
+       if (uvd == NULL) {
+               err("%s: uvd == NULL", proc);
+               return;
+       }
+       if (uvd->procfs_vEntry != NULL) {
+               remove_proc_entry(uvd->videoName, uvd->procfs_vEntry);
+               uvd->procfs_vEntry = NULL;
+       }
+}
+
+static int usbvideo_default_procfs_read_proc(
+       char *page, char **start, off_t off, int count,
+       int *eof, void *data)
+{
+       char *out = page;
+       int len;
+       
+       /* Stay under PAGE_SIZE or else */
+       out += sprintf(out, "This driver does not support /proc services.\n");
+       len = out - page;
+       len -= off;
+       if (len < count) {
+               *eof = 1;
+               if (len <= 0)
+                       return 0;
+       } else
+               len = count;
+       *start = page + off;
+       return len;     
+}
+
+static int usbvideo_default_procfs_write_proc(
+       struct file *file, const char *buffer, 
+       unsigned long count, void *data)
+{
+       return -EINVAL;
+}
+
+#endif /* USES_PROC_FS */
diff --git a/drivers/usb/usbvideo.h b/drivers/usb/usbvideo.h
new file mode 100644 (file)
index 0000000..0942fc9
--- /dev/null
@@ -0,0 +1,424 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef usbvideo_h
+#define        usbvideo_h
+
+#include <linux/config.h>
+#include <linux/proc_fs.h>
+#include <linux/videodev.h>
+#include <linux/usb.h>
+
+/* Most helpful debugging aid */
+#define assert(expr) ((void) ((expr) ? 0 : (err("assert failed at line %d",__LINE__))))
+
+#define USES_PROC_FS   (defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS))
+#define USBVIDEO_REPORT_STATS  1       /* Set to 0 to block statistics on close */
+
+/* Bit flags (options) */
+#define FLAGS_RETRY_VIDIOCSYNC         (1 << 0)
+#define        FLAGS_MONOCHROME                (1 << 1)
+#define FLAGS_DISPLAY_HINTS            (1 << 2)
+#define FLAGS_OVERLAY_STATS            (1 << 3)
+#define FLAGS_FORCE_TESTPATTERN                (1 << 4)
+#define FLAGS_SEPARATE_FRAMES          (1 << 5)
+#define FLAGS_CLEAN_FRAMES             (1 << 6)
+#define        FLAGS_NO_DECODING               (1 << 7)
+
+/* Bit flags for frames (apply to the frame where they are specified) */
+#define USBVIDEO_FRAME_FLAG_SOFTWARE_CONTRAST  (1 << 0)
+
+/* Camera capabilities (maximum) */
+#define CAMERA_URB_FRAMES       32
+#define CAMERA_MAX_ISO_PACKET   1023 /* 1022 actually sent by camera */
+#define FRAMES_PER_DESC                (CAMERA_URB_FRAMES)
+#define FRAME_SIZE_PER_DESC    (CAMERA_MAX_ISO_PACKET)
+
+/* This macro restricts an int variable to an inclusive range */
+#define RESTRICT_TO_RANGE(v,mi,ma) { if ((v) < (mi)) (v) = (mi); else if ((v) > (ma)) (v) = (ma); }
+
+#define V4L_BYTES_PER_PIXEL     3      /* Because we produce RGB24 */
+
+/*
+ * Use this macro to construct constants for different video sizes.
+ * We have to deal with different video sizes that have to be
+ * configured in the device or compared against when we receive
+ * a data. Normally one would define a bunch of VIDEOSIZE_x_by_y
+ * #defines and that's the end of story. However this solution
+ * does not allow to convert between real pixel sizes and the
+ * constant (integer) value that may be used to tag a frame or
+ * whatever. The set of macros below constructs videosize constants
+ * from the pixel size and allows to reconstruct the pixel size
+ * from the combined value later.
+ */
+#define        VIDEOSIZE(x,y)  (((x) & 0xFFFFL) | (((y) & 0xFFFFL) << 16))
+#define        VIDEOSIZE_X(vs) ((vs) & 0xFFFFL)
+#define        VIDEOSIZE_Y(vs) (((vs) >> 16) & 0xFFFFL)
+typedef unsigned long videosize_t;
+
+/*
+ * This macro checks if the camera is still operational. The 'uvd'
+ * pointer must be valid, uvd->dev must be valid, we are not
+ * removing the device and the device has not erred on us.
+ */
+#define CAMERA_IS_OPERATIONAL(uvd) (\
+       (uvd != NULL) && \
+       ((uvd)->dev != NULL) && \
+       ((uvd)->last_error == 0) && \
+       (!(uvd)->remove_pending))
+
+/*
+ * We use macros to do YUV -> RGB conversion because this is
+ * very important for speed and totally unimportant for size.
+ *
+ * YUV -> RGB Conversion
+ * ---------------------
+ *
+ * B = 1.164*(Y-16)                + 2.018*(V-128)
+ * G = 1.164*(Y-16) - 0.813*(U-128) - 0.391*(V-128)
+ * R = 1.164*(Y-16) + 1.596*(U-128)
+ *
+ * If you fancy integer arithmetics (as you should), hear this:
+ *
+ * 65536*B = 76284*(Y-16)                + 132252*(V-128)
+ * 65536*G = 76284*(Y-16) -  53281*(U-128) -  25625*(V-128)
+ * 65536*R = 76284*(Y-16) + 104595*(U-128)
+ *
+ * Make sure the output values are within [0..255] range.
+ */
+#define LIMIT_RGB(x) (((x) < 0) ? 0 : (((x) > 255) ? 255 : (x)))
+#define YUV_TO_RGB_BY_THE_BOOK(my,mu,mv,mr,mg,mb) { \
+    int mm_y, mm_yc, mm_u, mm_v, mm_r, mm_g, mm_b; \
+    mm_y = (my) - 16;  \
+    mm_u = (mu) - 128; \
+    mm_v = (mv) - 128; \
+    mm_yc= mm_y * 76284; \
+    mm_b = (mm_yc              + 132252*mm_v   ) >> 16; \
+    mm_g = (mm_yc -  53281*mm_u -  25625*mm_v  ) >> 16; \
+    mm_r = (mm_yc + 104595*mm_u                        ) >> 16; \
+    mb = LIMIT_RGB(mm_b); \
+    mg = LIMIT_RGB(mm_g); \
+    mr = LIMIT_RGB(mm_r); \
+}
+
+#define        RING_QUEUE_ADVANCE_INDEX(rq,ind,n) (rq)->ind = ((rq)->ind + (n)) % (rq)->length
+#define        RING_QUEUE_DEQUEUE_BYTES(rq,n) RING_QUEUE_ADVANCE_INDEX(rq,ri,n)
+#define        RING_QUEUE_PEEK(rq,ofs) ((rq)->queue[((ofs) + (rq)->ri) % (rq)->length])
+
+typedef struct {
+       unsigned char *queue;   /* Data from the Isoc data pump */
+       int length;             /* How many bytes allocated for the queue */
+       int wi;                 /* That's where we write */
+       int ri;                 /* Read from here until you hit write index */
+       wait_queue_head_t wqh;  /* Processes waiting */
+} RingQueue_t;
+
+typedef enum {
+       ScanState_Scanning,     /* Scanning for header */
+       ScanState_Lines         /* Parsing lines */
+} ScanState_t;
+
+/* Completion states of the data parser */
+typedef enum {
+       scan_Continue,          /* Just parse next item */
+       scan_NextFrame,         /* Frame done, send it to V4L */
+       scan_Out,               /* Not enough data for frame */
+       scan_EndParse           /* End parsing */
+} ParseState_t;
+
+typedef enum {
+       FrameState_Unused,      /* Unused (no MCAPTURE) */
+       FrameState_Ready,       /* Ready to start grabbing */
+       FrameState_Grabbing,    /* In the process of being grabbed into */
+       FrameState_Done,        /* Finished grabbing, but not been synced yet */
+       FrameState_Done_Hold,   /* Are syncing or reading */
+       FrameState_Error,       /* Something bad happened while processing */
+} FrameState_t;
+
+/*
+ * Some frames may contain only even or odd lines. This type
+ * specifies what type of deinterlacing is required.
+ */
+typedef enum {
+       Deinterlace_None=0,
+       Deinterlace_FillOddLines,
+       Deinterlace_FillEvenLines
+} Deinterlace_t;
+
+struct usb_device;
+
+#define USBVIDEO_NUMFRAMES     2       /* How many frames we work with */
+#define USBVIDEO_NUMSBUF       2       /* How many URBs linked in a ring */
+
+/* This structure represents one Isoc request - URB and buffer */
+typedef struct {
+       char *data;
+       urb_t *urb;
+} usbvideo_sbuf_t;
+
+typedef struct {
+       char *data;             /* Frame buffer */
+       unsigned long header;   /* Significant bits from the header */
+
+       videosize_t canvas;     /* The canvas (max. image) allocated */
+       videosize_t request;    /* That's what the application asked for */
+       unsigned short palette; /* The desired format */
+
+       FrameState_t frameState;/* State of grabbing */
+       ScanState_t scanstate;  /* State of scanning */
+       Deinterlace_t deinterlace;
+       int flags;              /* USBVIDEO_FRAME_FLAG_xxx bit flags */
+
+       int curline;            /* Line of frame we're working on */
+
+       long seqRead_Length;    /* Raw data length of frame */
+       long seqRead_Index;     /* Amount of data that has been already read */
+
+       void *user;             /* Additional data that user may need */
+} usbvideo_frame_t;
+
+/* Statistics that can be overlaid on screen */
+typedef struct {
+        unsigned long frame_num;       /* Sequential number of the frame */
+        unsigned long urb_count;        /* How many URBs we received so far */
+        unsigned long urb_length;       /* Length of last URB */
+        unsigned long data_count;       /* How many bytes we received */
+        unsigned long header_count;     /* How many frame headers we found */
+       unsigned long iso_skip_count;   /* How many empty ISO packets received */
+       unsigned long iso_err_count;    /* How many bad ISO packets received */
+} usbvideo_statistics_t;
+
+struct s_usbvideo_t;
+
+typedef struct {
+       struct video_device vdev;       /* Must be the first field! */
+       struct usb_device *dev;
+       struct s_usbvideo_t *handle;    /* Points back to the usbvideo_t */
+       void *user_data;                /* Camera-dependent data */
+       int user_size;                  /* Size of that camera-dependent data */
+       int debug;                      /* Debug level for usbvideo */
+       unsigned char iface;            /* Video interface number */
+       unsigned char video_endp;
+       unsigned char ifaceAltActive;
+       unsigned char ifaceAltInactive; /* Alt settings */
+       unsigned long flags;            /* FLAGS_USBVIDEO_xxx */
+       unsigned long paletteBits;      /* Which palettes we accept? */
+       unsigned short defaultPalette;  /* What palette to use for read() */
+       struct semaphore lock;
+       int user;               /* user count for exclusive use */
+
+       videosize_t videosize;  /* Current setting */
+       videosize_t canvas;     /* This is the width,height of the V4L canvas */
+       int max_frame_size;     /* Bytes in one video frame */
+
+       int uvd_used;           /* Is this structure in use? */
+       int streaming;          /* Are we streaming Isochronous? */
+       int grabbing;           /* Are we grabbing? */
+       int settingsAdjusted;   /* Have we adjusted contrast etc.? */
+       int last_error;         /* What calamity struck us? */
+
+       char *fbuf;             /* Videodev buffer area */
+       int fbuf_size;          /* Videodev buffer size */
+
+       int curframe;
+       int iso_packet_len;     /* Videomode-dependent, saves bus bandwidth */
+
+       RingQueue_t dp;         /* Isoc data pump */
+       usbvideo_frame_t frame[USBVIDEO_NUMFRAMES];
+       usbvideo_sbuf_t sbuf[USBVIDEO_NUMSBUF];
+
+       volatile int remove_pending;    /* If set then about to exit */
+
+       struct video_picture vpic, vpic_old;    /* Picture settings */
+       struct video_capability vcap;           /* Video capabilities */
+       struct video_channel vchan;     /* May be used for tuner support */
+       usbvideo_statistics_t stats;
+       struct proc_dir_entry *procfs_vEntry;   /* /proc/video/MYDRIVER/video2 */
+       char videoName[32];             /* Holds name like "video7" */
+} uvd_t;
+
+/*
+ * usbvideo callbacks (virtual methods). They are set when usbvideo
+ * services are registered. All of these default to NULL, except those
+ * that default to usbvideo-provided methods.
+ */
+typedef struct {
+#if defined(usb_device_id_ver)
+       /* New style probe (for 2.4.x kernels with hotplugging) */
+       void *(*probe)(struct usb_device *, unsigned int,const struct usb_device_id *);
+#else
+       /* Old style probe (for 2.2.x kernels) */
+       void *(*probe)(struct usb_device *, unsigned int);
+#endif
+       void (*userFree)(uvd_t *);
+       void (*disconnect)(struct usb_device *, void *);
+       int (*setupOnOpen)(uvd_t *);
+       void (*videoStart)(uvd_t *);
+       void (*videoStop)(uvd_t *);
+       void (*processData)(uvd_t *, usbvideo_frame_t *);
+       void (*postProcess)(uvd_t *, usbvideo_frame_t *);
+       void (*adjustPicture)(uvd_t *);
+       int (*getFPS)(uvd_t *);
+       int (*overlayHook)(uvd_t *, usbvideo_frame_t *);
+       int (*getFrame)(uvd_t *, int);
+       int (*procfs_read)(char *page,char **start,off_t off,int count,int *eof,void *data);
+       int (*procfs_write)(struct file *file,const char *buffer,unsigned long count,void *data);
+} usbvideo_cb_t;
+
+struct s_usbvideo_t {
+       int num_cameras;                /* As allocated */
+       struct usb_driver usbdrv;       /* Interface to the USB stack */
+       char drvName[80];               /* Driver name */
+       struct semaphore lock;          /* Mutex protecting camera structures */
+       usbvideo_cb_t cb;               /* Table of callbacks (virtual methods) */
+       struct video_device vdt;        /* Video device template */
+       uvd_t *cam;                     /* Array of camera structures */
+       int uses_procfs;                /* Non-zero if we create /proc entries */
+       struct proc_dir_entry *procfs_dEntry;   /* /proc/video/MYDRIVER */
+       struct module *md_module;       /* Minidriver module */
+};
+typedef struct s_usbvideo_t usbvideo_t;
+
+/*
+ * This macro retrieves callback address from the uvd_t object.
+ * No validity checks are done here, so be sure to check the
+ * callback beforehand with VALID_CALLBACK.
+ */
+#define        GET_CALLBACK(uvd,cbName) ((uvd)->handle->cb.cbName)
+
+/*
+ * This macro returns either callback pointer or NULL. This is safe
+ * macro, meaning that most of components of data structures involved
+ * may be NULL - this only results in NULL being returned. You may
+ * wish to use this macro to make sure that the callback is callable.
+ * However keep in mind that those checks take time.
+ */
+#define        VALID_CALLBACK(uvd,cbName) ((((uvd) != NULL) && \
+               ((uvd)->handle != NULL)) ? GET_CALLBACK(uvd,cbName) : NULL)
+
+void RingQueue_Initialize(RingQueue_t *rq);
+void RingQueue_Allocate(RingQueue_t *rq, int rqLen);
+int  RingQueue_IsAllocated(const RingQueue_t *rq);
+void RingQueue_Free(RingQueue_t *rq);
+int  RingQueue_Dequeue(RingQueue_t *rq, unsigned char *dst, int len);
+int  RingQueue_Enqueue(RingQueue_t *rq, const unsigned char *cdata, int n);
+int  RingQueue_GetLength(const RingQueue_t *rq);
+void RingQueue_InterruptibleSleepOn(RingQueue_t *rq);
+void RingQueue_WakeUpInterruptible(RingQueue_t *rq);
+
+void usbvideo_CollectRawData(uvd_t *uvd, usbvideo_frame_t *frame);
+void usbvideo_DrawLine(
+       usbvideo_frame_t *frame,
+       int x1, int y1,
+       int x2, int y2,
+       unsigned char cr, unsigned char cg, unsigned char cb);
+void usbvideo_HexDump(const unsigned char *data, int len);
+void usbvideo_OverlayChar(uvd_t *uvd, usbvideo_frame_t *frame, int x, int y, int ch);
+void usbvideo_OverlayString(uvd_t *uvd, usbvideo_frame_t *frame, int x, int y, const char *str);
+void usbvideo_OverlayStats(uvd_t *uvd, usbvideo_frame_t *frame);
+void usbvideo_ReportStatistics(const uvd_t *uvd);
+void usbvideo_SayAndWait(const char *what);
+void usbvideo_TestPattern(uvd_t *uvd, int fullframe, int pmode);
+void usbvideo_VideosizeToString(char *buf, int bufLen, videosize_t vs);
+
+/* Memory allocation routines */
+unsigned long usbvideo_uvirt_to_kva(pgd_t *pgd, unsigned long adr);
+unsigned long usbvideo_uvirt_to_bus(unsigned long adr);
+unsigned long usbvideo_kvirt_to_bus(unsigned long adr);
+unsigned long usbvideo_kvirt_to_pa(unsigned long adr);
+void *usbvideo_rvmalloc(unsigned long size);
+void usbvideo_rvfree(void *mem, unsigned long size);
+
+int usbvideo_register(
+       usbvideo_t **pCams,
+       const int num_cams,
+       const int num_extra,
+       const char *driverName,
+       const usbvideo_cb_t *cbTable,
+       struct module *md);
+uvd_t *usbvideo_AllocateDevice(usbvideo_t *cams);
+int usbvideo_RegisterVideoDevice(uvd_t *uvd);
+void usbvideo_Deregister(usbvideo_t **uvt);
+void usbvideo_Disconnect(struct usb_device *dev, void *ptr);
+void usbvideo_CameraRelease(uvd_t *uvd);
+
+void usbvideo_v4l_close(struct video_device *dev);
+int usbvideo_v4l_initialize(struct video_device *dev);
+int usbvideo_v4l_ioctl(struct video_device *dev, unsigned int cmd, void *arg);
+int usbvideo_v4l_mmap(struct video_device *dev, const char *adr, unsigned long size);
+int usbvideo_v4l_open(struct video_device *dev, int flags);
+long usbvideo_v4l_read(struct video_device *dev, char *buf,
+                       unsigned long count, int noblock);
+long usbvideo_v4l_write(struct video_device *dev, const char *buf,
+                       unsigned long count, int noblock);
+
+int usbvideo_GetFrame(uvd_t *uvd, int frameNum);
+int usbvideo_NewFrame(uvd_t *uvd, int framenum);
+int usbvideo_StartDataPump(uvd_t *uvd);
+void usbvideo_StopDataPump(uvd_t *uvd);
+void usbvideo_DeinterlaceFrame(uvd_t *uvd, usbvideo_frame_t *frame);
+void usbvideo_SoftwareContrastAdjustment(uvd_t *uvd, usbvideo_frame_t *frame);
+
+/*
+ * This code performs bounds checking - use it when working with
+ * new formats, or else you may get oopses all over the place.
+ * If pixel falls out of bounds then it gets shoved back (as close
+ * to place of offence as possible) and is painted bright red.
+ *
+ * There are two important concepts: frame width, height and
+ * V4L canvas width, height. The former is the area requested by
+ * the application -for this very frame-. The latter is the largest
+ * possible frame that we can serve (we advertise that via V4L ioctl).
+ * The frame data is expected to be formatted as lines of length
+ * VIDEOSIZE_X(fr->request), total VIDEOSIZE_Y(frame->request) lines.
+ */
+static inline void RGB24_PUTPIXEL(
+       usbvideo_frame_t *fr,
+       int ix, int iy,
+       unsigned char vr,
+       unsigned char vg,
+       unsigned char vb)
+{
+       register unsigned char *pf;
+       int limiter = 0, mx, my;
+       mx = ix;
+       my = iy;
+       if (mx < 0) {
+               mx=0;
+               limiter++;
+       } else if (mx >= VIDEOSIZE_X((fr)->request)) {
+               mx= VIDEOSIZE_X((fr)->request) - 1;
+               limiter++;
+       }
+       if (my < 0) {
+               my = 0;
+               limiter++;
+       } else if (my >= VIDEOSIZE_Y((fr)->request)) {
+               my = VIDEOSIZE_Y((fr)->request) - 1;
+               limiter++;
+       }
+       pf = (fr)->data + V4L_BYTES_PER_PIXEL*((iy)*VIDEOSIZE_X((fr)->request) + (ix));
+       if (limiter) {
+               *pf++ = 0;
+               *pf++ = 0;
+               *pf++ = 0xFF;
+       } else {
+               *pf++ = (vb);
+               *pf++ = (vg);
+               *pf++ = (vr);
+       }
+}
+
+#endif /* usbvideo_h */
index a81f29a20ae0813d50d5f7d6f92b2ecacc26c6cc..4ccd3bb4fd0aa46389360b95d3bd811e2308f9f0 100644 (file)
@@ -2206,6 +2206,10 @@ static int __init fbcon_show_logo( void )
                            /* Some cards require 32bit access */
                            fb_writel (val, dst);
                            dst += 4;
+                       } else if (bdepth == 2 && !((long)dst & 1)) {
+                           /* others require 16bit access */
+                           fb_writew (val,dst);
+                           dst +=2;
                        } else {
 #ifdef __LITTLE_ENDIAN
                            for( i = 0; i < bdepth; ++i )
@@ -2280,6 +2284,10 @@ static int __init fbcon_show_logo( void )
                        /* Some cards require 32bit access */
                        fb_writel (val, dst);
                        dst += 4;
+                   } else if (bdepth == 2 && !((long)dst & 1)) {
+                       /* others require 16bit access */
+                       fb_writew (val,dst);
+                       dst +=2;
                    } else {
 #ifdef __LITTLE_ENDIAN
                        for( i = 0; i < bdepth; ++i )
@@ -2493,3 +2501,5 @@ EXPORT_SYMBOL(fbcon_redraw_bmove);
 EXPORT_SYMBOL(fbcon_redraw_clear);
 EXPORT_SYMBOL(fbcon_dummy);
 EXPORT_SYMBOL(fb_con);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/radeon.h b/drivers/video/radeon.h
new file mode 100644 (file)
index 0000000..447fdb0
--- /dev/null
@@ -0,0 +1,665 @@
+#ifndef _RADEON_H
+#define _RADEON_H
+
+
+/* radeon PCI ids */
+#define PCI_DEVICE_ID_RADEON_QD                0x5144
+#define PCI_DEVICE_ID_RADEON_QE                0x5145
+#define PCI_DEVICE_ID_RADEON_QF                0x5146
+#define PCI_DEVICE_ID_RADEON_QG                0x5147
+
+#define RADEON_REGSIZE                 0x4000
+
+
+#define MM_INDEX                               0x0000  
+#define MM_DATA                                0x0004  
+#define BUS_CNTL                               0x0030  
+#define HI_STAT                                0x004C  
+#define BUS_CNTL1                              0x0034
+#define I2C_CNTL_1                            0x0094  
+#define CONFIG_CNTL                            0x00E0  
+#define CONFIG_MEMSIZE                         0x00F8  
+#define CONFIG_APER_0_BASE                     0x0100  
+#define CONFIG_APER_1_BASE                     0x0104  
+#define CONFIG_APER_SIZE                       0x0108  
+#define CONFIG_REG_1_BASE                      0x010C  
+#define CONFIG_REG_APER_SIZE                   0x0110  
+#define PAD_AGPINPUT_DELAY                     0x0164  
+#define PAD_CTLR_STRENGTH                      0x0168  
+#define PAD_CTLR_UPDATE                        0x016C
+#define AGP_CNTL                               0x0174
+#define BM_STATUS                              0x0160
+#define CAP0_TRIG_CNTL                        0x0950
+#define VIPH_CONTROL                          0x0C40
+#define VENDOR_ID                              0x0F00  
+#define DEVICE_ID                              0x0F02  
+#define COMMAND                                0x0F04  
+#define STATUS                                 0x0F06  
+#define REVISION_ID                            0x0F08  
+#define REGPROG_INF                            0x0F09  
+#define SUB_CLASS                              0x0F0A  
+#define BASE_CODE                              0x0F0B  
+#define CACHE_LINE                             0x0F0C  
+#define LATENCY                                0x0F0D  
+#define HEADER                                 0x0F0E  
+#define BIST                                   0x0F0F  
+#define REG_MEM_BASE                           0x0F10  
+#define REG_IO_BASE                            0x0F14  
+#define REG_REG_BASE                           0x0F18
+#define ADAPTER_ID                             0x0F2C
+#define BIOS_ROM                               0x0F30
+#define CAPABILITIES_PTR                       0x0F34  
+#define INTERRUPT_LINE                         0x0F3C  
+#define INTERRUPT_PIN                          0x0F3D  
+#define MIN_GRANT                              0x0F3E  
+#define MAX_LATENCY                            0x0F3F  
+#define ADAPTER_ID_W                           0x0F4C  
+#define PMI_CAP_ID                             0x0F50  
+#define PMI_NXT_CAP_PTR                        0x0F51  
+#define PMI_PMC_REG                            0x0F52  
+#define PM_STATUS                              0x0F54  
+#define PMI_DATA                               0x0F57  
+#define AGP_CAP_ID                             0x0F58  
+#define AGP_STATUS                             0x0F5C  
+#define AGP_COMMAND                            0x0F60  
+#define AIC_CTRL                               0x01D0
+#define AIC_STAT                               0x01D4
+#define AIC_PT_BASE                            0x01D8
+#define AIC_LO_ADDR                            0x01DC  
+#define AIC_HI_ADDR                            0x01E0  
+#define AIC_TLB_ADDR                           0x01E4  
+#define AIC_TLB_DATA                           0x01E8  
+#define DAC_CNTL                               0x0058  
+#define CRTC_GEN_CNTL                          0x0050  
+#define MEM_CNTL                               0x0140  
+#define EXT_MEM_CNTL                           0x0144  
+#define MC_AGP_LOCATION                        0x014C  
+#define MEM_IO_CNTL_A0                         0x0178  
+#define MEM_INIT_LATENCY_TIMER                 0x0154  
+#define MEM_SDRAM_MODE_REG                     0x0158  
+#define AGP_BASE                               0x0170  
+#define MEM_IO_CNTL_A1                         0x017C  
+#define MEM_IO_CNTL_B0                         0x0180
+#define MEM_IO_CNTL_B1                         0x0184
+#define MC_DEBUG                               0x0188
+#define MC_STATUS                              0x0150  
+#define MEM_IO_OE_CNTL                         0x018C  
+#define MC_FB_LOCATION                         0x0148  
+#define HOST_PATH_CNTL                         0x0130  
+#define MEM_VGA_WP_SEL                         0x0038  
+#define MEM_VGA_RP_SEL                         0x003C  
+#define HDP_DEBUG                              0x0138  
+#define SW_SEMAPHORE                           0x013C  
+#define SURFACE_CNTL                           0x0B00  
+#define SURFACE0_LOWER_BOUND                   0x0B04  
+#define SURFACE1_LOWER_BOUND                   0x0B14  
+#define SURFACE2_LOWER_BOUND                   0x0B24  
+#define SURFACE3_LOWER_BOUND                   0x0B34  
+#define SURFACE4_LOWER_BOUND                   0x0B44  
+#define SURFACE5_LOWER_BOUND                   0x0B54
+#define SURFACE6_LOWER_BOUND                   0x0B64
+#define SURFACE7_LOWER_BOUND                   0x0B74
+#define SURFACE0_UPPER_BOUND                   0x0B08  
+#define SURFACE1_UPPER_BOUND                   0x0B18  
+#define SURFACE2_UPPER_BOUND                   0x0B28  
+#define SURFACE3_UPPER_BOUND                   0x0B38  
+#define SURFACE4_UPPER_BOUND                   0x0B48  
+#define SURFACE5_UPPER_BOUND                   0x0B58  
+#define SURFACE6_UPPER_BOUND                   0x0B68  
+#define SURFACE7_UPPER_BOUND                   0x0B78  
+#define SURFACE0_INFO                          0x0B0C  
+#define SURFACE1_INFO                          0x0B1C  
+#define SURFACE2_INFO                          0x0B2C  
+#define SURFACE3_INFO                          0x0B3C  
+#define SURFACE4_INFO                          0x0B4C  
+#define SURFACE5_INFO                          0x0B5C  
+#define SURFACE6_INFO                          0x0B6C
+#define SURFACE7_INFO                          0x0B7C
+#define SURFACE_ACCESS_FLAGS                   0x0BF8
+#define SURFACE_ACCESS_CLR                     0x0BFC  
+#define GEN_INT_CNTL                           0x0040  
+#define GEN_INT_STATUS                         0x0044  
+#define CRTC_EXT_CNTL                          0x0054
+#define RB3D_CNTL                             0x1C3C  
+#define WAIT_UNTIL                             0x1720  
+#define ISYNC_CNTL                             0x1724  
+#define RBBM_GUICNTL                           0x172C  
+#define RBBM_STATUS                            0x0E40  
+#define RBBM_STATUS_alt_1                      0x1740  
+#define RBBM_CNTL                              0x00EC  
+#define RBBM_CNTL_alt_1                        0x0E44  
+#define RBBM_SOFT_RESET                        0x00F0  
+#define RBBM_SOFT_RESET_alt_1                  0x0E48  
+#define NQWAIT_UNTIL                           0x0E50  
+#define RBBM_DEBUG                             0x0E6C
+#define RBBM_CMDFIFO_ADDR                      0x0E70
+#define RBBM_CMDFIFO_DATAL                     0x0E74
+#define RBBM_CMDFIFO_DATAH                     0x0E78  
+#define RBBM_CMDFIFO_STAT                      0x0E7C  
+#define CRTC_STATUS                            0x005C  
+#define GPIO_VGA_DDC                           0x0060  
+#define GPIO_DVI_DDC                           0x0064  
+#define GPIO_MONID                             0x0068  
+#define PALETTE_INDEX                          0x00B0  
+#define PALETTE_DATA                           0x00B4  
+#define PALETTE_30_DATA                        0x00B8  
+#define CRTC_H_TOTAL_DISP                      0x0200  
+#define CRTC_H_SYNC_STRT_WID                   0x0204  
+#define CRTC_V_TOTAL_DISP                      0x0208  
+#define CRTC_V_SYNC_STRT_WID                   0x020C  
+#define CRTC_VLINE_CRNT_VLINE                  0x0210  
+#define CRTC_CRNT_FRAME                        0x0214
+#define CRTC_GUI_TRIG_VLINE                    0x0218
+#define CRTC_DEBUG                             0x021C
+#define CRTC_OFFSET_RIGHT                      0x0220  
+#define CRTC_OFFSET                            0x0224  
+#define CRTC_OFFSET_CNTL                       0x0228  
+#define CRTC_PITCH                             0x022C  
+#define OVR_CLR                                0x0230  
+#define OVR_WID_LEFT_RIGHT                     0x0234  
+#define OVR_WID_TOP_BOTTOM                     0x0238  
+#define DISPLAY_BASE_ADDR                      0x023C  
+#define SNAPSHOT_VH_COUNTS                     0x0240  
+#define SNAPSHOT_F_COUNT                       0x0244  
+#define N_VIF_COUNT                            0x0248  
+#define SNAPSHOT_VIF_COUNT                     0x024C  
+#define FP_CRTC_H_TOTAL_DISP                   0x0250  
+#define FP_CRTC_V_TOTAL_DISP                   0x0254  
+#define CRT_CRTC_H_SYNC_STRT_WID               0x0258
+#define CRT_CRTC_V_SYNC_STRT_WID               0x025C
+#define CUR_OFFSET                             0x0260
+#define CUR_HORZ_VERT_POSN                     0x0264  
+#define CUR_HORZ_VERT_OFF                      0x0268  
+#define CUR_CLR0                               0x026C  
+#define CUR_CLR1                               0x0270  
+#define FP_HORZ_VERT_ACTIVE                    0x0278  
+#define CRTC_MORE_CNTL                         0x027C  
+#define DAC_EXT_CNTL                           0x0280  
+#define FP_GEN_CNTL                            0x0284  
+#define FP_HORZ_STRETCH                        0x028C  
+#define FP_VERT_STRETCH                        0x0290  
+#define FP_H_SYNC_STRT_WID                     0x02C4  
+#define FP_V_SYNC_STRT_WID                     0x02C8  
+#define AUX_WINDOW_HORZ_CNTL                   0x02D8  
+#define AUX_WINDOW_VERT_CNTL                   0x02DC  
+#define DDA_CONFIG                            0x02e0
+#define DDA_ON_OFF                            0x02e4
+#define GRPH_BUFFER_CNTL                       0x02F0
+#define VGA_BUFFER_CNTL                        0x02F4
+#define OV0_Y_X_START                          0x0400
+#define OV0_Y_X_END                            0x0404  
+#define OV0_PIPELINE_CNTL                      0x0408  
+#define OV0_REG_LOAD_CNTL                      0x0410  
+#define OV0_SCALE_CNTL                         0x0420  
+#define OV0_V_INC                              0x0424  
+#define OV0_P1_V_ACCUM_INIT                    0x0428  
+#define OV0_P23_V_ACCUM_INIT                   0x042C  
+#define OV0_P1_BLANK_LINES_AT_TOP              0x0430  
+#define OV0_P23_BLANK_LINES_AT_TOP             0x0434  
+#define OV0_BASE_ADDR                          0x043C  
+#define OV0_VID_BUF0_BASE_ADRS                 0x0440  
+#define OV0_VID_BUF1_BASE_ADRS                 0x0444  
+#define OV0_VID_BUF2_BASE_ADRS                 0x0448  
+#define OV0_VID_BUF3_BASE_ADRS                 0x044C  
+#define OV0_VID_BUF4_BASE_ADRS                 0x0450
+#define OV0_VID_BUF5_BASE_ADRS                 0x0454
+#define OV0_VID_BUF_PITCH0_VALUE               0x0460
+#define OV0_VID_BUF_PITCH1_VALUE               0x0464  
+#define OV0_AUTO_FLIP_CNTRL                    0x0470  
+#define OV0_DEINTERLACE_PATTERN                0x0474  
+#define OV0_SUBMIT_HISTORY                     0x0478  
+#define OV0_H_INC                              0x0480  
+#define OV0_STEP_BY                            0x0484  
+#define OV0_P1_H_ACCUM_INIT                    0x0488  
+#define OV0_P23_H_ACCUM_INIT                   0x048C  
+#define OV0_P1_X_START_END                     0x0494  
+#define OV0_P2_X_START_END                     0x0498  
+#define OV0_P3_X_START_END                     0x049C  
+#define OV0_FILTER_CNTL                        0x04A0  
+#define OV0_FOUR_TAP_COEF_0                    0x04B0  
+#define OV0_FOUR_TAP_COEF_1                    0x04B4  
+#define OV0_FOUR_TAP_COEF_2                    0x04B8
+#define OV0_FOUR_TAP_COEF_3                    0x04BC
+#define OV0_FOUR_TAP_COEF_4                    0x04C0
+#define OV0_FLAG_CNTRL                         0x04DC  
+#define OV0_SLICE_CNTL                         0x04E0  
+#define OV0_VID_KEY_CLR_LOW                    0x04E4  
+#define OV0_VID_KEY_CLR_HIGH                   0x04E8  
+#define OV0_GRPH_KEY_CLR_LOW                   0x04EC  
+#define OV0_GRPH_KEY_CLR_HIGH                  0x04F0  
+#define OV0_KEY_CNTL                           0x04F4  
+#define OV0_TEST                               0x04F8  
+#define SUBPIC_CNTL                            0x0540  
+#define SUBPIC_DEFCOLCON                       0x0544  
+#define SUBPIC_Y_X_START                       0x054C  
+#define SUBPIC_Y_X_END                         0x0550  
+#define SUBPIC_V_INC                           0x0554  
+#define SUBPIC_H_INC                           0x0558  
+#define SUBPIC_BUF0_OFFSET                     0x055C
+#define SUBPIC_BUF1_OFFSET                     0x0560
+#define SUBPIC_LC0_OFFSET                      0x0564
+#define SUBPIC_LC1_OFFSET                      0x0568  
+#define SUBPIC_PITCH                           0x056C  
+#define SUBPIC_BTN_HLI_COLCON                  0x0570  
+#define SUBPIC_BTN_HLI_Y_X_START               0x0574  
+#define SUBPIC_BTN_HLI_Y_X_END                 0x0578  
+#define SUBPIC_PALETTE_INDEX                   0x057C  
+#define SUBPIC_PALETTE_DATA                    0x0580  
+#define SUBPIC_H_ACCUM_INIT                    0x0584  
+#define SUBPIC_V_ACCUM_INIT                    0x0588  
+#define DISP_MISC_CNTL                         0x0D00  
+#define DAC_MACRO_CNTL                         0x0D04  
+#define DISP_PWR_MAN                           0x0D08  
+#define DISP_TEST_DEBUG_CNTL                   0x0D10  
+#define DISP_HW_DEBUG                          0x0D14  
+#define DAC_CRC_SIG1                           0x0D18
+#define DAC_CRC_SIG2                           0x0D1C
+#define OV0_LIN_TRANS_A                        0x0D20
+#define OV0_LIN_TRANS_B                        0x0D24  
+#define OV0_LIN_TRANS_C                        0x0D28  
+#define OV0_LIN_TRANS_D                        0x0D2C  
+#define OV0_LIN_TRANS_E                        0x0D30  
+#define OV0_LIN_TRANS_F                        0x0D34  
+#define OV0_GAMMA_0_F                          0x0D40  
+#define OV0_GAMMA_10_1F                        0x0D44  
+#define OV0_GAMMA_20_3F                        0x0D48  
+#define OV0_GAMMA_40_7F                        0x0D4C  
+#define OV0_GAMMA_380_3BF                      0x0D50  
+#define OV0_GAMMA_3C0_3FF                      0x0D54  
+#define DISP_MERGE_CNTL                        0x0D60  
+#define DISP_OUTPUT_CNTL                       0x0D64  
+#define DISP_LIN_TRANS_GRPH_A                  0x0D80  
+#define DISP_LIN_TRANS_GRPH_B                  0x0D84
+#define DISP_LIN_TRANS_GRPH_C                  0x0D88
+#define DISP_LIN_TRANS_GRPH_D                  0x0D8C
+#define DISP_LIN_TRANS_GRPH_E                  0x0D90  
+#define DISP_LIN_TRANS_GRPH_F                  0x0D94  
+#define DISP_LIN_TRANS_VID_A                   0x0D98  
+#define DISP_LIN_TRANS_VID_B                   0x0D9C  
+#define DISP_LIN_TRANS_VID_C                   0x0DA0  
+#define DISP_LIN_TRANS_VID_D                   0x0DA4  
+#define DISP_LIN_TRANS_VID_E                   0x0DA8  
+#define DISP_LIN_TRANS_VID_F                   0x0DAC  
+#define RMX_HORZ_FILTER_0TAP_COEF              0x0DB0  
+#define RMX_HORZ_FILTER_1TAP_COEF              0x0DB4  
+#define RMX_HORZ_FILTER_2TAP_COEF              0x0DB8  
+#define RMX_HORZ_PHASE                         0x0DBC  
+#define DAC_EMBEDDED_SYNC_CNTL                 0x0DC0  
+#define DAC_BROAD_PULSE                        0x0DC4  
+#define DAC_SKEW_CLKS                          0x0DC8
+#define DAC_INCR                               0x0DCC
+#define DAC_NEG_SYNC_LEVEL                     0x0DD0
+#define DAC_POS_SYNC_LEVEL                     0x0DD4  
+#define DAC_BLANK_LEVEL                        0x0DD8  
+#define CLOCK_CNTL_INDEX                       0x0008  
+#define CLOCK_CNTL_DATA                        0x000C  
+#define CP_RB_CNTL                             0x0704  
+#define CP_RB_BASE                             0x0700  
+#define CP_RB_RPTR_ADDR                        0x070C  
+#define CP_RB_RPTR                             0x0710  
+#define CP_RB_WPTR                             0x0714  
+#define CP_RB_WPTR_DELAY                       0x0718  
+#define CP_IB_BASE                             0x0738  
+#define CP_IB_BUFSZ                            0x073C  
+#define SCRATCH_REG0                           0x15E0  
+#define GUI_SCRATCH_REG0                       0x15E0  
+#define SCRATCH_REG1                           0x15E4  
+#define GUI_SCRATCH_REG1                       0x15E4  
+#define SCRATCH_REG2                           0x15E8
+#define GUI_SCRATCH_REG2                       0x15E8
+#define SCRATCH_REG3                           0x15EC
+#define GUI_SCRATCH_REG3                       0x15EC  
+#define SCRATCH_REG4                           0x15F0  
+#define GUI_SCRATCH_REG4                       0x15F0  
+#define SCRATCH_REG5                           0x15F4  
+#define GUI_SCRATCH_REG5                       0x15F4  
+#define SCRATCH_UMSK                           0x0770  
+#define SCRATCH_ADDR                           0x0774  
+#define DP_BRUSH_FRGD_CLR                      0x147C  
+#define DP_BRUSH_BKGD_CLR                      0x1478
+#define DST_LINE_START                         0x1600
+#define DST_LINE_END                           0x1604  
+#define SRC_OFFSET                             0x15AC  
+#define SRC_PITCH                              0x15B0
+#define SRC_TILE                               0x1704
+#define SRC_PITCH_OFFSET                       0x1428
+#define SRC_X                                  0x1414  
+#define SRC_Y                                  0x1418  
+#define SRC_X_Y                                0x1590  
+#define SRC_Y_X                                0x1434  
+#define DST_Y_X                                       0x1438
+#define DST_WIDTH_HEIGHT                      0x1598
+#define DST_HEIGHT_WIDTH                      0x143c
+#define SRC_CLUT_ADDRESS                       0x1780  
+#define SRC_CLUT_DATA                          0x1784  
+#define SRC_CLUT_DATA_RD                       0x1788  
+#define HOST_DATA0                             0x17C0  
+#define HOST_DATA1                             0x17C4  
+#define HOST_DATA2                             0x17C8  
+#define HOST_DATA3                             0x17CC  
+#define HOST_DATA4                             0x17D0  
+#define HOST_DATA5                             0x17D4  
+#define HOST_DATA6                             0x17D8  
+#define HOST_DATA7                             0x17DC
+#define HOST_DATA_LAST                         0x17E0
+#define DP_SRC_ENDIAN                          0x15D4
+#define DP_SRC_FRGD_CLR                        0x15D8  
+#define DP_SRC_BKGD_CLR                        0x15DC  
+#define SC_LEFT                                0x1640  
+#define SC_RIGHT                               0x1644  
+#define SC_TOP                                 0x1648  
+#define SC_BOTTOM                              0x164C  
+#define SRC_SC_RIGHT                           0x1654  
+#define SRC_SC_BOTTOM                          0x165C  
+#define DP_CNTL                                0x16C0  
+#define DP_CNTL_XDIR_YDIR_YMAJOR               0x16D0  
+#define DP_DATATYPE                            0x16C4  
+#define DP_MIX                                 0x16C8  
+#define DP_WRITE_MSK                           0x16CC  
+#define DP_XOP                                 0x17F8  
+#define CLR_CMP_CLR_SRC                        0x15C4
+#define CLR_CMP_CLR_DST                        0x15C8
+#define CLR_CMP_CNTL                           0x15C0
+#define CLR_CMP_MSK                            0x15CC  
+#define DSTCACHE_MODE                          0x1710  
+#define DSTCACHE_CTLSTAT                       0x1714  
+#define DEFAULT_PITCH_OFFSET                   0x16E0  
+#define DEFAULT_SC_BOTTOM_RIGHT                0x16E8  
+#define DP_GUI_MASTER_CNTL                     0x146C  
+#define SC_TOP_LEFT                            0x16EC  
+#define SC_BOTTOM_RIGHT                        0x16F0  
+#define SRC_SC_BOTTOM_RIGHT                    0x16F4  
+#define RB2D_DSTCACHE_CTLSTAT                 0x342C
+
+
+#define CLK_PIN_CNTL                               0x0001
+#define PPLL_CNTL                                  0x0002
+#define PPLL_REF_DIV                               0x0003
+#define PPLL_DIV_0                                 0x0004
+#define PPLL_DIV_1                                 0x0005
+#define PPLL_DIV_2                                 0x0006
+#define PPLL_DIV_3                                 0x0007
+#define VCLK_ECP_CNTL                              0x0008
+#define HTOTAL_CNTL                                0x0009
+#define M_SPLL_REF_FB_DIV                          0x000a
+#define AGP_PLL_CNTL                               0x000b
+#define SPLL_CNTL                                  0x000c
+#define SCLK_CNTL                                  0x000d
+#define MPLL_CNTL                                  0x000e
+#define MCLK_CNTL                                  0x0012
+#define AGP_PLL_CNTL                               0x000b
+#define PLL_TEST_CNTL                              0x0013
+
+
+/* MCLK_CNTL bit constants */
+#define FORCEON_MCLKA                             (1 << 16)
+#define FORCEON_MCLKB                             (1 << 17)
+#define FORCEON_YCLKA                             (1 << 18)
+#define FORCEON_YCLKB                             (1 << 19)
+#define FORCEON_MC                                (1 << 20)
+#define FORCEON_AIC                               (1 << 21)
+
+
+/* BUS_CNTL bit constants */
+#define BUS_DBL_RESYNC                             0x00000001
+#define BUS_MSTR_RESET                             0x00000002
+#define BUS_FLUSH_BUF                              0x00000004
+#define BUS_STOP_REQ_DIS                           0x00000008
+#define BUS_ROTATION_DIS                           0x00000010
+#define BUS_MASTER_DIS                             0x00000040
+#define BUS_ROM_WRT_EN                             0x00000080
+#define BUS_DIS_ROM                                0x00001000
+#define BUS_PCI_READ_RETRY_EN                      0x00002000
+#define BUS_AGP_AD_STEPPING_EN                     0x00004000
+#define BUS_PCI_WRT_RETRY_EN                       0x00008000
+#define BUS_MSTR_RD_MULT                           0x00100000
+#define BUS_MSTR_RD_LINE                           0x00200000
+#define BUS_SUSPEND                                0x00400000
+#define LAT_16X                                    0x00800000
+#define BUS_RD_DISCARD_EN                          0x01000000
+#define BUS_RD_ABORT_EN                            0x02000000
+#define BUS_MSTR_WS                                0x04000000
+#define BUS_PARKING_DIS                            0x08000000
+#define BUS_MSTR_DISCONNECT_EN                     0x10000000
+#define BUS_WRT_BURST                              0x20000000
+#define BUS_READ_BURST                             0x40000000
+#define BUS_RDY_READ_DLY                           0x80000000
+
+
+/* CLOCK_CNTL_INDEX bit constants */
+#define PLL_WR_EN                                  0x00000080
+
+/* CONFIG_CNTL bit constants */
+#define CFG_VGA_RAM_EN                             0x00000100
+
+/* CRTC_EXT_CNTL bit constants */
+#define VGA_ATI_LINEAR                             0x00000008
+#define VGA_128KAP_PAGING                          0x00000010
+#define        XCRT_CNT_EN                                (1 << 6)
+#define CRTC_HSYNC_DIS                            (1 << 8)
+#define CRTC_VSYNC_DIS                            (1 << 9)
+#define CRTC_DISPLAY_DIS                          (1 << 10)
+
+
+/* DSTCACHE_CTLSTAT bit constants */
+#define RB2D_DC_FLUSH                             (3 << 0)
+#define RB2D_DC_FLUSH_ALL                         0xf
+#define RB2D_DC_BUSY                              (1 << 31)
+
+
+/* CRTC_GEN_CNTL bit constants */
+#define CRTC_DBL_SCAN_EN                           0x00000001
+#define CRTC_CUR_EN                                0x00010000
+#define CRTC_EXT_DISP_EN                          (1 << 24)
+#define CRTC_EN                                           (1 << 25)
+
+/* CRTC_STATUS bit constants */
+#define CRTC_VBLANK                                0x00000001
+
+/* CUR_OFFSET, CUR_HORZ_VERT_POSN, CUR_HORZ_VERT_OFF bit constants */
+#define CUR_LOCK                                   0x80000000
+
+/* DAC_CNTL bit constants */   
+#define DAC_8BIT_EN                                0x00000100
+#define DAC_4BPP_PIX_ORDER                         0x00000200
+#define DAC_CRC_EN                                 0x00080000
+#define DAC_MASK_ALL                              (0xff << 24)
+#define DAC_VGA_ADR_EN                            (1 << 13)
+#define DAC_RANGE_CNTL                            (3 << 0)
+#define DAC_BLANKING                              (1 << 2)
+
+/* GEN_RESET_CNTL bit constants */
+#define SOFT_RESET_GUI                             0x00000001
+#define SOFT_RESET_VCLK                            0x00000100
+#define SOFT_RESET_PCLK                            0x00000200
+#define SOFT_RESET_ECP                             0x00000400
+#define SOFT_RESET_DISPENG_XCLK                    0x00000800
+
+/* MEM_CNTL bit constants */
+#define MEM_CTLR_STATUS_IDLE                       0x00000000
+#define MEM_CTLR_STATUS_BUSY                       0x00100000
+#define MEM_SEQNCR_STATUS_IDLE                     0x00000000
+#define MEM_SEQNCR_STATUS_BUSY                     0x00200000
+#define MEM_ARBITER_STATUS_IDLE                    0x00000000
+#define MEM_ARBITER_STATUS_BUSY                    0x00400000
+#define MEM_REQ_UNLOCK                             0x00000000
+#define MEM_REQ_LOCK                               0x00800000
+
+
+/* RBBM_SOFT_RESET bit constants */
+#define SOFT_RESET_CP                             (1 <<  0)
+#define SOFT_RESET_HI                             (1 <<  1)
+#define SOFT_RESET_SE                             (1 <<  2)
+#define SOFT_RESET_RE                             (1 <<  3)
+#define SOFT_RESET_PP                             (1 <<  4)
+#define SOFT_RESET_E2                             (1 <<  5)
+#define SOFT_RESET_RB                             (1 <<  6)
+#define SOFT_RESET_HDP                            (1 <<  7)
+
+
+/* DEFAULT_SC_BOTTOM_RIGHT bit constants */
+#define DEFAULT_SC_RIGHT_MAX                      (0x1fff << 0)
+#define DEFAULT_SC_BOTTOM_MAX                     (0x1fff << 16)
+
+/* MM_INDEX bit constants */
+#define MM_APER                                    0x80000000
+
+/* CLR_CMP_CNTL bit constants */
+#define COMPARE_SRC_FALSE                          0x00000000
+#define COMPARE_SRC_TRUE                           0x00000001
+#define COMPARE_SRC_NOT_EQUAL                      0x00000004
+#define COMPARE_SRC_EQUAL                          0x00000005
+#define COMPARE_SRC_EQUAL_FLIP                     0x00000007
+#define COMPARE_DST_FALSE                          0x00000000
+#define COMPARE_DST_TRUE                           0x00000100
+#define COMPARE_DST_NOT_EQUAL                      0x00000400
+#define COMPARE_DST_EQUAL                          0x00000500
+#define COMPARE_DESTINATION                        0x00000000
+#define COMPARE_SOURCE                             0x01000000
+#define COMPARE_SRC_AND_DST                        0x02000000
+
+
+/* DP_CNTL bit constants */
+#define DST_X_RIGHT_TO_LEFT                        0x00000000
+#define DST_X_LEFT_TO_RIGHT                        0x00000001
+#define DST_Y_BOTTOM_TO_TOP                        0x00000000
+#define DST_Y_TOP_TO_BOTTOM                        0x00000002
+#define DST_X_MAJOR                                0x00000000
+#define DST_Y_MAJOR                                0x00000004
+#define DST_X_TILE                                 0x00000008
+#define DST_Y_TILE                                 0x00000010
+#define DST_LAST_PEL                               0x00000020
+#define DST_TRAIL_X_RIGHT_TO_LEFT                  0x00000000
+#define DST_TRAIL_X_LEFT_TO_RIGHT                  0x00000040
+#define DST_TRAP_FILL_RIGHT_TO_LEFT                0x00000000
+#define DST_TRAP_FILL_LEFT_TO_RIGHT                0x00000080
+#define DST_BRES_SIGN                              0x00000100
+#define DST_HOST_BIG_ENDIAN_EN                     0x00000200
+#define DST_POLYLINE_NONLAST                       0x00008000
+#define DST_RASTER_STALL                           0x00010000
+#define DST_POLY_EDGE                              0x00040000
+
+
+/* DP_CNTL_YDIR_XDIR_YMAJOR bit constants (short version of DP_CNTL) */
+#define DST_X_MAJOR_S                              0x00000000
+#define DST_Y_MAJOR_S                              0x00000001
+#define DST_Y_BOTTOM_TO_TOP_S                      0x00000000
+#define DST_Y_TOP_TO_BOTTOM_S                      0x00008000
+#define DST_X_RIGHT_TO_LEFT_S                      0x00000000
+#define DST_X_LEFT_TO_RIGHT_S                      0x80000000
+
+
+/* DP_DATATYPE bit constants */
+#define DST_8BPP                                   0x00000002
+#define DST_15BPP                                  0x00000003
+#define DST_16BPP                                  0x00000004
+#define DST_24BPP                                  0x00000005
+#define DST_32BPP                                  0x00000006
+#define DST_8BPP_RGB332                            0x00000007
+#define DST_8BPP_Y8                                0x00000008
+#define DST_8BPP_RGB8                              0x00000009
+#define DST_16BPP_VYUY422                          0x0000000b
+#define DST_16BPP_YVYU422                          0x0000000c
+#define DST_32BPP_AYUV444                          0x0000000e
+#define DST_16BPP_ARGB4444                         0x0000000f
+#define BRUSH_SOLIDCOLOR                           0x00000d00
+#define SRC_MONO                                   0x00000000
+#define SRC_MONO_LBKGD                             0x00010000
+#define SRC_DSTCOLOR                               0x00030000
+#define BYTE_ORDER_MSB_TO_LSB                      0x00000000
+#define BYTE_ORDER_LSB_TO_MSB                      0x40000000
+#define DP_CONVERSION_TEMP                         0x80000000
+#define HOST_BIG_ENDIAN_EN                        (1 << 29)
+
+
+/* DP_GUI_MASTER_CNTL bit constants */
+#define GMC_SRC_PITCH_OFFSET_DEFAULT               0x00000000
+#define GMC_SRC_PITCH_OFFSET_LEAVE                 0x00000001
+#define GMC_DST_PITCH_OFFSET_DEFAULT               0x00000000
+#define GMC_DST_PITCH_OFFSET_LEAVE                 0x00000002
+#define GMC_SRC_CLIP_DEFAULT                       0x00000000
+#define GMC_SRC_CLIP_LEAVE                         0x00000004
+#define GMC_DST_CLIP_DEFAULT                       0x00000000
+#define GMC_DST_CLIP_LEAVE                         0x00000008
+#define GMC_BRUSH_8x8MONO                          0x00000000
+#define GMC_BRUSH_8x8MONO_LBKGD                    0x00000010
+#define GMC_BRUSH_8x1MONO                          0x00000020
+#define GMC_BRUSH_8x1MONO_LBKGD                    0x00000030
+#define GMC_BRUSH_1x8MONO                          0x00000040
+#define GMC_BRUSH_1x8MONO_LBKGD                    0x00000050
+#define GMC_BRUSH_32x1MONO                         0x00000060
+#define GMC_BRUSH_32x1MONO_LBKGD                   0x00000070
+#define GMC_BRUSH_32x32MONO                        0x00000080
+#define GMC_BRUSH_32x32MONO_LBKGD                  0x00000090
+#define GMC_BRUSH_8x8COLOR                         0x000000a0
+#define GMC_BRUSH_8x1COLOR                         0x000000b0
+#define GMC_BRUSH_1x8COLOR                         0x000000c0
+#define GMC_BRUSH_SOLID_COLOR                       0x000000d0
+#define GMC_DST_8BPP                               0x00000200
+#define GMC_DST_15BPP                              0x00000300
+#define GMC_DST_16BPP                              0x00000400
+#define GMC_DST_24BPP                              0x00000500
+#define GMC_DST_32BPP                              0x00000600
+#define GMC_DST_8BPP_RGB332                        0x00000700
+#define GMC_DST_8BPP_Y8                            0x00000800
+#define GMC_DST_8BPP_RGB8                          0x00000900
+#define GMC_DST_16BPP_VYUY422                      0x00000b00
+#define GMC_DST_16BPP_YVYU422                      0x00000c00
+#define GMC_DST_32BPP_AYUV444                      0x00000e00
+#define GMC_DST_16BPP_ARGB4444                     0x00000f00
+#define GMC_SRC_MONO                               0x00000000
+#define GMC_SRC_MONO_LBKGD                         0x00001000
+#define GMC_SRC_DSTCOLOR                           0x00003000
+#define GMC_BYTE_ORDER_MSB_TO_LSB                  0x00000000
+#define GMC_BYTE_ORDER_LSB_TO_MSB                  0x00004000
+#define GMC_DP_CONVERSION_TEMP_9300                0x00008000
+#define GMC_DP_CONVERSION_TEMP_6500                0x00000000
+#define GMC_DP_SRC_RECT                            0x02000000
+#define GMC_DP_SRC_HOST                            0x03000000
+#define GMC_DP_SRC_HOST_BYTEALIGN                  0x04000000
+#define GMC_3D_FCN_EN_CLR                          0x00000000
+#define GMC_3D_FCN_EN_SET                          0x08000000
+#define GMC_DST_CLR_CMP_FCN_LEAVE                  0x00000000
+#define GMC_DST_CLR_CMP_FCN_CLEAR                  0x10000000
+#define GMC_AUX_CLIP_LEAVE                         0x00000000
+#define GMC_AUX_CLIP_CLEAR                         0x20000000
+#define GMC_WRITE_MASK_LEAVE                       0x00000000
+#define GMC_WRITE_MASK_SET                         0x40000000
+#define GMC_CLR_CMP_CNTL_DIS                      (1 << 28)
+#define GMC_SRC_DATATYPE_COLOR                    (3 << 12)
+#define ROP3_S                                    0x00cc0000
+#define ROP3_SRCCOPY                              0x00cc0000
+#define ROP3_P                                    0x00f00000
+#define ROP3_PATCOPY                              0x00f00000
+#define DP_SRC_SOURCE_MASK                        (7    << 24)
+#define GMC_BRUSH_NONE                            (15   <<  4)
+#define DP_SRC_SOURCE_MEMORY                      (2    << 24)
+#define GMC_BRUSH_SOLIDCOLOR                      0x000000d0
+
+/* DP_MIX bit constants */
+#define DP_SRC_RECT                                0x00000200
+#define DP_SRC_HOST                                0x00000300
+#define DP_SRC_HOST_BYTEALIGN                      0x00000400
+
+
+/* masks */
+
+#define CONFIG_MEMSIZE_MASK            0x1f000000
+#define MEM_CFG_TYPE                   0x40000000
+#define DST_OFFSET_MASK                        0x003fffff
+#define DST_PITCH_MASK                 0x3fc00000
+#define DEFAULT_TILE_MASK              0xc0000000
+#define        PPLL_DIV_SEL_MASK               0x00000300
+#define        PPLL_RESET                      0x00000001
+#define PPLL_ATOMIC_UPDATE_EN          0x00010000
+#define PPLL_REF_DIV_MASK              0x000003ff
+#define        PPLL_FB3_DIV_MASK               0x000007ff
+#define        PPLL_POST3_DIV_MASK             0x00070000
+#define PPLL_ATOMIC_UPDATE_R           0x00008000
+#define PPLL_ATOMIC_UPDATE_W           0x00008000
+#define        PPLL_VGA_ATOMIC_UPDATE_EN       0x00020000
+
+#define GUI_ACTIVE                     0x80000000
+
+#endif /* _RADEON_H */
+
diff --git a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c
new file mode 100644 (file)
index 0000000..d7c0915
--- /dev/null
@@ -0,0 +1,1907 @@
+/*
+ *     drivers/video/radeonfb.c
+ *     framebuffer driver for ATI Radeon chipset video boards
+ *
+ *     Copyright 2000  Ani Joshi <ajoshi@unixbox.com>
+ *
+ *
+ *     ChangeLog:
+ *     2000-08-03      initial version 0.0.1
+ *     2000-09-10      more bug fixes, public release 0.0.5
+ *     2001-02-19      mode bug fixes, 0.0.7
+ *     2001-07-05      fixed scrolling issues, engine initialization,
+ *                     and minor mode tweaking, 0.0.9
+ *
+ *
+ *     Special thanks to ATI DevRel team for their hardware donations.
+ *
+ */
+
+
+#define RADEON_VERSION "0.0.9"
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/console.h>
+#include <linux/selection.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/io.h>
+
+#include <video/fbcon.h> 
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb16.h>
+#include <video/fbcon-cfb24.h>
+#include <video/fbcon-cfb32.h>
+
+#include "radeon.h"
+
+
+#define DEBUG  0
+
+#if DEBUG
+#define RTRACE         printk
+#else
+#define RTRACE         if(0) printk
+#endif
+
+
+
+enum radeon_chips {
+       RADEON_QD,
+       RADEON_QE,
+       RADEON_QF,
+       RADEON_QG
+};
+
+
+static struct pci_device_id radeonfb_pci_table[] __devinitdata = {
+       { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QD},
+       { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QE},
+       { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QF},
+       { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QG},
+       { 0, }
+};
+MODULE_DEVICE_TABLE(pci, radeonfb_pci_table);
+
+
+typedef struct {
+       u16 reg;
+       u32 val;
+} reg_val;
+
+
+/* these common regs are cleared before mode setting so they do not
+ * interfere with anything
+ */
+reg_val common_regs[] = {
+       { OVR_CLR, 0 }, 
+       { OVR_WID_LEFT_RIGHT, 0 },
+       { OVR_WID_TOP_BOTTOM, 0 },
+       { OV0_SCALE_CNTL, 0 },
+       { SUBPIC_CNTL, 0 },
+       { VIPH_CONTROL, 0 },
+       { I2C_CNTL_1, 0 },
+       { GEN_INT_CNTL, 0 },
+       { CAP0_TRIG_CNTL, 0 },
+};
+
+#define COMMON_REGS_SIZE = (sizeof(common_regs)/sizeof(common_regs[0]))
+
+typedef struct {
+        u8 clock_chip_type;
+        u8 struct_size;
+        u8 accelerator_entry;
+        u8 VGA_entry;
+        u16 VGA_table_offset;
+        u16 POST_table_offset;
+        u16 XCLK;
+        u16 MCLK;
+        u8 num_PLL_blocks;
+        u8 size_PLL_blocks;
+        u16 PCLK_ref_freq;
+        u16 PCLK_ref_divider;
+        u32 PCLK_min_freq;
+        u32 PCLK_max_freq;
+        u16 MCLK_ref_freq;
+        u16 MCLK_ref_divider;
+        u32 MCLK_min_freq;
+        u32 MCLK_max_freq;
+        u16 XCLK_ref_freq;
+        u16 XCLK_ref_divider;
+        u32 XCLK_min_freq;
+        u32 XCLK_max_freq;
+} __attribute__ ((packed)) PLL_BLOCK;
+
+
+struct pll_info {
+       int ppll_max;
+       int ppll_min;
+       int xclk;
+       int ref_div;
+       int ref_clk;
+};
+
+
+struct ram_info {
+       int ml;
+       int mb;
+       int trcd;
+       int trp;
+       int twr;
+       int cl;
+       int tr2w;
+       int loop_latency;
+       int rloop;
+};
+
+
+struct radeon_regs {
+       u32 crtc_h_total_disp;
+       u32 crtc_h_sync_strt_wid;
+       u32 crtc_v_total_disp;
+       u32 crtc_v_sync_strt_wid;
+       u32 crtc_pitch;
+       u32 flags;
+       u32 pix_clock;
+       int xres, yres;
+       int bpp;
+       u32 crtc_gen_cntl;
+       u32 crtc_ext_cntl;
+       u32 dac_cntl;
+       u32 dda_config;
+       u32 dda_on_off;
+       u32 ppll_div_3;
+       u32 ppll_ref_div;
+};
+
+
+struct radeonfb_info {
+       struct fb_info info;
+
+       struct radeon_regs state;
+       struct radeon_regs init_state;
+
+       char name[10];
+       char ram_type[12];
+
+       u32 mmio_base_phys;
+       u32 fb_base_phys;
+
+       u32 mmio_base;
+       u32 fb_base;
+
+       struct pci_dev *pdev;
+
+       struct display disp;
+       int currcon;
+       struct display *currcon_display;
+
+       struct { u8 red, green, blue, pad; } palette[256];
+
+       int chipset;
+       int video_ram;
+       u8 rev;
+       int pitch, bpp, depth;
+       int xres, yres, pixclock;
+
+       u32 dp_gui_master_cntl;
+
+       struct pll_info pll;
+       int pll_output_freq, post_div, fb_div;
+
+       struct ram_info ram;
+
+#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
+        union {
+#if defined(FBCON_HAS_CFB16)
+                u_int16_t cfb16[16];
+#endif
+#if defined(FBCON_HAS_CFB32)
+                u_int32_t cfb32[16];
+#endif  
+        } con_cmap;
+#endif  
+};
+
+
+static struct fb_var_screeninfo radeonfb_default_var = {
+        640, 480, 640, 480, 0, 0, 8, 0,
+        {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
+        0, 0, -1, -1, 0, 39721, 40, 24, 32, 11, 96, 2,
+        0, FB_VMODE_NONINTERLACED
+};
+
+
+/*
+ * IO macros
+ */
+
+#define INREG8(addr)           readb((rinfo->mmio_base)+addr)
+#define OUTREG8(addr,val)      writeb(val, (rinfo->mmio_base)+addr)
+#define INREG(addr)            readl((rinfo->mmio_base)+addr)
+#define OUTREG(addr,val)       writel(val, (rinfo->mmio_base)+addr)
+
+#define OUTPLL(addr,val)       OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000001f) | 0x00000080); \
+                               OUTREG(CLOCK_CNTL_DATA, val)
+#define OUTPLLP(addr,val,mask)                                         \
+       do {                                                            \
+               unsigned int _tmp = INPLL(addr);                        \
+               _tmp &= (mask);                                         \
+               _tmp |= (val);                                          \
+               OUTPLL(addr, _tmp);                                     \
+       } while (0)
+
+#define OUTREGP(addr,val,mask)                                         \
+       do {                                                            \
+               unsigned int _tmp = INREG(addr);                        \
+               _tmp &= (mask);                                         \
+               _tmp |= (val);                                          \
+               OUTREG(addr, _tmp);                                     \
+       } while (0)
+
+
+static __inline__ u32 _INPLL(struct radeonfb_info *rinfo, u32 addr)
+{
+       OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000001f);
+       return (INREG(CLOCK_CNTL_DATA));
+}
+
+#define INPLL(addr)            _INPLL(rinfo, addr)
+
+
+/*
+ * 2D engine routines
+ */
+
+static __inline__ void radeon_engine_flush (struct radeonfb_info *rinfo)
+{
+       int i;
+
+       /* initiate flush */
+       OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL,
+               ~RB2D_DC_FLUSH_ALL);
+
+       for (i=0; i < 2000000; i++) {
+               if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY))
+                       break;
+       }
+}
+
+
+static __inline__ void _radeon_fifo_wait (struct radeonfb_info *rinfo, int entries)
+{
+       int i;
+
+       for (i=0; i<2000000; i++)
+               if ((INREG(RBBM_STATUS) & 0x7f) >= entries)
+                       return;
+}
+
+
+static __inline__ void _radeon_engine_idle (struct radeonfb_info *rinfo)
+{
+       int i;
+
+       /* ensure FIFO is empty before waiting for idle */
+       _radeon_fifo_wait (rinfo, 64);
+
+       for (i=0; i<2000000; i++) {
+               if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) {
+                       radeon_engine_flush (rinfo);
+                       return;
+               }
+       }
+}
+
+
+#define radeon_engine_idle()           _radeon_engine_idle(rinfo)
+#define radeon_fifo_wait(entries)      _radeon_fifo_wait(rinfo,entries)
+
+
+
+/*
+ * helper routines
+ */
+
+static __inline__ u32 radeon_get_dstbpp(u16 depth)
+{
+       switch (depth) {
+               case 8:
+                       return DST_8BPP;
+               case 15:
+                       return DST_15BPP;
+               case 16:
+                       return DST_16BPP;
+               case 32:
+                       return DST_32BPP;
+               default:
+                       return 0;
+       }
+}
+
+
+static void _radeon_engine_reset(struct radeonfb_info *rinfo)
+{
+       u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset;
+
+       radeon_engine_flush (rinfo);
+
+       clock_cntl_index = INREG(CLOCK_CNTL_INDEX);
+       mclk_cntl = INPLL(MCLK_CNTL);
+
+       OUTPLL(MCLK_CNTL, (mclk_cntl |
+                          FORCEON_MCLKA |
+                          FORCEON_MCLKB |
+                          FORCEON_YCLKA |
+                          FORCEON_YCLKB |
+                          FORCEON_MC |
+                          FORCEON_AIC));
+       rbbm_soft_reset = INREG(RBBM_SOFT_RESET);
+
+       OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset |
+                               SOFT_RESET_CP |
+                               SOFT_RESET_HI |
+                               SOFT_RESET_SE |
+                               SOFT_RESET_RE |
+                               SOFT_RESET_PP |
+                               SOFT_RESET_E2 |
+                               SOFT_RESET_RB |
+                               SOFT_RESET_HDP);
+       INREG(RBBM_SOFT_RESET);
+       OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset & (u32)
+                               ~(SOFT_RESET_CP |
+                                 SOFT_RESET_HI |
+                                 SOFT_RESET_SE |
+                                 SOFT_RESET_RE |
+                                 SOFT_RESET_PP |
+                                 SOFT_RESET_E2 |
+                                 SOFT_RESET_RB |
+                                 SOFT_RESET_HDP));
+       INREG(RBBM_SOFT_RESET);
+
+       OUTPLL(MCLK_CNTL, mclk_cntl);
+       OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index);
+       OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset);
+
+       return;
+}
+
+#define radeon_engine_reset()          _radeon_engine_reset(rinfo)
+
+
+static __inline__ u8 radeon_get_post_div_bitval(int post_div)
+{
+        switch (post_div) {
+                case 1:
+                        return 0x00;
+                case 2: 
+                        return 0x01;
+                case 3: 
+                        return 0x04;
+                case 4:
+                        return 0x02;
+                case 6:
+                        return 0x06;
+                case 8:
+                        return 0x03;
+                case 12:
+                        return 0x07;
+                default:
+                        return 0x02;
+        }
+}
+
+
+
+static __inline__ int round_div(int num, int den)
+{
+        return (num + (den / 2)) / den;
+}
+
+
+
+static __inline__ int min_bits_req(int val)
+{
+        int bits_req = 0;
+                
+        if (val == 0)
+                bits_req = 1;
+                        
+        while (val) {
+                val >>= 1;
+                bits_req++;
+        }       
+
+        return (bits_req);
+}
+
+
+static __inline__ int _max(int val1, int val2)
+{
+        if (val1 >= val2)
+                return val1;
+        else
+                return val2;
+}                       
+
+
+
+/*
+ * globals
+ */
+        
+static char fontname[40] __initdata;
+static char *mode_option __initdata;
+static char noaccel __initdata = 0;
+
+#ifdef FBCON_HAS_CFB8
+static struct display_switch fbcon_radeon8;
+#endif
+
+
+/*
+ * prototypes
+ */
+
+static int radeonfb_get_fix (struct fb_fix_screeninfo *fix, int con,
+                             struct fb_info *info);
+static int radeonfb_get_var (struct fb_var_screeninfo *var, int con,
+                             struct fb_info *info);
+static int radeonfb_set_var (struct fb_var_screeninfo *var, int con,
+                             struct fb_info *info);
+static int radeonfb_get_cmap (struct fb_cmap *cmap, int kspc, int con,
+                              struct fb_info *info);
+static int radeonfb_set_cmap (struct fb_cmap *cmap, int kspc, int con,
+                              struct fb_info *info);
+static int radeonfb_pan_display (struct fb_var_screeninfo *var, int con,
+                                 struct fb_info *info);
+static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
+                           unsigned long arg, int con, struct fb_info *info);
+static int radeonfb_switch (int con, struct fb_info *info);
+static int radeonfb_updatevar (int con, struct fb_info *info);
+static void radeonfb_blank (int blank, struct fb_info *info);
+static int radeon_get_cmap_len (const struct fb_var_screeninfo *var);
+static int radeon_getcolreg (unsigned regno, unsigned *red, unsigned *green,
+                             unsigned *blue, unsigned *transp,
+                             struct fb_info *info);
+static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green,
+                             unsigned blue, unsigned transp, struct fb_info *info);
+static void radeon_set_dispsw (struct radeonfb_info *rinfo);
+static void radeon_save_state (struct radeonfb_info *rinfo,
+                               struct radeon_regs *save);
+static void radeon_engine_init (struct radeonfb_info *rinfo);
+static void radeon_load_video_mode (struct radeonfb_info *rinfo,
+                                    struct fb_var_screeninfo *mode);
+static void radeon_write_mode (struct radeonfb_info *rinfo,
+                               struct radeon_regs *mode);
+static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo);
+static int __devinit radeon_init_disp (struct radeonfb_info *rinfo);
+static int radeon_init_disp_var (struct radeonfb_info *rinfo);
+static int radeonfb_pci_register (struct pci_dev *pdev,
+                                 const struct pci_device_id *ent);
+static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev);
+static char *radeon_find_rom(struct radeonfb_info *rinfo);
+static void radeon_get_pllinfo(struct radeonfb_info *rinfo, char *bios_seg);
+
+
+static struct fb_ops radeon_fb_ops = {
+       fb_get_fix:             radeonfb_get_fix,
+       fb_get_var:             radeonfb_get_var,
+       fb_set_var:             radeonfb_set_var,
+       fb_get_cmap:            radeonfb_get_cmap,
+       fb_set_cmap:            radeonfb_set_cmap,
+       fb_pan_display:         radeonfb_pan_display,
+       fb_ioctl:               radeonfb_ioctl,
+};
+
+
+static struct pci_driver radeonfb_driver = {
+       name:           "radeonfb",
+       id_table:       radeonfb_pci_table,
+       probe:          radeonfb_pci_register,
+       remove:         radeonfb_pci_unregister,
+};
+
+
+int __init radeonfb_init (void)
+{
+       return pci_module_init (&radeonfb_driver);
+}
+
+
+void __exit radeonfb_exit (void)
+{
+       pci_unregister_driver (&radeonfb_driver);
+}
+
+
+int __init radeonfb_setup (char *options)
+{
+        char *this_opt;
+
+        if (!options || !*options)
+                return 0;
+        for (this_opt = strtok (options, ","); this_opt;
+             this_opt = strtok (NULL, ",")) {
+                if (!strncmp (this_opt, "font:", 5)) {
+                        char *p;
+                        int i;
+        
+                        p = this_opt + 5;
+                        for (i=0; i<sizeof (fontname) - 1; i++)
+                                if (!*p || *p == ' ' || *p == ',')
+                                        break;
+                        memcpy(fontname, this_opt + 5, i);
+                } else if (!strncmp(this_opt, "noaccel", 7)) {
+                       noaccel = 1;
+               }
+                else    mode_option = this_opt;
+        }
+
+       return 0;
+}
+
+#ifdef MODULE
+module_init(radeonfb_init);
+module_exit(radeonfb_exit);
+#endif
+
+
+MODULE_AUTHOR("Ani Joshi");
+MODULE_DESCRIPTION("framebuffer driver for ATI Radeon chipset");
+MODULE_LICENSE("GPL");
+
+static int radeonfb_pci_register (struct pci_dev *pdev,
+                                 const struct pci_device_id *ent)
+{
+       struct radeonfb_info *rinfo;
+       u32 tmp;
+       int i, j;
+       char *bios_seg = NULL;
+
+       rinfo = kmalloc (sizeof (struct radeonfb_info), GFP_KERNEL);
+       if (!rinfo) {
+               printk ("radeonfb: could not allocate memory\n");
+               return -ENODEV;
+       }
+
+       memset (rinfo, 0, sizeof (struct radeonfb_info));
+
+       /* enable device */
+       {
+               int err;
+
+               if ((err = pci_enable_device(pdev))) {
+                       printk("radeonfb: cannot enable device\n");
+                       kfree (rinfo);
+                       return -ENODEV;
+               }
+       }
+
+       /* set base addrs */
+       rinfo->fb_base_phys = pci_resource_start (pdev, 0);
+       rinfo->mmio_base_phys = pci_resource_start (pdev, 2);
+
+       /* request the mem regions */
+       if (!request_mem_region (rinfo->fb_base_phys,
+                                pci_resource_len(pdev, 0), "radeonfb")) {
+               printk ("radeonfb: cannot reserve FB region\n");
+               kfree (rinfo);
+               return -ENODEV;
+       }
+
+       if (!request_mem_region (rinfo->mmio_base_phys,
+                                pci_resource_len(pdev, 2), "radeonfb")) {
+               printk ("radeonfb: cannot reserve MMIO region\n");
+               release_mem_region (rinfo->fb_base_phys,
+                                   pci_resource_len(pdev, 0));
+               kfree (rinfo);
+               return -ENODEV;
+       }
+
+       /* map the regions */
+       rinfo->mmio_base = (u32) ioremap (rinfo->mmio_base_phys,
+                                                   RADEON_REGSIZE);
+       if (!rinfo->mmio_base) {
+               printk ("radeonfb: cannot map MMIO\n");
+               release_mem_region (rinfo->mmio_base_phys,
+                                   pci_resource_len(pdev, 2));
+               release_mem_region (rinfo->fb_base_phys,
+                                   pci_resource_len(pdev, 0));
+               kfree (rinfo);
+               return -ENODEV;
+       }
+
+       /* chipset */
+       switch (pdev->device) {
+               case PCI_DEVICE_ID_RADEON_QD:
+                       strcpy(rinfo->name, "Radeon QD ");
+                       break;
+               case PCI_DEVICE_ID_RADEON_QE:
+                       strcpy(rinfo->name, "Radeon QE ");
+                       break;
+               case PCI_DEVICE_ID_RADEON_QF:
+                       strcpy(rinfo->name, "Radeon QF ");
+                       break;
+               case PCI_DEVICE_ID_RADEON_QG:
+                       strcpy(rinfo->name, "Radeon QG ");
+                       break;
+               default:
+                       return -ENODEV;
+       }
+
+       /* framebuffer size */
+       tmp = INREG(CONFIG_MEMSIZE);
+
+       /* mem size is bits [28:0], mask off the rest */
+       rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
+
+       /* ram type */
+       tmp = INREG(MEM_SDRAM_MODE_REG);
+       switch ((MEM_CFG_TYPE & tmp) >> 30) {
+               case 0:
+                       /* SDR SGRAM (2:1) */
+                       strcpy(rinfo->ram_type, "SDR SGRAM");
+                       rinfo->ram.ml = 4;
+                       rinfo->ram.mb = 4;
+                       rinfo->ram.trcd = 1;
+                       rinfo->ram.trp = 2;
+                       rinfo->ram.twr = 1;
+                       rinfo->ram.cl = 2;
+                       rinfo->ram.loop_latency = 16;
+                       rinfo->ram.rloop = 16;
+       
+                       break;
+               case 1:
+                       /* DDR SGRAM */
+                       strcpy(rinfo->ram_type, "DDR SGRAM");
+                       rinfo->ram.ml = 4;
+                       rinfo->ram.mb = 4;
+                       rinfo->ram.trcd = 3;
+                       rinfo->ram.trp = 3;
+                       rinfo->ram.twr = 2;
+                       rinfo->ram.cl = 3;
+                       rinfo->ram.tr2w = 1;
+                       rinfo->ram.loop_latency = 16;
+                       rinfo->ram.rloop = 16;
+
+                       break;
+               default:
+                       /* 64-bit SDR SGRAM */
+                       strcpy(rinfo->ram_type, "SDR SGRAM 64");
+                       rinfo->ram.ml = 4;
+                       rinfo->ram.mb = 8;
+                       rinfo->ram.trcd = 3;
+                       rinfo->ram.trp = 3;
+                       rinfo->ram.twr = 1;
+                       rinfo->ram.cl = 3;
+                       rinfo->ram.tr2w = 1;
+                       rinfo->ram.loop_latency = 17;
+                       rinfo->ram.rloop = 17;
+
+                       break;
+       }
+
+       bios_seg = radeon_find_rom(rinfo);
+       radeon_get_pllinfo(rinfo, bios_seg);
+
+       printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d\n",
+               rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
+
+       RTRACE("radeonfb: probed %s %dk videoram\n", (rinfo->ram_type), (rinfo->video_ram/1024));
+
+       rinfo->fb_base = (u32) ioremap (rinfo->fb_base_phys,
+                                                 rinfo->video_ram);
+       if (!rinfo->fb_base) {
+               printk ("radeonfb: cannot map FB\n");
+               iounmap ((void*)rinfo->mmio_base);
+               release_mem_region (rinfo->mmio_base_phys,
+                                   pci_resource_len(pdev, 2));
+               release_mem_region (rinfo->fb_base_phys,
+                                   pci_resource_len(pdev, 0));
+               kfree (rinfo);
+               return -ENODEV;
+       }
+
+       /* XXX turn off accel for now, blts aren't working right */
+       noaccel = 1;
+
+       /* set all the vital stuff */
+       radeon_set_fbinfo (rinfo);
+
+       /* save current mode regs before we switch into the new one
+        * so we can restore this upon __exit
+        */
+       radeon_save_state (rinfo, &rinfo->init_state);
+
+       /* init palette */
+       for (i=0; i<16; i++) {
+               j = color_table[i];
+               rinfo->palette[i].red = default_red[j];
+               rinfo->palette[i].green = default_grn[j];
+               rinfo->palette[i].blue = default_blu[j];
+       }
+
+       pdev->driver_data = rinfo;
+
+       if (register_framebuffer ((struct fb_info *) rinfo) < 0) {
+               printk ("radeonfb: could not register framebuffer\n");
+               iounmap ((void*)rinfo->fb_base);
+               iounmap ((void*)rinfo->mmio_base);
+               release_mem_region (rinfo->mmio_base_phys,
+                                   pci_resource_len(pdev, 2));
+               release_mem_region (rinfo->fb_base_phys,
+                                   pci_resource_len(pdev, 0));
+               kfree (rinfo);
+               return -ENODEV;
+       }
+
+       if (!noaccel) {
+               /* initialize the engine */
+               radeon_engine_init (rinfo);
+       }
+
+       printk ("radeonfb: ATI Radeon %s %d MB\n", rinfo->ram_type,
+               (rinfo->video_ram/(1024*1024)));
+
+       return 0;
+}
+
+
+
+static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
+{
+        struct radeonfb_info *rinfo = pdev->driver_data;
+        if (!rinfo)
+                return;
+       /* restore original state */
+        radeon_write_mode (rinfo, &rinfo->init_state);
+        unregister_framebuffer ((struct fb_info *) rinfo);
+                
+        iounmap ((void*)rinfo->mmio_base);
+        iounmap ((void*)rinfo->fb_base);
+       release_mem_region (rinfo->mmio_base_phys,
+                           pci_resource_len(pdev, 2));
+       release_mem_region (rinfo->fb_base_phys,
+                           pci_resource_len(pdev, 0));
+        
+        kfree (rinfo);
+}
+
+
+
+static char *radeon_find_rom(struct radeonfb_info *rinfo)
+{
+        u32  segstart;
+        char *rom_base;
+        char *rom;
+        int  stage;
+        int  i;
+        char aty_rom_sig[] = "761295520";
+        char radeon_sig[] = "RG6";
+
+#if defined(__i386__)
+       for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {   
+                stage = 1;
+                                
+                rom_base = (char *)ioremap(segstart, 0x1000);
+                                        
+                if ((*rom_base == 0x55) && (((*(rom_base + 1)) & 0xff) == 0xaa))
+                        stage = 2;
+                
+                        
+                if (stage != 2) { 
+                        iounmap(rom_base);
+                        continue;
+                }
+
+                rom = rom_base;
+
+                for (i = 0; (i < 128 - strlen(aty_rom_sig)) && (stage != 3); i++) {
+                        if (aty_rom_sig[0] == *rom)
+                                if (strncmp(aty_rom_sig, rom,
+                                                strlen(aty_rom_sig)) == 0)
+                                        stage = 3;
+                        rom++;
+                }  
+                if (stage != 3) {
+                        iounmap(rom_base);
+                        continue; 
+                }
+                rom = rom_base;
+                
+                for (i = 0; (i < 512) && (stage != 4); i++) {
+                        if (radeon_sig[0] == *rom)
+                                if (strncmp(radeon_sig, rom,
+                                                strlen(radeon_sig)) == 0)
+                                        stage = 4;
+                        rom++;
+                }
+                if (stage != 4) {
+                        iounmap(rom_base);
+                        continue;
+                }
+                
+                return rom_base;
+        }
+#endif                        
+        return NULL;
+}
+
+
+
+static void radeon_get_pllinfo(struct radeonfb_info *rinfo, char *bios_seg)
+{
+        void *bios_header;
+        void *header_ptr;
+        u16 bios_header_offset, pll_info_offset;
+        PLL_BLOCK pll;
+
+       if (bios_seg) {
+               bios_header = bios_seg + 0x48L;
+                       header_ptr  = bios_header;
+        
+               bios_header_offset = readw(header_ptr);
+               bios_header = bios_seg + bios_header_offset;
+               bios_header += 0x30;
+        
+               header_ptr = bios_header;
+               pll_info_offset = readw(header_ptr);
+               header_ptr = bios_seg + pll_info_offset;
+        
+               memcpy_fromio(&pll, header_ptr, 50);
+        
+               rinfo->pll.xclk = (u32)pll.XCLK;
+               rinfo->pll.ref_clk = (u32)pll.PCLK_ref_freq;
+               rinfo->pll.ref_div = (u32)pll.PCLK_ref_divider;
+               rinfo->pll.ppll_min = pll.PCLK_min_freq;
+               rinfo->pll.ppll_max = pll.PCLK_max_freq;
+       } else {
+               /* no BIOS or BIOS not found, use defaults */
+
+               rinfo->pll.ppll_max = 35000;
+               rinfo->pll.ppll_min = 12000;
+               rinfo->pll.xclk = 16600;
+               rinfo->pll.ref_div = 67;
+               rinfo->pll.ref_clk = 2700;
+       }
+}
+
+static void radeon_engine_init (struct radeonfb_info *rinfo)
+{
+       u32 temp;
+
+       /* disable 3D engine */
+       OUTREG(RB3D_CNTL, 0);
+
+       radeon_engine_reset ();
+
+       radeon_fifo_wait (1);
+       OUTREG(DSTCACHE_MODE, 0);
+
+       /* XXX */
+       rinfo->pitch = ((rinfo->xres * (rinfo->depth / 8) + 0x3f)) >> 6;
+
+       radeon_fifo_wait (1);
+       temp = INREG(DEFAULT_PITCH_OFFSET);
+       OUTREG(DEFAULT_PITCH_OFFSET, ((temp & 0xc0000000) | 
+                                     (rinfo->pitch << 0x16)));
+
+       radeon_fifo_wait (1);
+       OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);
+
+       radeon_fifo_wait (1);
+       OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX |
+                                        DEFAULT_SC_BOTTOM_MAX));
+
+       temp = radeon_get_dstbpp(rinfo->depth);
+       rinfo->dp_gui_master_cntl = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS);
+       radeon_fifo_wait (1);
+       OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
+                                   GMC_BRUSH_SOLID_COLOR |
+                                   GMC_SRC_DATATYPE_COLOR));
+
+       radeon_fifo_wait (7);
+
+       /* clear line drawing regs */
+       OUTREG(DST_LINE_START, 0);
+       OUTREG(DST_LINE_END, 0);
+
+       /* set brush color regs */
+       OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff);
+       OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000);
+
+       /* set source color regs */
+       OUTREG(DP_SRC_FRGD_CLR, 0xffffffff);
+       OUTREG(DP_SRC_BKGD_CLR, 0x00000000);
+
+       /* default write mask */
+       OUTREG(DP_WRITE_MSK, 0xffffffff);
+
+       radeon_engine_idle ();
+}
+
+
+
+static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
+{
+       struct fb_info *info;
+
+       info = &rinfo->info;
+
+       strcpy (info->modename, rinfo->name);
+        info->node = -1;
+        info->flags = FBINFO_FLAG_DEFAULT;
+        info->fbops = &radeon_fb_ops;
+        info->display_fg = NULL;
+        strncpy (info->fontname, fontname, sizeof (info->fontname));
+        info->fontname[sizeof (info->fontname) - 1] = 0;
+        info->changevar = NULL;
+        info->switch_con = radeonfb_switch;
+        info->updatevar = radeonfb_updatevar;
+        info->blank = radeonfb_blank;
+
+        if (radeon_init_disp (rinfo) < 0)
+                return -1;   
+
+        return 0;
+}
+
+
+
+static int __devinit radeon_init_disp (struct radeonfb_info *rinfo)
+{
+        struct fb_info *info;
+        struct display *disp;
+
+        info = &rinfo->info;
+        disp = &rinfo->disp;
+        
+        disp->var = radeonfb_default_var;
+        info->disp = disp;
+
+        radeon_set_dispsw (rinfo);
+
+       if (noaccel)
+               disp->scrollmode = SCROLL_YREDRAW;
+       else
+               disp->scrollmode = 0;
+        
+        rinfo->currcon_display = disp;
+
+        if ((radeon_init_disp_var (rinfo)) < 0)
+                return -1;
+        
+        return 0;
+}
+
+
+
+static int radeon_init_disp_var (struct radeonfb_info *rinfo)
+{
+#ifndef MODULE
+        if (mode_option)
+                fb_find_mode (&rinfo->disp.var, &rinfo->info, mode_option,
+                              NULL, 0, NULL, 8);
+        else
+#endif
+                fb_find_mode (&rinfo->disp.var, &rinfo->info, "640x480-8@60",
+                              NULL, 0, NULL, 0);
+
+       if (noaccel)
+               rinfo->disp.var.accel_flags &= ~FB_ACCELF_TEXT;
+       else
+               rinfo->disp.var.accel_flags |= FB_ACCELF_TEXT;
+        return 0;
+}
+
+
+
+static void radeon_set_dispsw (struct radeonfb_info *rinfo)
+{
+        struct display *disp = &rinfo->disp;
+       int accel;
+
+       accel = disp->var.accel_flags & FB_ACCELF_TEXT;
+        
+        disp->dispsw_data = NULL;
+
+       disp->screen_base = (char*)rinfo->fb_base;
+        disp->type = FB_TYPE_PACKED_PIXELS;
+        disp->type_aux = 0;
+        disp->ypanstep = 1;
+        disp->ywrapstep = 0;
+        disp->can_soft_blank = 1;
+        disp->inverse = 0;   
+
+       rinfo->depth = disp->var.bits_per_pixel;        
+        switch (disp->var.bits_per_pixel) {
+#ifdef FBCON_HAS_CFB8
+                case 8:
+                        disp->dispsw = accel ? &fbcon_radeon8 : &fbcon_cfb8;
+                       disp->visual = FB_VISUAL_PSEUDOCOLOR;
+                       disp->line_length = disp->var.xres_virtual;
+                        break;
+#endif                 
+#ifdef FBCON_HAS_CFB16
+                case 16:
+                        disp->dispsw = &fbcon_cfb16;
+                        disp->dispsw_data = &rinfo->con_cmap.cfb16;
+                       disp->visual = FB_VISUAL_DIRECTCOLOR;
+                       disp->line_length = disp->var.xres_virtual * 2;
+                        break;
+#endif
+#ifdef FBCON_HAS_CFB32
+                case 32:
+                        disp->dispsw = &fbcon_cfb32;
+                        disp->dispsw_data = &rinfo->con_cmap.cfb32;
+                       disp->visual = FB_VISUAL_DIRECTCOLOR;
+                       disp->line_length = disp->var.xres_virtual * 4;
+                        break;
+#endif
+                default:
+                        printk ("radeonfb: setting fbcon_dummy renderer\n");
+                        disp->dispsw = &fbcon_dummy;
+        }
+        
+        return;
+}
+
+
+
+/*
+ * fb ops
+ */
+
+static int radeonfb_get_fix (struct fb_fix_screeninfo *fix, int con,
+                             struct fb_info *info)
+{
+        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
+        struct display *disp;  
+        
+        disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
+
+        memset (fix, 0, sizeof (struct fb_fix_screeninfo));
+       strcpy (fix->id, rinfo->name);
+        
+        fix->smem_start = rinfo->fb_base_phys;
+        fix->smem_len = rinfo->video_ram;
+
+        fix->type = disp->type;
+        fix->type_aux = disp->type_aux;
+        fix->visual = disp->visual;
+
+        fix->xpanstep = 1;
+        fix->ypanstep = 1;
+        fix->ywrapstep = 0;
+        
+        fix->line_length = disp->line_length;
+        fix->mmio_start = rinfo->mmio_base_phys;
+        fix->mmio_len = RADEON_REGSIZE;
+       if (noaccel)
+               fix->accel = FB_ACCEL_NONE;
+       else
+               fix->accel = 40;        /* XXX */
+        
+        return 0;
+}
+
+
+
+static int radeonfb_get_var (struct fb_var_screeninfo *var, int con,
+                             struct fb_info *info)
+{
+        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
+        
+        *var = (con < 0) ? rinfo->disp.var : fb_display[con].var;
+        
+        return 0;
+}
+
+
+
+static int radeonfb_set_var (struct fb_var_screeninfo *var, int con,
+                             struct fb_info *info)
+{
+        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
+        struct display *disp;
+        struct fb_var_screeninfo v;
+        int nom, den, i, accel;
+        unsigned chgvar = 0;
+        static struct {
+                int xres, yres;
+        } modes[] = {
+                {
+                1600, 1280}, {
+                1280, 1024}, {
+                1024, 768}, {
+                800, 600}, {
+                640, 480}, {
+                -1, -1}
+        };
+        disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
+
+       accel = var->accel_flags & FB_ACCELF_TEXT;
+  
+        if (con >= 0) {
+                chgvar = ((disp->var.xres != var->xres) ||
+                          (disp->var.yres != var->yres) ||
+                          (disp->var.xres_virtual != var->xres_virtual) ||
+                          (disp->var.yres_virtual != var->yres_virtual) ||
+                          memcmp (&disp->var.red, &var->red, sizeof (var->red)) ||
+                          memcmp (&disp->var.green, &var->green, sizeof (var->green)) ||
+                          memcmp (&disp->var.blue, &var->blue, sizeof (var->blue)));
+        }
+                
+        memcpy (&v, var, sizeof (v));
+        
+        switch (v.bits_per_pixel) {
+#ifdef FBCON_HAS_CFB8
+                case 8:
+                        v.bits_per_pixel = 8;
+                        disp->dispsw = accel ? &fbcon_radeon8 : &fbcon_cfb8;
+                        nom = den = 1;
+                        disp->line_length = v.xres_virtual;
+                        disp->visual = FB_VISUAL_PSEUDOCOLOR;
+                        v.red.offset = v.green.offset = v.blue.offset = 0;
+                        v.red.length = v.green.length = v.blue.length = 8;
+                        break;
+#endif
+                          
+#ifdef FBCON_HAS_CFB16
+                case 16:
+                        v.bits_per_pixel = 16;
+                        disp->dispsw = &fbcon_cfb16;
+                        disp->dispsw_data = &rinfo->con_cmap.cfb16;
+                        nom = 2;
+                        den = 1;
+                        disp->line_length = v.xres_virtual * 2;
+                        disp->visual = FB_VISUAL_DIRECTCOLOR;
+                        v.red.offset = 11;
+                        v.green.offset = 5;
+                        v.blue.offset = 0;
+                       v.red.length = 5;
+                       v.green.length = 6;
+                       v.blue.length = 5;
+                        break;
+#endif
+
+#ifdef FBCON_HAS_CFB32    
+                case 32:
+                        v.bits_per_pixel = 32;
+                        disp->dispsw = &fbcon_cfb32;
+                        disp->dispsw_data = rinfo->con_cmap.cfb32;
+                        nom = 4;
+                        den = 1;
+                        disp->line_length = v.xres_virtual * 4;
+                        disp->visual = FB_VISUAL_DIRECTCOLOR;  
+                        v.red.offset = 16;
+                        v.green.offset = 8;
+                        v.blue.offset = 0; 
+                        v.red.length = v.blue.length = v.green.length = 8;
+                        break;
+#endif
+                default:
+                        printk ("radeonfb: mode %dx%dx%d rejected, color depth invalid\n",
+                                var->xres, var->yres, var->bits_per_pixel);
+                        return -EINVAL;
+        }
+
+        if (v.xres * nom / den * v.yres > (rinfo->video_ram)) {
+                printk ("radeonfb: mode %dx%dx%d rejected, not enough video ram\n",
+                        var->xres, var->yres, var->bits_per_pixel);
+                        return -EINVAL;
+        }
+  
+        if (v.xres_virtual == -1 && v.yres_virtual == -1) {
+                printk ("radeonfb: using maximum available virtual resolution\n");
+                for (i = 0; modes[i].xres != -1; i++) {
+                        if (modes[i].xres * nom / den * modes[i].yres < (rinfo->video_ram/2))
+                                break;
+                }
+                if (modes[i].xres == -1) {
+                        printk ("radeonfb: could not find a virtual res\n");
+                        return -EINVAL;
+                }
+                v.xres_virtual = modes[i].xres;
+                v.yres_virtual = modes[i].yres;
+                
+                printk ("radeonfb: virtual resolution set to maximum of %dx%d\n",
+                        v.xres_virtual, v.yres_virtual);
+        }
+  
+        if (v.xoffset < 0)
+                v.xoffset = 0;
+        if (v.yoffset < 0)
+                v.yoffset = 0;
+                                
+        if (v.xoffset > v.xres_virtual - v.xres)
+                v.xoffset = v.xres_virtual - v.xres - 1;
+                        
+        if (v.yoffset > v.yres_virtual - v.yres)
+                v.yoffset = v.yres_virtual - v.yres - 1;
+                
+        v.red.msb_right = v.green.msb_right = v.blue.msb_right =
+                          v.transp.offset = v.transp.length =
+                          v.transp.msb_right = 0;
+                        
+        switch (v.activate & FB_ACTIVATE_MASK) {
+                case FB_ACTIVATE_TEST:
+                        return 0;
+                case FB_ACTIVATE_NXTOPEN:
+                case FB_ACTIVATE_NOW:
+                        break;
+                default:        
+                        return -EINVAL;
+        }
+                        
+        disp->type = FB_TYPE_PACKED_PIXELS;
+                
+        memcpy (&disp->var, &v, sizeof (v));
+
+       radeon_load_video_mode (rinfo, &v);
+
+        if (chgvar && info && info->changevar)
+                info->changevar (con);
+  
+        return 0;
+}
+
+
+
+static int radeonfb_get_cmap (struct fb_cmap *cmap, int kspc, int con,
+                              struct fb_info *info)
+{
+        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
+        struct display *disp;
+                
+        disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
+        
+        if (con == rinfo->currcon) {
+                int rc = fb_get_cmap (cmap, kspc, radeon_getcolreg, info);
+                return rc;
+        } else if (disp->cmap.len)
+                fb_copy_cmap (&disp->cmap, cmap, kspc ? 0 : 2);
+        else
+                fb_copy_cmap (fb_default_cmap (radeon_get_cmap_len (&disp->var)),
+                              cmap, kspc ? 0 : 2);
+                        
+        return 0;
+}
+
+
+
+static int radeonfb_set_cmap (struct fb_cmap *cmap, int kspc, int con,
+                              struct fb_info *info)
+{
+        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
+        struct display *disp;
+        unsigned int cmap_len;
+                
+        disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
+  
+        cmap_len = radeon_get_cmap_len (&disp->var);
+        if (disp->cmap.len != cmap_len) {
+                int err = fb_alloc_cmap (&disp->cmap, cmap_len, 0);
+                if (err)
+                        return err;
+        }
+        if (con == rinfo->currcon) {
+                int rc = fb_set_cmap (cmap, kspc, radeon_setcolreg, info);
+                return rc;
+        } else
+                fb_copy_cmap (cmap, &disp->cmap, kspc ? 0 : 1);
+        
+        return 0;
+}               
+
+
+
+static int radeonfb_pan_display (struct fb_var_screeninfo *var, int con,
+                                 struct fb_info *info)
+{
+        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
+        struct display *disp;
+        unsigned int base;
+         
+        disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
+        
+        if (var->xoffset > (var->xres_virtual - var->xres))
+                return -EINVAL;
+        if (var->yoffset > (var->yres_virtual - var->yres))
+                return -EINVAL;
+        
+        if (var->vmode & FB_VMODE_YWRAP) {
+                if (var->yoffset < 0 || 
+                    var->yoffset >= disp->var.yres_virtual ||
+                    var->xoffset )
+                        return -EINVAL;
+        } else {
+                if (var->xoffset + disp->var.xres > disp->var.xres_virtual ||
+                    var->yoffset + disp->var.yres > disp->var.yres_virtual)
+                        return -EINVAL;
+        }
+
+        base = var->yoffset * disp->line_length + var->xoffset;
+        
+        disp->var.xoffset = var->xoffset;
+        disp->var.yoffset = var->yoffset;
+
+        if (var->vmode & FB_VMODE_YWRAP)
+                disp->var.vmode |= FB_VMODE_YWRAP;
+        else
+                disp->var.vmode &= ~FB_VMODE_YWRAP;
+        
+        return 0;
+}
+
+
+
+static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
+                           unsigned long arg, int con, struct fb_info *info)
+{
+       return -EINVAL;
+}
+
+
+
+static int radeonfb_switch (int con, struct fb_info *info)
+{
+        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
+        struct display *disp;
+        struct fb_cmap *cmap;
+       int switchcon = 0;
+        
+        disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
+        if (rinfo->currcon >= 0) {
+                cmap = &(rinfo->currcon_display->cmap);
+                if (cmap->len)
+                        fb_get_cmap (cmap, 1, radeon_getcolreg, info);
+        }
+
+       if ((disp->var.xres != rinfo->xres) ||
+           (disp->var.yres != rinfo->yres) ||
+           (disp->var.pixclock != rinfo->pixclock) ||
+           (disp->var.bits_per_pixel != rinfo->depth))
+               switchcon = 1;
+
+       if (switchcon) {
+               rinfo->currcon = con;
+                       rinfo->currcon_display = disp;
+               disp->var.activate = FB_ACTIVATE_NOW;
+
+               radeonfb_set_var (&disp->var, con, info);
+               radeon_set_dispsw (rinfo);
+       }
+  
+        return 0;
+}
+
+
+
+static int radeonfb_updatevar (int con, struct fb_info *info)
+{
+        int rc;
+                
+        rc = (con < 0) ? -EINVAL : radeonfb_pan_display (&fb_display[con].var,
+                                                         con, info);
+        
+        return rc;
+}
+
+static void radeonfb_blank (int blank, struct fb_info *info)
+{
+        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
+       u8 mode = 0;
+
+       switch (blank) {
+               case 0:
+                       /* unblank */
+                       mode = 0;
+                       break;
+               case 1:
+                       /* blank */
+                       mode = ((INREG8(CRTC_EXT_CNTL + 1) & 3) | 4);
+                       break;
+               case 2:
+               case 3:
+               case 4:
+                       mode = blank | 4;
+                       break;
+       }
+
+       OUTREG8(CRTC_EXT_CNTL + 1, mode);
+}
+
+
+
+static int radeon_get_cmap_len (const struct fb_var_screeninfo *var)
+{
+        int rc = 16;            /* reasonable default */
+        
+        switch (var->bits_per_pixel) {
+                case 8:
+                        rc = 256;
+                        break;
+               case 16:
+                       rc = 64;
+                       break;
+                default:
+                        rc = 32;
+                        break;
+        }
+                
+        return rc;
+}
+
+
+
+static int radeon_getcolreg (unsigned regno, unsigned *red, unsigned *green,
+                             unsigned *blue, unsigned *transp,
+                             struct fb_info *info)
+{
+        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
+       
+       if (regno > 255)
+               return 1;
+     
+       *red = (rinfo->palette[regno].red<<8) | rinfo->palette[regno].red; 
+       *green = (rinfo->palette[regno].green<<8) | rinfo->palette[regno].green;
+       *blue = (rinfo->palette[regno].blue<<8) | rinfo->palette[regno].blue;
+       *transp = 0;
+
+       return 0;
+}                            
+
+
+
+static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green,
+                             unsigned blue, unsigned transp, struct fb_info *info)
+{
+        struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
+       u32 pindex, col;
+
+       if (regno > 255)
+               return 1;
+
+       red >>= 8;
+       green >>= 8;
+       blue >>= 8;
+       rinfo->palette[regno].red = red;
+       rinfo->palette[regno].green = green;
+       rinfo->palette[regno].blue = blue;
+
+       /* init gamma for hicolor */
+       if ((rinfo->depth > 8) && (regno == 0)) {
+               int i;
+               u32 tmp;
+
+               for (i=0; i<255; i++) {
+                       OUTREG(PALETTE_INDEX, i);
+                       tmp = (i << 16) | (i << 8) | i;
+                       radeon_fifo_wait(32);
+                       OUTREG(PALETTE_DATA, tmp);
+               }
+       }
+
+       /* default */
+       pindex = regno;
+       col = (red << 16) | (green << 8) | blue;
+
+       if (rinfo->depth == 16) {
+               pindex = regno << 3;
+
+               if ((rinfo->depth == 16) && (regno >= 32)) {
+                       pindex -= 252;
+
+                       col = (rinfo->palette[regno >> 1].red << 16) |
+                                       (green << 8) |
+                                       (rinfo->palette[regno >> 1].blue);
+               } else {
+                       col = (red << 16) | (green << 8) | blue;
+               }
+       }
+       
+       OUTREG8(PALETTE_INDEX, pindex);
+       radeon_fifo_wait(32);
+       OUTREG(PALETTE_DATA, col);
+
+#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
+       if (regno < 32) {
+               switch (rinfo->depth) {
+#ifdef FBCON_HAS_CFB16
+                       case 16:
+                               rinfo->con_cmap.cfb16[regno] = (regno << 10) | (regno << 5) |
+                                                                 regno;   
+                               break;
+#endif
+#ifdef FBCON_HAS_CFB32
+                       case 32: {
+                               u32 i;    
+   
+                               i = (regno << 8) | regno;
+                               rinfo->con_cmap.cfb32[regno] = (i << 16) | i;
+                               break;
+                       }
+#endif
+               }
+        }
+#endif
+       return 0;
+}
+
+
+
+static void radeon_save_state (struct radeonfb_info *rinfo,
+                               struct radeon_regs *save)
+{
+       save->crtc_gen_cntl = INREG(CRTC_GEN_CNTL);
+       save->crtc_ext_cntl = INREG(CRTC_EXT_CNTL);
+       save->dac_cntl = INREG(DAC_CNTL);
+        save->crtc_h_total_disp = INREG(CRTC_H_TOTAL_DISP);
+        save->crtc_h_sync_strt_wid = INREG(CRTC_H_SYNC_STRT_WID);
+        save->crtc_v_total_disp = INREG(CRTC_V_TOTAL_DISP);
+        save->crtc_v_sync_strt_wid = INREG(CRTC_V_SYNC_STRT_WID);
+       save->crtc_pitch = INREG(CRTC_PITCH);
+}
+
+
+
+static void radeon_load_video_mode (struct radeonfb_info *rinfo,
+                                    struct fb_var_screeninfo *mode)
+{
+       struct radeon_regs newmode;
+       int hTotal, vTotal, hSyncStart, hSyncEnd,
+           hSyncPol, vSyncStart, vSyncEnd, vSyncPol, cSync;
+       u8 hsync_adj_tab[] = {0, 0x12, 9, 9, 6, 5};
+       u32 dotClock = 1000000000 / mode->pixclock,
+           sync, h_sync_pol, v_sync_pol;
+       int freq = dotClock / 10;  /* x 100 */
+        int xclk_freq, vclk_freq, xclk_per_trans, xclk_per_trans_precise;
+        int useable_precision, roff, ron;
+        int min_bits, format = 0;
+       int hsync_start, hsync_fudge, bytpp, hsync_wid, vsync_wid;
+
+       rinfo->xres = mode->xres;
+       rinfo->yres = mode->yres;
+       rinfo->pixclock = mode->pixclock;
+
+       hSyncStart = mode->xres + mode->right_margin;
+       hSyncEnd = hSyncStart + mode->hsync_len;
+       hTotal = hSyncEnd + mode->left_margin;
+
+       vSyncStart = mode->yres + mode->lower_margin;
+       vSyncEnd = vSyncStart + mode->vsync_len;
+       vTotal = vSyncEnd + mode->upper_margin;
+
+       sync = mode->sync;
+       h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
+       v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
+
+       RTRACE("hStart = %d, hEnd = %d, hTotal = %d\n",
+               hSyncStart, hSyncEnd, hTotal);
+       RTRACE("vStart = %d, vEnd = %d, vTotal = %d\n",
+               vSyncStart, vSyncEnd, vTotal);
+
+       hsync_wid = (hSyncEnd - hSyncStart) / 8;
+       vsync_wid = vSyncEnd - vSyncStart;
+       if (hsync_wid == 0)
+               hsync_wid = 1;
+       else if (hsync_wid > 0x3f)      /* max */
+               hsync_wid = 0x3f;
+       vsync_wid = mode->vsync_len;
+       if (vsync_wid == 0)
+               vsync_wid = 1;
+       else if (vsync_wid > 0x1f)      /* max */
+               vsync_wid = 0x1f;
+
+       hSyncPol = mode->sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
+       vSyncPol = mode->sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
+
+       cSync = mode->sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0;
+
+       switch (mode->bits_per_pixel) {
+               case 8:
+                       format = DST_8BPP;
+                       bytpp = 1;
+                       break;
+               case 16:
+                       format = DST_16BPP;
+                       bytpp = 2;
+                       break;
+               case 24:
+                       format = DST_24BPP;
+                       bytpp = 3;
+                       break;
+               case 32:
+                       format = DST_32BPP;
+                       bytpp = 4;
+                       break;
+       }
+
+       hsync_fudge = hsync_adj_tab[format-1];
+       hsync_start = hSyncStart - 8 + hsync_fudge;
+
+       newmode.crtc_gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN |
+                               (format << 8);
+
+       newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN;
+
+       newmode.dac_cntl = INREG(DAC_CNTL) | DAC_MASK_ALL | DAC_VGA_ADR_EN |
+                          DAC_8BIT_EN;
+
+       newmode.crtc_h_total_disp = ((((hTotal / 8) - 1) & 0xffff) |
+                                    (((mode->xres / 8) - 1) << 16));
+
+       newmode.crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) |
+                                       (hsync_wid << 16) | (h_sync_pol << 23));
+
+       newmode.crtc_v_total_disp = ((vTotal - 1) & 0xffff) |
+                                   ((mode->yres - 1) << 16);
+
+       newmode.crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) |
+                                        (vsync_wid << 16) | (v_sync_pol  << 23));
+
+       newmode.crtc_pitch = (mode->xres >> 3);
+
+       rinfo->pitch = ((mode->xres * ((mode->bits_per_pixel + 1) / 8) + 0x3f)
+                       & ~(0x3f)) / 64;
+
+       RTRACE("h_total_disp = 0x%x\t   hsync_strt_wid = 0x%x\n",
+               newmode.crtc_h_total_disp, newmode.crtc_h_sync_strt_wid);
+       RTRACE("v_total_disp = 0x%x\t   vsync_strt_wid = 0x%x\n",
+               newmode.crtc_v_total_disp, newmode.crtc_v_sync_strt_wid);
+
+       newmode.xres = mode->xres;
+       newmode.yres = mode->yres;
+
+       rinfo->bpp = mode->bits_per_pixel;
+
+       if (freq > rinfo->pll.ppll_max)
+               freq = rinfo->pll.ppll_max;
+       if (freq*12 < rinfo->pll.ppll_min)
+               freq = rinfo->pll.ppll_min / 12;
+
+       {
+               struct {
+                       int divider;
+                       int bitvalue;
+               } *post_div,
+                 post_divs[] = {
+                       { 1,  0 },
+                       { 2,  1 },
+                       { 4,  2 },
+                       { 8,  3 },
+                       { 3,  4 },
+                       { 16, 5 },
+                       { 6,  6 },
+                       { 12, 7 },
+                       { 0,  0 },
+               };
+
+               for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
+                       rinfo->pll_output_freq = post_div->divider * freq;
+                       if (rinfo->pll_output_freq >= rinfo->pll.ppll_min  &&
+                           rinfo->pll_output_freq <= rinfo->pll.ppll_max)
+                               break;
+               }
+
+               rinfo->post_div = post_div->divider;
+               rinfo->fb_div = round_div(rinfo->pll.ref_div*rinfo->pll_output_freq,
+                                         rinfo->pll.ref_clk);
+               newmode.ppll_ref_div = rinfo->pll.ref_div;
+               newmode.ppll_div_3 = rinfo->fb_div | (post_div->bitvalue << 16);
+       }
+
+       RTRACE("post div = 0x%x\n", rinfo->post_div);
+       RTRACE("fb_div = 0x%x\n", rinfo->fb_div);
+       RTRACE("ppll_div_3 = 0x%x\n", newmode.ppll_div_3);
+
+       /* DDA */
+       vclk_freq = round_div(rinfo->pll.ref_clk * rinfo->fb_div,
+                             rinfo->pll.ref_div * rinfo->post_div);
+       xclk_freq = rinfo->pll.xclk;
+
+       xclk_per_trans = round_div(xclk_freq * 128, vclk_freq * mode->bits_per_pixel);
+
+       min_bits = min_bits_req(xclk_per_trans);
+       useable_precision = min_bits + 1;
+
+       xclk_per_trans_precise = round_div((xclk_freq * 128) << (11 - useable_precision),
+                                          vclk_freq * mode->bits_per_pixel);
+
+       ron = (4 * rinfo->ram.mb + 3 * _max(rinfo->ram.trcd - 2, 0) +
+              2 * rinfo->ram.trp + rinfo->ram.twr + rinfo->ram.cl + rinfo->ram.tr2w +
+              xclk_per_trans) << (11 - useable_precision);
+       roff = xclk_per_trans_precise * (32 - 4);
+
+       RTRACE("ron = %d, roff = %d\n", ron, roff);
+       RTRACE("vclk_freq = %d, per = %d\n", vclk_freq, xclk_per_trans_precise);
+
+       if ((ron + rinfo->ram.rloop) >= roff) {
+               printk("radeonfb: error ron out of range\n");
+               return;
+       }
+
+       newmode.dda_config = (xclk_per_trans_precise |
+                             (useable_precision << 16) |
+                             (rinfo->ram.rloop << 20));
+       newmode.dda_on_off = (ron << 16) | roff;
+
+       /* do it! */
+       radeon_write_mode (rinfo, &newmode);
+
+       return;
+}
+
+
+
+static void radeon_write_mode (struct radeonfb_info *rinfo,
+                               struct radeon_regs *mode)
+{
+       int i;
+
+       /* blank screen */
+       OUTREG8(CRTC_EXT_CNTL + 1, 4);
+
+       for (i=0; i<9; i++)
+               OUTREG(common_regs[i].reg, common_regs[i].val);
+
+       OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
+       OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
+               CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS);
+       OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
+       OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
+       OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
+       OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
+       OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
+       OUTREG(CRTC_OFFSET, 0);
+       OUTREG(CRTC_OFFSET_CNTL, 0);
+       OUTREG(CRTC_PITCH, mode->crtc_pitch);
+
+       while ((INREG(CLOCK_CNTL_INDEX) & PPLL_DIV_SEL_MASK) !=
+              PPLL_DIV_SEL_MASK) {
+               OUTREGP(CLOCK_CNTL_INDEX, PPLL_DIV_SEL_MASK, 0xffff);
+       }
+
+       OUTPLLP(PPLL_CNTL, PPLL_RESET, 0xffff);
+
+       while ((INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK) !=
+              (mode->ppll_ref_div & PPLL_REF_DIV_MASK)) {
+               OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK);
+       }
+
+       while ((INPLL(PPLL_DIV_3) & PPLL_FB3_DIV_MASK) !=
+              (mode->ppll_div_3 & PPLL_FB3_DIV_MASK)) {
+               OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK);
+       }
+
+       while ((INPLL(PPLL_DIV_3) & PPLL_POST3_DIV_MASK) !=
+              (mode->ppll_div_3 & PPLL_POST3_DIV_MASK)) {
+               OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK);
+       }
+
+       OUTPLL(HTOTAL_CNTL, 0);
+
+       OUTPLLP(PPLL_CNTL, 0, ~PPLL_RESET);
+
+       OUTREG(DDA_CONFIG, mode->dda_config);
+       OUTREG(DDA_ON_OFF, mode->dda_on_off);
+
+       /* unblank screen */
+       OUTREG8(CRTC_EXT_CNTL + 1, 0);
+
+       return;
+}
+
+
+
+/*
+ * text console acceleration
+ */
+
+
+static void fbcon_radeon_bmove(struct display *p, int srcy, int srcx,
+                              int dsty, int dstx, int height, int width)
+{
+       struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
+       u32 dp_cntl = DST_LAST_PEL;
+
+       srcx *= fontwidth(p);
+       srcy *= fontheight(p);
+       dstx *= fontwidth(p);
+       dsty *= fontheight(p);
+       width *= fontwidth(p);
+       height *= fontheight(p);
+
+       if (srcy < dsty) {
+               srcy += height - 1;
+               dsty += height - 1;
+       } else
+               dp_cntl |= DST_Y_TOP_TO_BOTTOM;
+
+       if (srcx < dstx) {
+               srcx += width - 1;
+               dstx += width - 1;
+       } else
+               dp_cntl |= DST_X_LEFT_TO_RIGHT;
+
+       radeon_fifo_wait(6);
+       OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
+                                   GMC_BRUSH_NONE |
+                                   GMC_SRC_DATATYPE_COLOR |
+                                   ROP3_S |
+                                   DP_SRC_SOURCE_MEMORY));
+       OUTREG(DP_WRITE_MSK, 0xffffffff);
+       OUTREG(DP_CNTL, dp_cntl);
+       OUTREG(SRC_Y_X, (srcy << 16) | srcx);
+       OUTREG(DST_Y_X, (dsty << 16) | dstx);
+       OUTREG(DST_HEIGHT_WIDTH, (height << 16) | width);
+}
+
+
+
+static void fbcon_radeon_clear(struct vc_data *conp, struct display *p,
+                              int srcy, int srcx, int height, int width)
+{
+       struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
+       u32 clr;
+
+       clr = attr_bgcol_ec(p, conp);
+       clr |= (clr << 8);
+       clr |= (clr << 16);
+
+       srcx *= fontwidth(p);
+       srcy *= fontheight(p);
+       width *= fontwidth(p);
+       height *= fontheight(p);
+
+       radeon_fifo_wait(6);
+       OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
+                                   GMC_BRUSH_SOLID_COLOR |
+                                   GMC_SRC_DATATYPE_COLOR |
+                                   ROP3_P));
+       OUTREG(DP_BRUSH_FRGD_CLR, clr);
+       OUTREG(DP_WRITE_MSK, 0xffffffff);
+       OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
+       OUTREG(DST_Y_X, (srcy << 16) | srcx);
+       OUTREG(DST_WIDTH_HEIGHT, (width << 16) | height);
+}
+
+
+
+
+#ifdef FBCON_HAS_CFB8
+static struct display_switch fbcon_radeon8 = {
+       setup:                  fbcon_cfb8_setup,
+       bmove:                  fbcon_radeon_bmove,
+       clear:                  fbcon_cfb8_clear,
+       putc:                   fbcon_cfb8_putc,
+       putcs:                  fbcon_cfb8_putcs,
+       revc:                   fbcon_cfb8_revc,
+       clear_margins:          fbcon_cfb8_clear_margins,
+       fontwidthmask:          FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
index b3de7cdb7e65573fee4dbf041fa60735db4f4761..c6852569c32f9b7a131ecd27c6025af62600399b 100644 (file)
@@ -260,7 +260,7 @@ static char nomtrr __initdata = 0;
 #endif
 
 #ifndef MODULE
-static const char *mode_option __initdata = NULL;
+static char *mode_option __initdata = NULL;
 #else
 static char *font = NULL;
 #endif
@@ -1109,6 +1109,8 @@ static int riva_get_cmap_len(const struct fb_var_screeninfo *var)
                break;
 #endif
 #ifdef FBCON_HAS_CFB16
+       case 15:
+               rc = 15;        /* fix for 15 bpp depths on Riva 128 based cards */
        case 16:
                rc = 16;        /* directcolor... 16 entries SW palette */
                break;          /* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
@@ -1119,7 +1121,6 @@ static int riva_get_cmap_len(const struct fb_var_screeninfo *var)
                break;          /* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
 #endif
        default:
-               assert(0);
                /* should not occur */
                break;
        }
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c
new file mode 100644 (file)
index 0000000..0cea53f
--- /dev/null
@@ -0,0 +1,2067 @@
+/*
+ * linux/drivers/video/sstfb.c -- voodoo graphics frame buffer
+ *
+ *     Copyright (c) 2000,2001 Ghozlane Toumi <gtoumi@messel.emse.fr>
+ *
+ *     Created 15 Jan 2000 by Ghozlane Toumi
+ *
+ * Contributions (and many thanks) :
+ *
+ * 03/2001 James Simmons   <jsimmons@linux-fbdev.org>
+ * 04/2001 Paul Mundt      <lethal@chaoticdreams.org>
+ * 05/2001 Urs Ganse       <urs.ganse@t-online.de>
+ *     (initial work on voodoo2 port)
+ *
+ *
+ * $Id: sstfb.c,v 1.26.4.1 2001/08/29 01:30:37 ghoz Exp $
+ */
+
+/*
+ * The voodoo1 has the following memory mapped adress space:
+ * 0x000000 - 0x3fffff : registers              (4Mb)
+ * 0x400000 - 0x7fffff : linear frame buffer    (4Mb)
+ * 0x800000 - 0xffffff : texture memory         (8Mb)
+ */
+
+/*
+ * misc notes, TODOs, toASKs, and deep thoughts
+
+-TODO: at one time or another test that the mode is acceptable by the monitor
+-ASK: I can choose different ordering for the color bitfields (rgba argb ...) 
+      wich one should i use ? is there any preferred one ? It seems ARGB is 
+      the one ...
+-ASK: later: how to cope with endianness ? the fbi chip has builtin functions
+      to do byte swizling /swapping, maybe use that ...
+-TODO: check the error paths . if something get wrong, the error doesn't seem 
+      to be very well handled...if handled at all.. not good. 
+-ASK: ioremap ou ioremap_nocache ? : nocache is safe
+-TODO: in  set_var check the validity of timings (hsync vsync)...
+-FIXME: I'm not sure i like all the functions with no parameters.. change them 
+        to use a sstfb_par or sstfb_info or something like that.
+-TODO: check and recheck the use of sst_wait_idle : we dont flush the fifo via 
+       a nop command . so it's ok as long as the commands we pass don't go 
+       through the fifo. warning: issuing a nop command seems to need pci_fifo 
+       enabled
+-ASK: the 24 bits mode is NOT packed . how do i differenciate from a packed mode ?
+      set a pseudo alpha value not used ?
+-ASK: how does the 32 bpp work ? should i enable the pipeline so alpha values 
+      are used ?
+-TODO: check how the voodoo graphics can cope with 24/32 bpp (engine is 16bpp 
+       only)
+-ASK: Do i ioremap the complete area devoted to the lfb (4Mb), or check the 
+      real size, then unmap and remap to the real size of the lfb ? 
+      ... map all the area.
+-FIXME: in case of failure in the init sequence, be sure we return to a safe 
+        state.
+-FIXME: 4MB boards have banked memory (FbiInit2 bits 1 & 20)
+-ASK: I stole "inverse" but seems it doesn't work... check what it realy does...
+Notes
+-TODO: change struct sst_info fb_info from static to array/dynamic
+  TTT comments is for code i've put there for debuging the "weird peinguin 
+       syndrome", it should disapear soon
+
+ *
+ */
+
+/*
+ * debug info
+ * SST_DEBUG : enable debugging
+ * SST_DEBUG_REG : debug registers
+ *   0 :  no debug
+ *   1 : dac calls, [un]set_bits, FbiInit
+ *   2 : insane debug level (log every register read/write)
+ * SST_DEBUG_FUNC : functions
+ *   0 : no debug
+ *   1 : function call / debug ioctl
+ *   2 : variables
+ *   3 : flood . you don't want to do that. trust me.
+ * SST_DEBUG_VAR : debug display/var structs
+ *   0 : no debug
+ *   1 : dumps display, fb_var
+ * SST_DEBUG_IOCTL : enable sstfb specific ioctls
+ *   0 : disable
+ *   1 : enable debug ioctls :
+ *             toggle vga (0x46db) : toggle vga_pass_through
+ *             fill fb    (0x46dc) : fills fb
+ *             dump var   (0x46dd) : logs display[0-5].var
+ *             test disp  (0x46de) : draws a test motif
+ */
+
+/* #define SST_DEBUG */
+#undef SST_DEBUG
+
+#define SST_DEBUG_REG   0
+#define SST_DEBUG_FUNC  0
+#define SST_DEBUG_VAR   0
+#define SST_DEBUG_IOCTL 1
+
+/* #define EN_24_32_BPP  *//* enable 24/32 bpp functions for testing only */
+#undef EN_24_32_BPP
+
+/*
+  Default video mode .
+  0 800x600@60  took from glide
+  1 640x480@75  took from glide
+  2 1024x768@76 std fb.mode
+  3 640x480@60  glide default */
+#define DEFAULT_MODE 1
+/*
+ * Includes
+ */
+
+#include <linux/string.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/tty.h>
+#include <linux/fb.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/version.h>
+
+#include <asm/io.h>
+#include <asm/ioctl.h>
+
+#include <video/fbcon.h>
+#include <video/fbcon-cfb16.h>
+#ifdef  EN_24_32_BPP
+#  include <video/fbcon-cfb24.h>
+#  include <video/fbcon-cfb32.h>
+#endif
+
+#include "sstfb.h"
+
+/* void Dump_regs(void); */
+
+/* sst default init registers */
+#define FBIINIT0_DEFAULT EN_VGA_PASSTHROUGH
+
+#define FBIINIT1_DEFAULT       \
+       (                       \
+         FAST_PCI_WRITES       \
+/*       SLOW_PCI_WRITES*/     \
+       | VIDEO_RESET           \
+       | 10 << TILES_IN_X_SHIFT\
+       | SEL_SOURCE_VCLK_2X_SEL\
+       | EN_LFB_READ           \
+       )
+
+#define FBIINIT2_DEFAULT       \
+       (                       \
+        SWAP_DACVSYNC          \
+       | EN_DRAM_OE            \
+       | DRAM_REFRESH_16       \
+       | EN_DRAM_REFRESH       \
+       | EN_FAST_RAS_READ      \
+       | EN_RD_AHEAD_FIFO      \
+       | EN_FAST_RD_AHEAD_WR   \
+       )
+
+#define FBIINIT3_DEFAULT       \
+       ( DISABLE_TEXTURE )
+
+#define FBIINIT4_DEFAULT       \
+       (                       \
+         FAST_PCI_READS        \
+/*       SLOW_PCI_READS*/      \
+       | LFB_READ_AHEAD        \
+       )
+/* Careful with this one : writing back the data just read will trash the DAC
+   reading some fields give logic value on pins, but setting this field will
+   set the source signal driving the pin. conclusion : just use the default
+   as a base before writing back .
+*/
+#define FBIINIT6_DEFAULT       (0x0)
+
+/********/
+
+int currcon; /* =0 */
+int num_sst; /* =0*/           /* number of initialized boards */
+
+/* initialized by setup */
+static int inverse; /* =0 */   /* invert colormap */
+static int vgapass; /* =0 */   /* enable Vga passthrough cable */
+static int mem;     /* =0 */   /* mem size in Mb , 0 = autodetect */
+static int clipping = 1;       /* use clipping (slower, safer) */
+static int gfxclk;  /* =0 */   /* force FBI freq in Mhz . Dangerous */
+static int slowpci; /* =0 */   /* slow PCI settings */
+static int dev = -1;           /* specify device (0..n) */
+static char * mode_option ;
+
+
+#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB24) || defined(FBCON_HAS_CFB32)
+union {
+#  ifdef FBCON_HAS_CFB16
+       u16 cfb16[16];
+#  endif
+#ifdef EN_24_32_BPP
+#  if defined (FBCON_HAS_CFB24) || defined(FBCON_HAS_CFB32)
+       u32 cfb32[16];
+#  endif
+#endif
+       } fbcon_cmap;
+#endif
+static struct { u_int red, green, blue, transp; } palette[16];
+static struct sstfb_info fb_info;
+static struct display disp;
+
+/********/
+
+/* Interface to ze oueurld  */
+int sstfb_init(void);
+int sstfb_setup(char *options);
+
+
+/* Framebuffer API */
+static int sstfb_open(struct fb_info *info, int user);
+static int sstfb_release(struct fb_info *info, int user);
+static int sstfb_get_fix(struct fb_fix_screeninfo *fix,
+                         int con, struct fb_info *info);
+static int sstfb_get_var(struct fb_var_screeninfo *var,
+                         int con, struct fb_info *info);
+static int sstfb_set_var(struct fb_var_screeninfo *var,
+                         int con, struct fb_info *info);
+static int sstfb_get_cmap(struct fb_cmap *cmap, int kspc,
+                          int con, struct fb_info *info);
+static int sstfb_set_cmap(struct fb_cmap *cmap, int kspc,
+                          int con, struct fb_info *info);
+static int sstfb_pan_display(struct fb_var_screeninfo *var,
+                             int con, struct fb_info *info);
+static int sstfb_ioctl(struct inode *inode, struct file *file,
+                       u_int cmd, u_long arg, int con,
+                       struct fb_info *info);
+
+/* Interface to the low level console driver */
+static int sstfbcon_switch(int con, struct fb_info *info);
+static int sstfbcon_updatevar(int con, struct fb_info *info);
+static void sstfbcon_blank(int blank, struct fb_info *info);
+
+/* Internal routines */
+static void sstfb_install_cmap(int con, struct fb_info *info);
+static int sstfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+                           u_int *transp, struct fb_info *info);
+static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                           u_int transp, struct fb_info *info);
+
+static int sstfb_set_par(const struct sstfb_par *par,
+                          struct sstfb_info *sst_info);
+static int sstfb_decode_var (const struct fb_var_screeninfo *var,
+                             struct sstfb_par *par,
+                             const struct sstfb_info *sst_info);
+static int sstfb_encode_var (struct fb_var_screeninfo *var,
+                             const struct sstfb_par *par,
+                             const struct sstfb_info *sst_info);
+
+static void sstfb_test16(struct sstfb_info *sst_info);
+
+#ifdef EN_24_32_BPP
+static void sstfb_test32(struct sstfb_info *sst_info);
+#endif
+
+/* Low level routines */
+static int sst_get_memsize(u_long *memsize);
+static int sst_wait_idle(void);
+static int sst_detect_dactype(void);
+static int sst_detect_att(void);
+static int sst_detect_ti(void);
+static int sst_detect_ics(void);
+static int sst_calc_pll(const int freq, int *freq_out, struct pll_timing *t);
+static int sst_set_pll_att_ti(const struct pll_timing *t, const int clock);
+static int sst_set_pll_ics(const struct pll_timing *t, const int clock);
+static void sst_set_vidmod_att_ti(const int bpp);
+static void sst_set_vidmod_ics(const int bpp);
+static int sst_init(void);
+#ifdef MODULE
+static void sst_shutdown(void);
+#endif
+
+static struct fb_ops sstfb_ops = {
+       owner : THIS_MODULE,
+       fb_open:        sstfb_open,
+       fb_release:     sstfb_release,
+       fb_get_fix:     sstfb_get_fix,
+       fb_get_var:     sstfb_get_var,
+       fb_set_var:     sstfb_set_var,
+       fb_get_cmap:    sstfb_get_cmap,
+       fb_set_cmap:    sstfb_set_cmap,
+       fb_pan_display: sstfb_pan_display,
+       fb_ioctl:       sstfb_ioctl,
+};
+
+#ifndef DEFAULT_MODE
+#  define DEFAULT_MODE 0
+#endif
+static struct fb_var_screeninfo        sstfb_default =
+#if ( DEFAULT_MODE == 0 )
+    { /* 800x600@60, 16 bpp .borowed from glide/sst1/include/sst1init.h */
+    800, 600, 800, 600, 0, 0, 16, 0,
+    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+    0, 0, -1, -1, 0,
+    25000, 86, 41, 23, 1, 127, 4,
+    0, FB_VMODE_NONINTERLACED };
+#endif
+#if ( DEFAULT_MODE == 1 )
+    {/* 640x480@75, 16 bpp .borowed from glide/sst1/include/sst1init.h */
+    640, 480, 640, 480, 0, 0, 16, 0,
+    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+    0, 0, -1, -1, 0,
+    31746, 118, 17, 16, 1, 63, 3,
+    0, FB_VMODE_NONINTERLACED };
+#endif
+#if ( DEFAULT_MODE == 2 )
+    { /* 1024x768@76 took from my /etc/fb.modes */
+    1024, 768, 1024, 768,0, 0, 16,0,
+    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+    0, 0, -1, -1, 0,
+    11764, 208, 8, 36, 16, 120, 3 ,
+    0, FB_VMODE_NONINTERLACED };
+#endif
+#if ( DEFAULT_MODE == 3 )
+    { /* 640x480@60 , 16bpp glide default ?*/
+    640, 480, 640, 480, 0, 0, 16, 0,
+    {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+    0, 0, -1, -1, 0,
+    39721 ,  38, 26 ,  25 ,18  , 96 ,2,
+    0, FB_VMODE_NONINTERLACED };
+#endif
+
+static struct dac_switch dacs[] = {
+       {       name:           "TI TVP3409",
+               detect:         sst_detect_ti,
+               set_pll:        sst_set_pll_att_ti,
+               set_vidmod:     sst_set_vidmod_att_ti },
+
+       {       name:           "AT&T ATT20C409",
+               detect:         sst_detect_att,
+               set_pll:        sst_set_pll_att_ti,
+               set_vidmod:     sst_set_vidmod_att_ti },
+       {       name:           "ICS ICS5342",
+               detect:         sst_detect_ics,
+               set_pll:        sst_set_pll_ics,
+               set_vidmod:     sst_set_vidmod_ics },
+};
+
+static struct sst_spec voodoo1_spec = {
+       name : "Voodoo Graphics",
+       default_gfx_clock : 50000,
+       max_gfxclk : 60,
+};
+
+static struct sst_spec voodoo2_spec = {
+       name : "Voodoo2",
+       default_gfx_clock : 75000,
+       max_gfxclk : 85,
+};
+
+/*
+ *
+ *  Definitions
+ *
+ */
+
+#if (SST_DEBUG_VAR > 0)
+/* debug info / dump a fb_var_screeninfo */
+static void sst_dbg_print_var(struct fb_var_screeninfo *var) {
+       dprintk(" {%d, %d, %d, %d, %d, %d, %d, %d,\n",
+               var->xres, var->yres, var->xres_virtual, var->yres_virtual,
+               var->xoffset, var->yoffset,
+               var->bits_per_pixel, var->grayscale);
+       dprintk(" {%d, %d, %d}, {%d, %d, %d}, {%d, %d, %d}, {%d, %d, %d},\n",
+               var->red.offset, var->red.length, var->red.msb_right,
+               var->green.offset, var->green.length, var->green.msb_right,
+               var->blue.offset, var->blue.length, var->blue.msb_right,
+               var->transp.offset, var->transp.length,
+               var->transp.msb_right);
+       dprintk(" %d, %d, %d, %d, %d,\n",
+               var->nonstd, var->activate,
+               var->height, var->width, var->accel_flags);
+       dprintk(" %d, %d, %d, %d, %d, %d, %d,\n",
+               var->pixclock, var->left_margin, var->right_margin,
+               var->upper_margin, var->lower_margin,
+               var->hsync_len, var->vsync_len);
+       dprintk(" %#x, %#x}\n",var->sync, var->vmode);
+}
+#endif /* (SST_DEBUG_VAR > 0) */
+
+static void sst_dbg_print_read_reg (u32 reg, u32 val) {
+#if (SST_DEBUG_REG > 0) /* i need the init registers :) */
+       char * regname =NULL;
+       switch (reg) {
+       case FBIINIT0: regname="FbiInit0"; break;
+       case FBIINIT1: regname="FbiInit1"; break;
+       case FBIINIT2: regname="FbiInit2"; break;
+       case FBIINIT3: regname="FbiInit3"; break;
+       case FBIINIT4: regname="FbiInit4"; break;
+       case FBIINIT6: regname="FbiInit6"; break;
+       }
+       if (regname == NULL)
+               r_ddprintk("sst_read(%#x): %#x\n", reg, val);
+       else
+               r_dprintk(" sst_read(%s): %#x\n", regname, val);
+#endif /*  (SST_DEBUG_REG > 0) */
+}
+
+static void sst_dbg_print_write_reg (u32 reg, u32 val) {
+#if (SST_DEBUG_REG > 0) /* i need the init registers :) */
+       char * regname = NULL;
+
+       switch (reg) {
+       case FBIINIT0: regname="FbiInit0"; break;
+       case FBIINIT1: regname="FbiInit1"; break;
+       case FBIINIT2: regname="FbiInit2"; break;
+       case FBIINIT3: regname="FbiInit3"; break;
+       case FBIINIT4: regname="FbiInit4"; break;
+       case FBIINIT6: regname="FbiInit6"; break;
+       }
+       if (regname == NULL)
+               r_ddprintk("sst_write(%#x, %#x)\n", reg, val);
+       else
+               r_dprintk(" sst_write(%s, %#x)\n", regname, val);
+#endif /*  (SST_DEBUG_REG > 0) */
+}
+
+/* register access */
+static inline u32 sst_read(u32 reg)
+{
+       u32 ret;
+
+       ret = readl(fb_info.mmio.vbase + reg);
+       sst_dbg_print_read_reg(reg, ret);
+       return ret;
+}
+
+static inline void sst_write(u32 reg, u32 val)
+{
+       sst_dbg_print_write_reg(reg, val);
+       writel(val, fb_info.mmio.vbase + reg);
+}
+
+static inline void sst_set_bits(u32 reg, u32 val)
+{
+       r_dprintk("sst_set_bits(%#x, %#x)\n", reg, val);
+       sst_write(reg, sst_read(reg) | val);
+}
+
+static inline void sst_unset_bits(u32 reg, u32 val)
+{
+       r_dprintk("sst_unset_bits(%#x, %#x)\n", reg, val);
+       sst_write(reg, sst_read(reg) & ~val);
+}
+
+/* dac access */
+/* dac_read should be remaped to FbiInit2 (via the pci reg init_enable) */
+static u8 sst_dac_read(u8 reg)
+{
+       u8 ret;
+
+#ifdef SST_DEBUG
+       if ((reg & 0x07) != reg) {
+               dprintk("bug line %d: register adress '%d' is to high\n",
+                        __LINE__,reg);
+       }
+#endif
+       reg &= 0x07;
+       sst_write(DAC_DATA, ((u32)reg << 8) | DAC_READ_CMD );
+       sst_wait_idle();
+       /*udelay(10);*/
+       ret=(sst_read(DAC_READ) & 0xff);
+       r_dprintk("sst_dac_read(%#x): %#x\n", reg, ret);
+       return (u8)ret;
+}
+
+static void sst_dac_write(u8 reg, u8 val)
+{
+       r_dprintk("sst_dac_write(%#x, %#x)\n", reg, val);
+#ifdef SST_DEBUG
+       if ((reg & 0x07) != reg)
+               dprintk("bug line %d: register adress '%d' is to high\n",
+                        __LINE__,reg);
+#endif
+       reg &= 0x07;
+       sst_write(DAC_DATA,(((u32)reg << 8)) | (u32)val);
+}
+
+/* indexed access to ti/att dacs */
+static inline u32 dac_i_read(u8 reg)
+{
+       u32 ret;
+
+       sst_dac_write(DACREG_ADDR_I, reg);
+       ret = sst_dac_read(DACREG_DATA_I);
+       r_dprintk("sst_dac_read_i(%#x): %#x\n", reg, ret);
+       return ret;
+}
+
+static inline void dac_i_write(u8 reg,u8 val)
+{
+       r_dprintk("sst_dac_write_i(%#x, %#x)\n", reg, val);
+       sst_dac_write(DACREG_ADDR_I, reg);
+       sst_dac_write(DACREG_DATA_I, val);
+}
+
+/*
+ *
+ *  Internal routines
+ *
+ */
+
+static void sstfb_install_cmap(int con, struct fb_info *info)
+{
+       f_dprintk("sstfb_install_cmap(con: %d)\n",con);
+       f_ddprintk("currcon: %d\n", currcon);
+       if (con != currcon)
+               return;
+       if (fb_display[con].cmap.len)
+               fb_set_cmap(&fb_display[con].cmap, 1, sstfb_setcolreg, info);
+       else
+               fb_set_cmap(
+                       fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+                       1, sstfb_setcolreg, info);
+}
+
+static int sstfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+                           u_int *transp, struct fb_info *info)
+{
+       f_ddprintk("sstfb_getcolreg\n");
+       if (regno >= 16) return 1;
+
+       *red    = palette[regno].red;
+       *green  = palette[regno].green;
+       *blue   = palette[regno].blue;
+       *transp = palette[regno].transp;
+       f_dddprintk("%-2d rvba: %#x, %#x, %#x, %#x\n",
+                   regno,*red, *green, *blue, *transp);
+       return 0;
+}
+
+static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                           u_int transp, struct fb_info *info)
+{
+       u32 col;
+
+       f_ddprintk("sstfb_setcolreg\n");
+       f_dddprintk("%-2d rvba: %#x, %#x, %#x, %#x\n",
+                   regno, red, green, blue, transp);
+       if (regno >= 16) return 1;
+       palette[regno].red   = red;
+       palette[regno].green = green;
+       palette[regno].blue  = blue;
+
+       red    >>= (16 - disp.var.red.length);
+       green  >>= (16 - disp.var.green.length);
+       blue   >>= (16 - disp.var.blue.length);
+       transp >>= (16 - disp.var.transp.length);
+       col = (red << disp.var.red.offset)
+               | (green << disp.var.green.offset)
+               | (blue  << disp.var.blue.offset)
+               | (transp << disp.var.transp.offset);
+
+       switch(disp.var.bits_per_pixel) {
+#ifdef FBCON_HAS_CFB16
+       case 16:
+               fbcon_cmap.cfb16[regno]=(u16)col;
+               break;
+#endif
+#ifdef EN_24_32_BPP
+#ifdef FBCON_HAS_CFB24
+       case 24:
+               fbcon_cmap.cfb32[regno]=col;
+               break;
+#endif
+#ifdef FBCON_HAS_CFB32
+       case 32:
+               fbcon_cmap.cfb32[regno]=col;
+               break;
+#endif
+#endif
+       default:
+               eprintk("bug line %d: bad depth '%u'\n",__LINE__,
+                       disp.var.bits_per_pixel);
+               break;
+       }
+       f_dddprintk("bpp: %d . encoded color: %#x\n",
+                   disp.var.bits_per_pixel, col);
+       return 0;
+}
+
+/* set par according to var ( checks var ) */
+static int sstfb_decode_var (const struct fb_var_screeninfo *var,
+                             struct sstfb_par *par,
+                             const struct sstfb_info *sst_info)
+{
+       int real_length;
+
+       f_dprintk("sstfb_decode_var\n");
+       /* Check var validity */
+       if ((var->xres > 1024) || (!var->xres) || (!var->xres)) {
+               eprintk ("Unsupported resolution %dx%d\n",
+                        var->xres, var->yres);
+               return -EINVAL;
+       }
+       if ((var->vmode & FB_VMODE_MASK) !=  FB_VMODE_NONINTERLACED) {
+               eprintk("Interlace non supported %#x\n",
+                       (var->vmode & FB_VMODE_MASK));
+               return -EINVAL;
+       }
+
+
+       memset(par, 0, sizeof(par));
+       par->xDim       = var->xres;
+       par->hSyncOn    = var->hsync_len;
+       par->hSyncOff   = var->xres + var->right_margin + var->left_margin;
+       par->hBackPorch = var->left_margin;
+       par->yDim       = var->yres;
+       par->vSyncOn    = var->vsync_len;
+       par->vSyncOff   = var->yres + var->lower_margin + var->upper_margin;
+       par->vBackPorch = var->upper_margin;
+
+       switch (var->bits_per_pixel) {
+       case 0 ... 16 :
+               par->bpp = 16;
+               break;
+#ifdef EN_24_32_BPP
+       case 17 ... 24 :
+               par->bpp = 24;
+               break;
+       case 25 ... 32 :
+               par->bpp = 32;
+               break;
+#endif
+       default :
+               eprintk ("Unsupported bpp %d\n", par->bpp);
+               return -EINVAL;
+               break;
+       }
+
+       if (sst_info->is_voodoo2) {
+               /* voodoo2 has 32 pixel wide tiles , BUT stange things
+                happen with odd number of tiles */
+               par->tiles_in_X= (par->xDim + 63 ) / 64 * 2;
+       } else {
+               /* voodoo1 has 64 pixels wide tiles. */
+               par->tiles_in_X= (par->xDim + 63 ) / 64;
+       }
+
+       /*
+        *  mem check
+        */
+       /* it seems that the fbi uses tiles of 64x16 pixels to "map" the mem*/
+       /* FIXME: i don't like this... looks wrong*/
+       real_length = par->tiles_in_X  * (sst_info->is_voodoo2 ? 32 : 64 )
+                     * ((par->bpp == 16) ? 2 : 4);
+/*shoud this function change var ? for instance with yvirt > yres  ?*/
+
+       if ((real_length * var->yres) > fb_info.video.len) {
+               eprintk ("Not enough video memory\n");
+               return -ENOMEM;
+       }
+
+       par->freq = PS2KHZ(var->pixclock);
+       
+       /* TODO add checks for timings */
+       return 0;
+}
+
+/* sets var according to par (basicaly, sets sane values) */
+static int sstfb_encode_var (struct fb_var_screeninfo *var,
+                             const struct sstfb_par *par,
+                             const struct sstfb_info *sst_info)
+{
+       memset(var,0,sizeof(struct fb_var_screeninfo));
+
+       var->xres           = par->xDim;
+       var->yres           = par->yDim;
+       var->xres_virtual   = par->xDim;
+       var->yres_virtual   = par->yDim;
+       var->bits_per_pixel = par->bpp;
+       /* {x|y}offset = 0 ; sync=0 */
+       var->height         = -1;
+       var->width          = -1;
+       var->pixclock       = KHZ2PS(par->freq);
+       var->left_margin    = par->hBackPorch;
+       var->right_margin   = par->hSyncOff - par->xDim - par->hBackPorch;
+       var->upper_margin   = par->vBackPorch;
+       var->lower_margin   = par->vSyncOff - par->yDim - par->vBackPorch;
+       var->hsync_len      = par->hSyncOn;
+       var->vsync_len      = par->vSyncOn;
+       var->vmode          = FB_VMODE_NONINTERLACED;
+
+       /*
+        * correct the color bit fields
+        */
+       /* var->{red|green|blue}.msb_right    = 0; */
+
+       switch (par->bpp) {
+       case 16:        /* RGB 565  LfbMode 0 */
+               var->red.length    = 5;
+               var->green.length  = 6;
+               var->blue.length   = 5;
+               var->transp.length = 0;
+
+               var->red.offset    = 11;
+               var->green.offset  = 5;
+               var->blue.offset   = 0;
+               var->transp.offset = 0;
+               break;
+#ifdef EN_24_32_BPP
+       case 24:        /* RGB 888 LfbMode 4 */
+       case 32:        /* ARGB 8888 LfbMode 5 */
+               var->red.length    = 8;
+               var->green.length  = 8;
+               var->blue.length   = 8;
+               var->transp.length = 0;
+
+               var->red.offset    = 16;
+               var->green.offset  = 8;
+               var->blue.offset   = 0;
+               var->transp.offset = 0; /* in 24bpp we fake a 32 bpp mode */
+               break;
+#endif
+       default:
+               eprintk ("bug line %d: bad depth '%u'\n", __LINE__, par->bpp);
+               break;
+       }
+       return 0;
+}
+
+/*
+ * Frame buffer API
+ */
+
+static int sstfb_open(struct fb_info *info, int user)
+{
+       f_dprintk("sstfb_open(user: %d)\n",user);
+       MOD_INC_USE_COUNT;
+       return 0;
+}
+
+static int sstfb_release(struct fb_info *info, int user)
+{
+       f_dprintk("sstfb_release(user: %d)\n",user);
+       MOD_DEC_USE_COUNT;
+       return 0;
+}
+
+static int sstfb_get_fix(struct fb_fix_screeninfo *fix,
+                         int con, struct fb_info *info)
+{
+#define sst_info       ((struct sstfb_info *) info)
+
+       struct fb_var_screeninfo *var;
+
+       f_dprintk("sstfb_get_fix(con: %d)\n",con);
+       if (con == -1)
+               var = &sstfb_default;
+       else
+               var = &fb_display[con].var;
+
+       strcpy(fix->id, sst_info->info.modename);
+       /* lfb phys address = membase + 4Mb */
+       fix->smem_start  = sst_info->video.base;
+       fix->smem_len    = sst_info->video.len;
+
+       fix->type        = FB_TYPE_PACKED_PIXELS;
+       fix->visual      = FB_VISUAL_TRUECOLOR;
+       /*
+        *   According to the specs, the linelength must be of 1024 *pixels*.
+        * and the 24bpp mode is in fact a 32 bpp mode.
+        */
+       fix->line_length = (var->bits_per_pixel == 16) ? 2048 : 4096 ;
+       return 0;
+#undef sst_info
+}
+
+static int sstfb_get_var(struct fb_var_screeninfo *var,
+                         int con, struct fb_info *info)
+{
+       f_dprintk("sstfb_get_var(con: %d)\n",con);
+       if (con == -1)
+               *var = sstfb_default;
+       else
+               *var = fb_display[con].var;
+       print_var(var, "var");
+       return 0;
+ }
+
+static int sstfb_set_var(struct fb_var_screeninfo *var,
+                         int con, struct fb_info *info)
+{
+#define sst_info       ((struct sstfb_info *) info)    
+
+       struct sstfb_par par;   
+       struct display *display;
+       int err;
+       int old_bpp,old_xres,old_yres;
+
+       f_dprintk("sstfb_set_var(con: %d)\n",con);
+       f_ddprintk("xres yres vxres vyres bpp activate\n");
+       f_ddprintk("%-4d %-4d %-5d %-5d %-3d %#-8x\n",
+                var->xres,var->yres,var->xres_virtual,var->yres_virtual,
+                var->bits_per_pixel,var->activate);
+       if (con < 0)
+               display = &disp;
+       else
+               display = &fb_display[con];
+
+       err = sstfb_decode_var(var, &par, sst_info);
+       if (err)
+               return err;
+       sstfb_encode_var (var, &par, sst_info);
+       
+       switch (var->activate & FB_ACTIVATE_MASK) {
+               case FB_ACTIVATE_TEST:
+                       return 0;
+               case FB_ACTIVATE_NXTOPEN:
+               case FB_ACTIVATE_NOW:
+                       break;
+               default:
+                       return -EINVAL;
+       }
+       old_xres = display->var.xres;
+       old_yres = display->var.yres;
+       old_bpp  = display->var.bits_per_pixel;
+       display->var = *var;
+
+       if ((old_xres != var->xres) || (old_yres != var->yres)
+           || (old_bpp != var->bits_per_pixel)) {
+               /* 2-3  lignes redondantes avec get_fix */
+               display->screen_base = (char *) sst_info->video.vbase;
+               display->visual = FB_VISUAL_TRUECOLOR;
+               display->type = FB_TYPE_PACKED_PIXELS;
+               display->type_aux = 0;
+               display->ypanstep = 0;
+               display->ywrapstep = 0;
+               display->line_length = (var->bits_per_pixel==16) ? 2048 : 4096;
+               display->inverse = 0;
+               switch (var->bits_per_pixel) {
+#ifdef FBCON_HAS_CFB16
+               case 16:
+                       display->dispsw = &fbcon_cfb16;
+                       display->dispsw_data = fbcon_cmap.cfb16;
+                       break;
+#endif
+#ifdef EN_24_32_BPP
+#if defined (FBCON_HAS_CFB24) || defined (FBCON_HAS_CFB32 )
+               case 24: /*24bpp non packed <=> 32 bpp */
+               case 32:
+                       display->dispsw = &fbcon_cfb32;
+                       display->dispsw_data = fbcon_cmap.cfb32;
+                       break;
+#endif
+#endif
+               default:
+                       display->dispsw = &fbcon_dummy;
+                       break;
+               }
+               display->scrollmode = SCROLL_YREDRAW;
+               if (sst_info->info.changevar) {
+                       v_dprintk("fb_info.changevar(con: %d)\n", con);
+                       (*sst_info->info.changevar)(con);
+                       v_dprintk("fb_info.changevar: done \n");
+               } else {
+                       v_dprintk("fb_info.changevar() == NULL . \n");
+               }
+       }
+
+       if ((con <0) || (con==currcon)) {
+               sstfb_set_par (&par, sst_info);
+       }
+       print_var(var, "var");
+       print_var(&display->var, "&display->var");
+
+       if (old_bpp != var->bits_per_pixel) {
+           if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
+               return err;
+           sstfb_install_cmap(con, info);
+       }
+
+       return 0;
+#undef sst_info
+}
+
+
+static int sstfb_set_cmap(struct fb_cmap *cmap, int kspc,
+                          int con, struct fb_info *info)
+{
+       struct display *d = (con<0) ? info->disp : fb_display + con;
+
+       f_dprintk("sstfb_set_cmap\n");
+       f_ddprintk("con: %d, currcon: %d, d->cmap.len %d\n",
+                con, currcon, d->cmap.len);
+
+       if (d->cmap.len != 16 ) {       /* or test if cmap.len == 0 ? */
+               int err;
+               err = fb_alloc_cmap(&d->cmap, 16, 0); /* cmap size=16 */
+               if (err) return err;
+       }
+       if (con == currcon) {
+               return fb_set_cmap(cmap, kspc, sstfb_setcolreg, info);
+       } else {
+               fb_copy_cmap(cmap, &d->cmap, kspc ? 0 : 1);
+       }
+       return 0;
+}
+
+static int sstfb_get_cmap(struct fb_cmap *cmap, int kspc,
+                          int con, struct fb_info *info)
+{
+       f_dprintk("sstfb_get_cmap\n");
+       f_ddprintk("con %d, curcon %d, cmap.len %d\n",
+                con, currcon, fb_display[con].cmap.len);
+
+       /* FIXME: check if con = -1 ? cf sstfb_set_cmap...  */
+       if (con == currcon)
+               return fb_get_cmap(cmap, kspc, sstfb_getcolreg, info);
+       else if (fb_display[con].cmap.len)
+               fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+       else
+               fb_copy_cmap(
+                       fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+                       cmap, kspc ? 0 : 2);
+       return 0;
+}
+
+/* TODO */
+static int sstfb_pan_display(struct fb_var_screeninfo *var,
+                             int con, struct fb_info *info)
+{
+       f_dprintk("sstfb_pan_display\n");
+       return -EINVAL;
+}
+
+static int sstfb_ioctl(struct inode *inode, struct file *file,
+                       u_int cmd, u_long arg, int con,
+                       struct fb_info *info)
+{
+#define sst_info       ((struct sstfb_info *) info)    
+#if (SST_DEBUG_IOCTL >0)
+       int i;
+       u_long p;
+       u32 tmp;
+       u32 fbiinit0;
+       struct pci_dev * sst_dev = sst_info->dev;
+#endif
+
+       f_dprintk("sstfb_ioctl(%x)\n", cmd);
+#if (SST_DEBUG_IOCTL >0)
+       switch (cmd) {
+#  if (SST_DEBUG_VAR >0)
+/* tmp ioctl : dumps fb_display[0-5] */
+       case _IO('F', 0xdb):            /* 0x46db */
+               f_dprintk("dumping fb_display[0-5].var\n");
+               for (i = 0 ; i< 6 ; i++) {
+                       print_var(&fb_display[i].var, "var(%d)", i);
+               }
+               return 0;
+#  endif /* (SST_DEBUG_VAR >0) */
+/* fills the lfb up to *(u32*)arg */
+       case _IOW('F', 0xdc, u32):      /* 0x46dc */
+               if (*(u32*)arg > 0x400000 )
+                       *(u32*) arg = 0x400000;
+               f_dprintk("filling %#x \n", *(u32*)arg);
+               for (p = 0 ; p < *(u32*)arg; p+=2)
+                       writew( p >> 6 , sst_info->video.vbase + p);
+               return 0;
+/* change VGA pass_through */
+       case _IOW('F', 0xdd, u32):      /* 0x46dd */
+               f_dprintk("switch VGA pass-through\n");
+               pci_read_config_dword(sst_dev, PCI_INIT_ENABLE, &tmp);
+               pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
+                                      tmp | PCI_EN_INIT_WR );
+               fbiinit0 = sst_read (FBIINIT0);
+               if (* (u32*)arg) {
+                       sst_write(FBIINIT0, fbiinit0 & ~EN_VGA_PASSTHROUGH);
+                       iprintk ( "Disabling VGA pass-through\n");
+               } else {
+                       sst_write(FBIINIT0, fbiinit0 | EN_VGA_PASSTHROUGH);
+                       iprintk ( "Enabling VGA pass-through\n");
+               }
+               pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, tmp);
+               return 0;
+       case _IO('F', 0xde):            /* 0x46de */
+               f_dprintk("test color display\n");
+               f_ddprintk("currcon: %d, bpp %d\n",
+                         currcon, fb_display[currcon].var.bits_per_pixel);
+               memset_io(sst_info->video.vbase, 0, sst_info->video.len);
+       switch (fb_display[currcon].var.bits_per_pixel) {
+/* FIXME broken : if we call this ioctl from a tty not bound to the fb, we use its depth and not the current one ... */
+               case 16:
+                       sstfb_test16(sst_info);
+                       break;
+#  ifdef EN_24_32_BPP
+               case 24:
+               case 32:
+                       sstfb_test32(sst_info);
+                       break;
+#  endif
+               default:
+                       dprintk("bug line %d: bad depth '%u'\n", __LINE__,
+                               fb_display[currcon].var.bits_per_pixel);
+                       }
+               return 0;
+       }
+#endif /* (SST_DEBUG_IOCTL >0) */
+       return -EINVAL;
+#undef sst_info
+}
+
+
+/*
+ * Low level routines
+ */
+
+/* get lfb size */
+
+static int sst_get_memsize(u_long *memsize)
+{
+       u32 fbbase_virt = fb_info.video.vbase;
+       f_dprintk("sst_get_memsize\n");
+
+       /* force memsize */
+       if ((mem >= 1 ) &&  (mem <= 4)) {
+               *memsize = (mem * 0x100000);
+               iprintk("supplied memsize: %#lx\n", *memsize);
+               return 1;
+       }
+
+       writel (0xdeadbeef, fbbase_virt);
+       writel (0xdeadbeef, fbbase_virt+0x100000);
+       writel (0xdeadbeef, fbbase_virt+0x200000);
+       f_ddprintk("0Mb: %#x, 1Mb: %#x, 2Mb: %#x\n",
+                  readl(fbbase_virt), readl(fbbase_virt + 0x100000),
+                  readl(fbbase_virt + 0x200000));
+
+       writel (0xabcdef01, fbbase_virt);
+
+       f_ddprintk("0Mb: %#x, 1Mb: %#x, 2Mb: %#x\n",
+                  readl(fbbase_virt), readl(fbbase_virt + 0x100000),
+                  readl(fbbase_virt + 0x200000));
+
+       /* checks for 4mb lfb , then 2, then defaults to 1*/
+       if (readl(fbbase_virt + 0x200000) == 0xdeadbeef) {
+               *memsize = 0x400000;
+       } else if (readl(fbbase_virt + 0x100000) == 0xdeadbeef) {
+               *memsize = 0x200000;
+       } else {
+               *memsize = 0x100000;
+       }
+       f_ddprintk("detected memsize: %#lx\n", *memsize);
+       return 1;
+}
+
+
+/*
+ * wait for the fbi chip. ASK: what happens if the fbi is stuck ?
+ *
+ * the FBI is supposed to be ready if we receive 5 time
+ * in a row a "idle" answer to our requests
+ */
+
+static int sst_wait_idle(void)
+{
+       int count = 0;
+
+       f_ddprintk("sst_wait_idle\n");
+       while(1) {
+               if (sst_read(STATUS) & STATUS_FBI_BUSY) {
+                       f_dddprintk("status: busy\n");
+/* FIXME basicaly, this is a busy wait. maybe not that good. oh well; this is a small loop after all ...*/
+                       count = 0;
+               } else {
+                       count++;
+                       f_dddprintk("status: idle(%d)\n", count);
+               }
+               if (count >= 5) return 1;
+       }
+}
+
+/*
+ * detect dac type
+ * prerequisite : write to FbiInitx enabled, video and fbi and pci fifo reset,
+ * dram refresh disabled, FbiInit remaped.
+ * TODO: mmh.. maybe i shoud put the "prerequisite" in the func ...
+ */
+static int __init sst_detect_dactype(void)
+{
+       int ret=0,i;
+       f_dprintk("sst_detect_dactype\n");
+       for (i=0; i< sizeof(dacs)/sizeof(dacs[0]) ; i++) {
+               ret = dacs[i].detect();
+               if (ret) break;
+       }
+       if (!ret)
+               return 0;
+       f_dprintk("found %s\n", dacs[i].name);
+       fb_info.dac_sw=&dacs[i];
+       return 1;
+}
+
+/* fbi should be idle, and fifo emty and mem disabled */
+/* supposed to detect AT&T ATT20C409 and Ti TVP3409 ramdacs */
+
+static int __init (sst_detect_att(void))
+{
+       int i, mir, dir;
+
+       f_dprintk("sst_detect_att\n");
+       for (i = 0; i<3; i++) {
+               sst_dac_write(DACREG_WMA, 0);   /* backdoor */
+               sst_dac_read(DACREG_RMR);       /* read 4 times RMR */
+               sst_dac_read(DACREG_RMR);
+               sst_dac_read(DACREG_RMR);
+               sst_dac_read(DACREG_RMR);
+               /* the fifth time,  CR0 is read */
+               sst_dac_read(DACREG_RMR);
+               /* the 6th, manufacturer id register */
+               mir = sst_dac_read(DACREG_RMR);
+               /*the 7th, device ID register */
+               dir = sst_dac_read(DACREG_RMR);
+               f_ddprintk("mir: %#x, dir: %#x\n", mir, dir);
+               if ((mir == DACREG_MIR_ATT ) && (dir == DACREG_DIR_ATT)) {
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+static int __init (sst_detect_ti(void))
+{
+       int i, mir, dir;
+
+       f_dprintk("sst_detect_ti\n");
+       for (i = 0; i<3; i++) {
+               sst_dac_write(DACREG_WMA, 0);   /* backdoor */
+               sst_dac_read(DACREG_RMR);       /* read 4 times RMR */
+               sst_dac_read(DACREG_RMR);
+               sst_dac_read(DACREG_RMR);
+               sst_dac_read(DACREG_RMR);
+               /* the fifth time,  CR0 is read */
+               sst_dac_read(DACREG_RMR);
+               /* the 6th, manufacturer id register */
+               mir = sst_dac_read(DACREG_RMR);
+               /*the 7th, device ID register */
+               dir = sst_dac_read(DACREG_RMR);
+               f_ddprintk("mir: %#x, dir: %#x\n", mir, dir);
+               if ((mir == DACREG_MIR_TI ) && (dir == DACREG_DIR_TI)) {
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+/*
+ * try to detect ICS5342  ramdac
+ * we get the 1st byte (M value) of preset f1,f7 and fB
+ * why those 3 ? mmmh... for now, i'll do it the glide way...
+ * and ask questions later. anyway, it seems that all the freq registers are
+ * realy at their default state (cf specs) so i ask again, why those 3 regs ?
+ * mmmmh.. it seems that's much more ugly than i thought. we use f0 and fA for
+ * pll programming, so in fact, we *hope* that the f1, f7 & fB won't be
+ * touched...
+ * is it realy safe ? how can i reset this ramdac ? geee...
+ */
+static int __init sst_detect_ics(void)
+{
+       int i;
+       int m_clk0_1, m_clk0_7, m_clk1_b;
+       int n_clk0_1, n_clk0_7, n_clk1_b;
+       f_dprintk("sst_detect_ics\n");
+       for (i = 0; i<5; i++ ) {
+               sst_dac_write(DACREG_ICS_PLLRMA, 0x1);  /* f1 */
+               m_clk0_1 = sst_dac_read(DACREG_ICS_PLLDATA);
+               n_clk0_1 = sst_dac_read(DACREG_ICS_PLLDATA);
+               sst_dac_write(DACREG_ICS_PLLRMA, 0x7);  /* f7 */
+               m_clk0_7 = sst_dac_read(DACREG_ICS_PLLDATA);
+               n_clk0_7 = sst_dac_read(DACREG_ICS_PLLDATA);
+               sst_dac_write(DACREG_ICS_PLLRMA, 0xb);  /* fB */
+               m_clk1_b= sst_dac_read(DACREG_ICS_PLLDATA);
+               n_clk1_b= sst_dac_read(DACREG_ICS_PLLDATA);
+               f_ddprintk("m_clk0_1: %#x, m_clk0_7: %#x, m_clk1_b: %#x\n",
+                       m_clk0_1, m_clk0_7, m_clk1_b);
+               f_ddprintk("n_clk0_1: %#x, n_clk0_7: %#x, n_clk1_b: %#x\n",
+                       n_clk0_1, n_clk0_7, n_clk1_b);
+               if ((   m_clk0_1 == DACREG_ICS_PLL_CLK0_1_INI)
+                   && (m_clk0_7 == DACREG_ICS_PLL_CLK0_7_INI)
+                   && (m_clk1_b == DACREG_ICS_PLL_CLK1_B_INI)) {
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+/* compute the m,n,p  , returns the real freq
+ * (ics datasheet :  N <-> N1 , P <-> N2)
+ *
+ * Fout= Fref * (M+2)/( 2^P * (N+2))
+ *  we try to get close to the asked freq
+ *  with P as high, and M as low as possible
+ * range:
+ * ti/att : 0 <= M <= 255; 0 <= P <= 3; 0<= N <= 63
+ * ics    : 1 <= M <= 127; 0 <= P <= 3; 1<= N <= 31
+ * we'll use the lowest limitation, should be precise enouth
+ */
+static int sst_calc_pll(const int freq, int *freq_out, struct pll_timing *t)
+{
+       int m, m2, n, p, best_err, fout;
+       int best_n=-1;
+       int best_m=-1;
+
+       f_dprintk("sst_calc_pll(%dKhz)\n", freq);
+       best_err = freq;
+       p=3;
+       /* f * 2^P = vco should be less than VCOmax ~ 250 MHz for ics*/
+       while (((1 << p) * freq > VCO_MAX) && (p >= 0))
+               p--;
+       if (p == -1)
+               return -EINVAL;
+       for (n = 1; n < 32; n++) {
+               /* calc 2 * m so we can round it later*/
+               m2 = (2 * freq * (1 << p) * (n + 2) ) / DAC_FREF - 4 ;
+
+               m = (m2 % 2 ) ? m2/2+1 : m2/2 ;
+               if (m >= 128)
+                       break;
+               fout = (DAC_FREF * (m + 2)) / ((1 << p) * (n + 2));
+               if ((ABS(fout - freq) < best_err) && (m > 0)) {
+                       best_n = n;
+                       best_m = m;
+                       best_err = ABS(fout - freq);
+                       /* we get the lowest m , allowing 0.5% error in freq*/
+                       if (200*best_err < freq) break;
+               }
+       }
+       if (best_n == -1)  /* unlikely, but who knows ? */
+               return -EINVAL;
+       t->p=p;
+       t->n=best_n;
+       t->m=best_m;
+       *freq_out=(DAC_FREF * (t->m + 2)) / ((1 << t->p) * (t->n + 2));
+       f_ddprintk ("m: %d, n: %d, p: %d, F: %dKhz\n",
+                 t->m, t->n, t->p, *freq_out);
+       return 0;
+}
+
+/*
+ * gfx, video, pci fifo should be reset, dram refresh disabled
+ * see detect_dac
+ */
+
+static int sst_set_pll_att_ti(const struct pll_timing *t, const int clock)
+{
+       u8 cr0, cc;
+       f_dprintk("sst_set_pll_att_ti\n");
+
+       /* enable indexed mode */
+
+       sst_dac_write(DACREG_WMA, 0);   /* backdoor */
+       sst_dac_read(DACREG_RMR);       /* 1 time:  RMR */
+       sst_dac_read(DACREG_RMR);       /* 2 RMR */
+       sst_dac_read(DACREG_RMR);       /* 3 //  */
+       sst_dac_read(DACREG_RMR);       /* 4 //  */
+       cr0 = sst_dac_read(DACREG_RMR); /* 5 CR0 */
+
+       sst_dac_write(DACREG_WMA, 0);
+       sst_dac_read(DACREG_RMR);
+       sst_dac_read(DACREG_RMR);
+       sst_dac_read(DACREG_RMR);
+       sst_dac_read(DACREG_RMR);
+       sst_dac_write(DACREG_RMR, (cr0 & 0xf0)
+                     | DACREG_CR0_EN_INDEXED
+                     | DACREG_CR0_8BIT
+                     | DACREG_CR0_PWDOWN );
+       /* so, now we are in indexed mode . dunno if its common, but
+          i find this way of doing things a little bit weird :p */
+
+       udelay(300);
+       cc = dac_i_read(DACREG_CC_I);
+       switch (clock) {
+       case VID_CLOCK:
+               dac_i_write(DACREG_AC0_I, t->m);
+               dac_i_write(DACREG_AC1_I, t->p << 6 | t->n);
+               dac_i_write(DACREG_CC_I,
+                           (cc & 0x0f) | DACREG_CC_CLKA | DACREG_CC_CLKA_C);
+               break;
+       case GFX_CLOCK:
+               dac_i_write(DACREG_BD0_I, t->m);
+               dac_i_write(DACREG_BD1_I, t->p << 6 | t->n);
+               dac_i_write(DACREG_CC_I,
+                           (cc & 0xf0) | DACREG_CC_CLKB | DACREG_CC_CLKB_D);
+               break;
+       default:
+               dprintk("bug line %d: wrong clock code '%d'\n",
+                       __LINE__,clock);
+               return 0;
+               }
+       udelay(300);
+
+       /* power up the dac & return to "normal" non-indexed mode */
+       dac_i_write(DACREG_CR0_I,
+                   cr0 & ~DACREG_CR0_PWDOWN & ~DACREG_CR0_EN_INDEXED);
+       return 1;
+}
+
+static int sst_set_pll_ics(const struct pll_timing *t, const int clock)
+{
+       u8 pll_ctrl;
+
+       f_dprintk("sst_set_pll_ics\n");
+
+       sst_dac_write(DACREG_ICS_PLLRMA, DACREG_ICS_PLL_CTRL);
+       pll_ctrl = sst_dac_read(DACREG_ICS_PLLDATA);
+       switch(clock) {
+       case VID_CLOCK:
+               sst_dac_write(DACREG_ICS_PLLWMA, 0x0);  /* CLK0, f0 */
+               sst_dac_write(DACREG_ICS_PLLDATA, t->m);
+               sst_dac_write(DACREG_ICS_PLLDATA, t->p << 5 | t->n);
+               /* selects freq f0 for clock 0 */
+               sst_dac_write(DACREG_ICS_PLLWMA, DACREG_ICS_PLL_CTRL);
+               sst_dac_write(DACREG_ICS_PLLDATA,
+                             (pll_ctrl & 0xd8)
+                             | DACREG_ICS_CLK0
+                             | DACREG_ICS_CLK0_0);
+               break;
+       case GFX_CLOCK :
+               sst_dac_write(DACREG_ICS_PLLWMA, 0xa);  /* CLK1, fA */
+               sst_dac_write(DACREG_ICS_PLLDATA, t->m);
+               sst_dac_write(DACREG_ICS_PLLDATA, t->p << 5 | t->n);
+               /* selects freq fA for clock 1 */
+               sst_dac_write(DACREG_ICS_PLLWMA, DACREG_ICS_PLL_CTRL);
+               sst_dac_write(DACREG_ICS_PLLDATA,
+                             (pll_ctrl & 0xef) | DACREG_ICS_CLK1_A);
+               break;
+       default:
+               dprintk("bug line %d: wrong clock code '%d'\n",
+                       __LINE__, clock);
+               return 0;
+               }
+       udelay(300);
+       return 1;
+}
+
+static int sstfb_set_par(const struct sstfb_par * par, struct sstfb_info * sst_info)
+{
+       u32 lfbmode, fbiinit1, fbiinit2, fbiinit3, fbiinit6=0;
+       int ntiles;
+       struct pll_timing pll;
+       int fout;
+       struct pci_dev  * sst_dev = sst_info->dev;
+
+       f_dprintk("sst_set_par(%dx%d)\n", par->xDim, par->yDim);
+       f_ddprintk("hSyncOn hSyncOff vSyncOn vSyncOff\n");
+       f_ddprintk("%-7d %-8d %-7d %-8d\n",
+                  par->hSyncOn, par->hSyncOff,
+                  par->vSyncOn, par->vSyncOff);
+       f_ddprintk("hBackPorch vBackPorch xDim yDim Freq\n");
+       f_ddprintk("%-10d %-10d %-4d %-4d %-8d\n",
+                  par->hBackPorch, par->vBackPorch,
+                  par->xDim, par->yDim, par->freq);
+
+
+       sst_calc_pll (par->freq, &fout, &pll);
+
+       sst_write(NOPCMD, 0);
+       sst_wait_idle();
+       pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_INIT_WR);
+       sst_set_bits(FBIINIT1, VIDEO_RESET);
+       sst_set_bits(FBIINIT0, FBI_RESET | FIFO_RESET);
+       sst_unset_bits(FBIINIT2, EN_DRAM_REFRESH);
+       sst_wait_idle();
+
+       /*sst_unset_bits (FBIINIT0, FBI_RESET); / reenable FBI ? */
+
+       sst_write(BACKPORCH,       par->vBackPorch << 16 | (par->hBackPorch-2));
+       sst_write(VIDEODIMENSIONS, (par->yDim - 1) << 16 | (par->xDim - 1));
+       sst_write(HSYNC,         (par->hSyncOff-1) << 16 | (par->hSyncOn-1));
+       sst_write(VSYNC,             par->vSyncOff << 16 | par->vSyncOn);
+
+       fbiinit2=sst_read(FBIINIT2);
+       fbiinit3=sst_read(FBIINIT3);
+
+       /* everything is reset. we enable fbiinit2/3 remap : dac acces ok */
+       pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
+                              PCI_EN_INIT_WR | PCI_REMAP_DAC );
+
+       sst_info->dac_sw->set_vidmod(par->bpp);
+       /* set video clock */
+       sst_info->dac_sw->set_pll(&pll, VID_CLOCK);
+       /* disable fbiinit2/3 remap */
+       pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
+                              PCI_EN_INIT_WR);
+       /* restore fbiinit2/3 */
+       sst_write(FBIINIT2,fbiinit2);
+       sst_write(FBIINIT3,fbiinit3);
+
+       fbiinit1 = (sst_read(FBIINIT1) & VIDEO_MASK)
+                   | EN_DATA_OE
+                   | EN_BLANK_OE
+                   | EN_HVSYNC_OE
+                   | EN_DCLK_OE
+/*                 | (15 << TILES_IN_X_SHIFT)*/
+                   | SEL_INPUT_VCLK_2X
+/*                 | (2 << VCLK_2X_SEL_DEL_SHIFT)
+                   | (2 << VCLK_DEL_SHIFT)*/;
+/* try with vclk_in_delay =0 (bits 29:30) , vclk_out_delay =0 (bits(27:28)
+ in (near) future set them accordingly to revision + resolution (cf glide)
+ first understand what it stands for :)
+ FIXME: there are some artefacts... check for the vclk_in_delay
+ lets try with 6ns delay in both vclk_out & in...
+ doh... they're still there :\
+*/
+
+       ntiles = par->tiles_in_X;
+       if (sst_info->is_voodoo2) {
+               fbiinit1 |= ((ntiles & 0x20) >> 5) << TILES_IN_X_MSB_SHIFT
+                           | ((ntiles & 0x1e) >> 1) << TILES_IN_X_SHIFT ;
+/* as the only value of importance for us in fbiinit6 is tiles in X (lsb),
+   and as reading fbinit 6 will return crap (see FBIINIT6_DEFAULT) we just
+   write our value. BTW due to the dac unable to read odd number of tiles, this
+   field is always null ... */
+               fbiinit6 = (ntiles & 0x1) << TILES_IN_X_LSB_SHIFT;
+       }
+       else
+               fbiinit1 |= ntiles << TILES_IN_X_SHIFT;
+
+       switch(par->bpp) {
+       case 16:
+               fbiinit1 |=  SEL_SOURCE_VCLK_2X_SEL;
+               break;
+#ifdef EN_24_32_BPP
+       case 24:
+       case 32:
+/*     orig    sst_set_bits(FBIINIT1, SEL_SOURCE_VCLK_2X_DIV2 | EN_24BPP); */
+               fbiinit1 |= SEL_SOURCE_VCLK_2X_SEL | EN_24BPP;
+               break;
+#endif
+       default:
+               dprintk("bug line %d: bad depth '%u'\n", __LINE__,
+                       par->bpp );
+               return 0;
+               break;
+       }
+       sst_write(FBIINIT1, fbiinit1);
+       if (sst_info->is_voodoo2)
+               sst_write(FBIINIT6, fbiinit6);
+       sst_wait_idle();
+       sst_unset_bits(FBIINIT1, VIDEO_RESET);
+       sst_unset_bits(FBIINIT0, FBI_RESET | FIFO_RESET);
+       sst_set_bits(FBIINIT2, EN_DRAM_REFRESH);
+/* disables fbiinit writes */
+       pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_FIFO_WR);
+
+       /* set lfbmode : set mode + front buffer for reads/writes
+          + disable pipeline + disable byte swapping */
+       switch(par->bpp) {
+       case 16:
+               lfbmode = LFB_565;
+               break;
+#ifdef EN_24_32_BPP
+       case 24:
+               lfbmode = LFB_888;
+               break;
+       case 32:
+               lfbmode = LFB_8888;
+               break;
+#endif
+       default:
+               dprintk("bug line %d: bad depth '%u'\n", __LINE__,
+                       par->bpp );
+               return 0;
+               break;
+       }
+
+       if (clipping) {
+               sst_write(LFBMODE, lfbmode | EN_PXL_PIPELINE);
+       /*
+        * Set "clipping" dimensions. If clipping is disabled and
+        * writes to offscreen areas of the framebuffer are performed,
+        * the "behaviour is undefined" (_very_ undefined) - Urs
+        */
+       /* btw, it requires enabling pixel pipeline in LFBMODE .
+          off screen read/writes will just wrap and read/print pixels
+          on screen. Ugly but not that dangerous */
+
+               f_ddprintk("setting clipping dimensions 0..%d, 0..%d\n",
+                           par->xDim-1, par->yDim-1);
+
+/* warning the fields are 9bits wide on voodoo1 , 11 (or 10) on voodoo2,
+   make sure we check the values before playing with the registers.. */
+
+               sst_write(CLIP_LEFT_RIGHT, par->xDim );
+               sst_write(CLIP_LOWY_HIGHY, par->yDim );
+               sst_set_bits(FBZMODE, EN_CLIPPING | EN_RGB_WRITE);
+       } else {
+               /* no clipping : direct access, no pipeline */
+               sst_write(LFBMODE, lfbmode );
+       }
+
+       sst_info->current_par = *par ;
+       return 1;
+}
+
+static void sst_set_vidmod_att_ti(const int bpp)
+{
+       u8 cr0;
+
+       f_dprintk("sst_set_vidmod_att_ti(bpp: %d)\n", bpp);
+
+       sst_dac_write(DACREG_WMA, 0);   /* backdoor */
+       sst_dac_read(DACREG_RMR);       /* read 4 times RMR */
+       sst_dac_read(DACREG_RMR);
+       sst_dac_read(DACREG_RMR);
+       sst_dac_read(DACREG_RMR);
+       /* the fifth time,  CR0 is read */
+       cr0 = sst_dac_read(DACREG_RMR);
+
+       sst_dac_write(DACREG_WMA, 0);   /* backdoor */
+       sst_dac_read(DACREG_RMR);       /* read 4 times RMR */
+       sst_dac_read(DACREG_RMR);
+       sst_dac_read(DACREG_RMR);
+       sst_dac_read(DACREG_RMR);
+       /* cr0 */
+       switch(bpp) {
+       case 16:
+               sst_dac_write(DACREG_RMR, (cr0 & 0x0f) | DACREG_CR0_16BPP);
+               break;
+#ifdef EN_24_32_BPP
+       case 24:
+       case 32:
+               sst_dac_write(DACREG_RMR, (cr0 & 0x0f) | DACREG_CR0_24BPP);
+               break;
+#endif
+       default:
+               dprintk("bug line %d: bad depth '%u'\n", __LINE__, bpp);
+               break;
+       }
+}
+
+static void sst_set_vidmod_ics(const int bpp)
+{
+       f_dprintk("sst_set_vidmod_ics(bpp: %d)\n", bpp);
+       switch(bpp) {
+       case 16:
+               sst_dac_write(DACREG_ICS_CMD, DACREG_ICS_CMD_16BPP);
+               break;
+#ifdef EN_24_32_BPP
+       case 24:
+       case 32:
+               sst_dac_write(DACREG_ICS_CMD, DACREG_ICS_CMD_24BPP);
+               break;
+#endif
+       default:
+               dprintk("bug line %d: bad depth '%u'\n", __LINE__, bpp);
+               break;
+       }
+}
+
+static int __init sst_init(void)
+{
+       struct pll_timing gfx_timings;
+       int Fout;
+       int dac_ok;
+       u32 fbiinit0, fbiinit1, fbiinit4;
+       struct pci_dev * sst_dev = fb_info.dev; /* or define a macro ?*/
+
+       f_dprintk("sst_init\n");
+       f_ddprintk(" fbiinit0   fbiinit1   fbiinit2   fbiinit3   fbiinit4  "
+                  " fbiinit6\n");
+       f_ddprintk("%0#10x %0#10x %0#10x %0#10x %0#10x %0#10x\n",
+                   sst_read(FBIINIT0), sst_read(FBIINIT1), sst_read(FBIINIT2),
+                   sst_read(FBIINIT3), sst_read(FBIINIT4), sst_read(FBIINIT6));
+       /* disable video clock */
+       pci_write_config_dword(sst_dev, PCI_VCLK_DISABLE,0);
+
+       /* enable writing to init registers ,disable pci fifo*/
+       pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_INIT_WR);
+       /* reset video */
+       sst_set_bits(FBIINIT1, VIDEO_RESET);
+       sst_wait_idle();
+       /* reset gfx + pci fifo */
+       sst_set_bits(FBIINIT0, FBI_RESET | FIFO_RESET);
+       sst_wait_idle();
+
+       /* unreset fifo */
+       /*sst_unset_bits(FBIINIT0, FIFO_RESET);
+       sst_wait_idle();*/
+       /* unreset FBI */
+       /*sst_unset_bits(FBIINIT0, FBI_RESET);
+       sst_wait_idle();*/
+
+       /* disable dram refresh */
+       sst_unset_bits(FBIINIT2, EN_DRAM_REFRESH);
+       sst_wait_idle();
+       /* remap fbinit2/3 to dac */
+       pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
+                                      PCI_EN_INIT_WR | PCI_REMAP_DAC );
+       /* detect dac type */
+       dac_ok = sst_detect_dactype();
+       if (!dac_ok) {
+               eprintk("Unknown dac type\n");
+               return 0;
+       }
+
+       /* set graphic clock */
+       if (dac_ok) {
+               fb_info.gfx_clock = fb_info.spec->default_gfx_clock;
+               if ((gfxclk >10 ) && (gfxclk < fb_info.spec->max_gfxclk)) {
+                       iprintk ("Using supplied graphic freq : %dMHz\n", gfxclk);
+                        fb_info.gfx_clock = gfxclk *1000;
+               } else if (gfxclk) {
+                       wprintk ("You fool, %dMhz is way out of spec! Using default\n", gfxclk);
+               }
+
+               sst_calc_pll(fb_info.gfx_clock, &Fout, &gfx_timings);
+               fb_info.dac_sw->set_pll(&gfx_timings, GFX_CLOCK);
+       }
+       /* disable fbiinit remap */
+       pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
+                              PCI_EN_INIT_WR| PCI_EN_FIFO_WR );
+       /* defaults init registers */
+       /* FbiInit0: unreset gfx, unreset fifo */
+       fbiinit0 = FBIINIT0_DEFAULT;
+       fbiinit1 = FBIINIT1_DEFAULT;
+       fbiinit4 = FBIINIT4_DEFAULT;
+       if (vgapass)
+               fbiinit0 &= ~EN_VGA_PASSTHROUGH;
+       else
+               fbiinit0 |= EN_VGA_PASSTHROUGH;
+       if (slowpci) {
+               fbiinit1 |= SLOW_PCI_WRITES;
+               fbiinit4 |= SLOW_PCI_READS;
+       } else {
+               fbiinit1 &= ~SLOW_PCI_WRITES;
+               fbiinit4 &= ~SLOW_PCI_READS;
+       }
+       sst_write(FBIINIT0, fbiinit0);
+       sst_wait_idle();
+       sst_write(FBIINIT1, fbiinit1);
+       sst_wait_idle();
+       sst_write(FBIINIT2, FBIINIT2_DEFAULT);
+       sst_wait_idle();
+       sst_write(FBIINIT3, FBIINIT3_DEFAULT);
+       sst_wait_idle();
+       sst_write(FBIINIT4, fbiinit4);
+       sst_wait_idle();
+       if (fb_info.is_voodoo2) {
+               sst_write(FBIINIT6, FBIINIT6_DEFAULT);
+               sst_wait_idle();
+       }
+
+       pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_FIFO_WR );
+       pci_write_config_dword(sst_dev, PCI_VCLK_ENABLE, 0);
+
+       return dac_ok;
+}
+
+#ifdef MODULE
+
+static void  __exit sst_shutdown(void)
+{
+       struct pll_timing gfx_timings;
+       int Fout;
+       struct pci_dev * sst_dev = fb_info.dev;
+
+       f_dprintk("sst_shutdown\n");
+       /* reset video, gfx, fifo, disable dram + remap fbiinit2/3 */
+       pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_INIT_WR);
+       sst_set_bits(FBIINIT1, VIDEO_RESET | EN_BLANKING);
+       sst_unset_bits(FBIINIT2, EN_DRAM_REFRESH);
+       sst_set_bits(FBIINIT0, FBI_RESET | FIFO_RESET);
+       sst_wait_idle();
+       pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
+                              PCI_EN_INIT_WR | PCI_REMAP_DAC );
+       /*set 20Mhz gfx clock */
+       sst_calc_pll(20000, &Fout, &gfx_timings);
+       fb_info.dac_sw->set_pll(&gfx_timings, GFX_CLOCK);
+       /* TODO maybe shutdown the dac, vrefresh and so on... */
+       pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
+                              PCI_EN_INIT_WR);
+       sst_unset_bits(FBIINIT0, FBI_RESET | FIFO_RESET | EN_VGA_PASSTHROUGH);
+       pci_write_config_dword(sst_dev, PCI_VCLK_DISABLE,0);
+/* maybe keep fbiinit* and PCI_INIT_enable in the fb_info struct at the beginining ? */
+       pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, 0);
+
+}
+#endif /* MODULE */
+
+/*
+ * Interface to the world
+ */
+
+int  __init sstfb_setup(char *options)
+{
+       char *this_opt;
+
+       f_dprintk("sstfb_setup\n");
+
+       if (!options || !*options)
+               return 0;
+
+       for(this_opt = strtok(options, ","); this_opt;
+           this_opt = strtok(NULL, ",")) {
+               if (!*this_opt) continue;
+
+               f_ddprintk("option %s\n", this_opt);
+
+               if (!strcmp(this_opt, "inverse")) {
+                       inverse = 1;
+                       fb_invert_cmaps();
+               }
+               else if (!strcmp(this_opt, "vganopass"))
+                       vgapass = 0;
+               else if (!strcmp(this_opt, "vgapass"))
+                       vgapass = 1;
+               else if (!strcmp(this_opt, "clipping"))
+                       clipping = 1;
+               else if (!strcmp(this_opt, "noclipping"))
+                       clipping = 0;
+               else if (!strcmp(this_opt, "fastpci"))
+                       slowpci = 0;
+               else if (!strcmp(this_opt, "slowpci"))
+                       slowpci = 1;
+               else if (!strncmp(this_opt, "mem:",4))
+                       mem=simple_strtoul (this_opt+4, NULL, 0);
+               else if (!strncmp(this_opt, "gfxclk:",7))
+                       gfxclk=simple_strtoul (this_opt+7, NULL, 0);
+               else if (!strncmp(this_opt, "dev:",4))
+                       dev=simple_strtoul (this_opt+4, NULL, 0);
+               else
+                       mode_option=this_opt;
+       }
+       return 0;
+}
+
+int __init sstfb_init(void)
+{
+       struct pci_dev * pdev;
+       struct fb_var_screeninfo var;
+#define sst_dev        (fb_info.dev)
+       f_dprintk("sstfb_init\n");
+       dprintk("Compile date: "__DATE__" "__TIME__"\n");
+
+       memset (&fb_info, 0, sizeof(fb_info));
+       pci_for_each_dev(pdev) {
+               if (pdev->vendor != PCI_VENDOR_ID_3DFX) continue;
+               if (pdev->device == PCI_DEVICE_ID_3DFX_VOODOO) {
+                       fb_info.is_voodoo2=0;
+                       fb_info.spec=&voodoo1_spec;
+               }
+               else if (pdev->device == PCI_DEVICE_ID_3DFX_VOODOO2) {
+                       fb_info.is_voodoo2=1;
+                       fb_info.spec=&voodoo2_spec;
+               }
+               else
+                       continue;
+               if (dev > 0) {
+                       dev--;
+                       continue;
+               }
+               f_ddprintk("found device : %s\n", fb_info.spec->name);
+               fb_info.dev = pdev;
+               fb_info.mmio.base = sst_dev->resource[0].start;
+               pci_read_config_byte(sst_dev,
+                                    PCI_REVISION_ID, &fb_info.revision);
+
+               fb_info.mmio.vbase = (u32) ioremap_nocache(fb_info.mmio.base, 0x400000);
+               if (!fb_info.mmio.vbase) {
+                       eprintk("cannot remap register area %#lx\n",
+                               fb_info.mmio.base);
+                       return -ENXIO;
+               }
+               fb_info.video.base = fb_info.mmio.base+0x400000;
+               fb_info.video.vbase = (u32) ioremap_nocache(fb_info.video.base,
+                                                   0x400000);
+               if (!fb_info.video.vbase) {
+                       eprintk("cannot remap framebuffer %#lx\n",
+                               fb_info.video.base);
+                       iounmap((void*) fb_info.mmio.vbase);
+                       return -ENXIO;
+               }
+               if(!sst_init()) {
+                       eprintk("Init failed\n");
+                       iounmap((void*)fb_info.mmio.vbase);
+                       iounmap((void*)fb_info.video.vbase);
+                       return -ENXIO;
+               }
+               sst_get_memsize(&fb_info.video.len);
+               fb_info.configured = 1;
+               strncpy(fb_info.info.modename, fb_info.spec->name, 16);
+
+               iprintk("%s with %s dac\n", fb_info.info.modename, fb_info.dac_sw->name);
+               iprintk("framebuffer at %#lx, mapped to %#lx,"
+                       " size %ldMb\n",
+                       fb_info.video.base, fb_info.video.vbase,
+                       fb_info.video.len >> 20);
+
+               f_ddprintk("revision: %d\n", fb_info.revision);
+               f_ddprintk("regbase_virt: %#lx\n", fb_info.mmio.vbase);
+               f_ddprintk("membase_phys: %#lx\n", fb_info.video.base);
+               f_ddprintk("fbbase_virt: %#lx\n", fb_info.video.vbase);
+
+               fb_info.info.node       = -1 ;
+               fb_info.info.flags      = FBINFO_FLAG_DEFAULT;
+               fb_info.info.fbops      = &sstfb_ops;
+               fb_info.info.disp       = &disp;
+               fb_info.info.changevar  = NULL;
+               fb_info.info.switch_con = &sstfbcon_switch;
+               fb_info.info.updatevar  = &sstfbcon_updatevar;
+               fb_info.info.blank      = &sstfbcon_blank;
+               if ( !mode_option &&
+                    !fb_find_mode(&var, &fb_info.info, mode_option,
+                                  NULL, 0, NULL, 16)) {
+                       var = sstfb_default;
+               }
+               if (sstfb_set_var(&var, -1, &fb_info.info)) {
+                       eprintk("can't set supplied video mode. Using default\n");
+                       var = sstfb_default;
+                       if (sstfb_set_var(&var, -1, &fb_info.info)) {
+                               eprintk("can't set default video mode.\n");
+                               return -ENXIO;
+                       }
+               }
+               /*clear fb */
+               memset_io(fb_info.video.vbase, 0, fb_info.video.len);
+               /* print some squares ... */
+               sstfb_test16(&fb_info); /* FIXME this is only for 16bpp */
+
+               /* register fb */
+               if (register_framebuffer(&fb_info.info) < 0) {
+                       eprintk("can't register framebuffer.\n");
+                       return -ENXIO;
+               }
+               printk(KERN_INFO "fb%d: %s frame buffer device\n",
+                      GET_FB_IDX(fb_info.info.node),fb_info.info.modename);
+
+               num_sst++;
+
+               if (dev <= 0)   /* we use the first card only for now (==0) */
+                       return 0;
+       }
+       return -ENXIO;  /* no voodoo detected */
+#undef sst_dev
+}
+
+/*
+ * console driver
+ */
+static int sstfbcon_switch(int con, struct fb_info *info)
+{
+#define sst_info        ((struct sstfb_info *) info)
+       struct sstfb_par par;
+
+       f_dprintk("sstfbcon_switch(con: %d)\n",con);
+       f_ddprintk("currcon: %d\n", currcon);
+       v_dprintk("currcon: %d\n", currcon);
+
+       if (currcon >=  0) {
+               if (fb_display[currcon].cmap.len)
+                       fb_get_cmap(&fb_display[currcon].cmap, 1,
+                                   sstfb_getcolreg, info);
+       }
+       currcon = con;
+       fb_display[con].var.activate = FB_ACTIVATE_NOW;
+
+       print_var(&fb_display[con].var, "&fb_display[con: %d].var",con);
+       sstfb_decode_var(&fb_display[con].var, &par, sst_info);
+       if (memcmp(&par,&(sst_info->current_par),sizeof(par))) {
+               sstfb_set_par(&par, sst_info);
+       }
+       sstfb_install_cmap(con, info);
+       return 0;
+#undef sst_info
+}
+
+static int sstfbcon_updatevar(int con, struct fb_info *info)
+{
+       f_dprintk("sstfbcon_updatevar\n");
+       return -EINVAL;
+}
+
+static void sstfbcon_blank(int blank, struct fb_info *info)
+{
+       f_dprintk("sstfbcon_blank(level %d)\n", blank);
+}
+
+
+/* print some squares on the fb (presuming 16bpp)  */
+static void sstfb_test16(struct sstfb_info *sst_info)
+{
+       int i,j;
+       u_long p;
+       u_long fbbase_virt = sst_info->video.vbase;
+
+       f_dprintk("sstfb_test16\n");
+       /* rect blanc 20x100+200+0 */
+       for (i=0 ; i< 100; i++) {
+         p = fbbase_virt + 2048 *i+400;
+         for (j=0 ; j < 10 ; j++) {
+           writel( 0xffffffff, p);
+           p+=4;
+         }
+       }
+       /* rect bleu 180x200+0+0 */
+       for (i=0 ; i< 200; i++) {
+         p = fbbase_virt + 2048 *i;
+         for (j=0 ; j < 90 ; j++) {
+           writel(0x001f001f,p);
+           p+=4;
+         }
+       }
+       /* carre vert 40x40+100+0 */
+       for (i=0 ; i< 40 ; i++) {
+         p = fbbase_virt + 2048 *i + 200;
+         for (j=0; j <20;j++) {
+           writel(0x07e007e0, p);
+           p+=4;
+         }
+       }
+       /*carre rouge 40x40+100+40 */
+       for (i=0; i<40; i++) {
+         p = fbbase_virt + 2048 * (i+40) + 200;
+         for (j=0; j <20;j++) {
+           writel( 0xf800f800, p);
+           p+=4;
+         }
+       }
+}
+
+/* print some squares on the fb (24/32bpp)  */
+#ifdef EN_24_32_BPP
+static void sstfb_test32(struct sstfb_info *sst_info)
+{
+       int i,j;
+       u_long p;
+       u32 fbbase_virt = sst_info->video.vbase;
+
+       f_dprintk("sstfb_test32\n");
+       /* rect blanc 20x100+200+0 */
+       for (i=0 ; i< 100; i++) {
+         p = fbbase_virt + 4096*i + 800;
+         for (j=0 ; j < 20 ; j++) {
+           writel( 0x00ffffff, p);
+           p+=4;
+         }
+       }
+       /* rect bleu 180x200+0+0 */
+       for (i=0 ; i< 200; i++) {
+         p = fbbase_virt + 4096 * i;
+         for (j=0 ; j < 180 ; j++) {
+           writel(0x000000ff,p);
+           p+=4;
+         }
+       }
+       /* carre vert 40x40+100+0 */
+       for (i=0 ; i< 40 ; i++) {
+         p = fbbase_virt + 4096 *i + 400;
+         for (j=0; j <40;j++) {
+           writel(0x0000ff00, p);
+           p+=4;
+         }
+       }
+       /*carre rouge 40x40+100+10 */
+       for (i=0; i<40; i++) {
+         p = fbbase_virt + 4096 * (i+40) + 400;
+         for (j=0; j <40;j++) {
+           writel( 0x00ff0000, p);
+           p+=4;
+         }
+       }
+}
+#endif /* EN_24_32_BPP */
+
+#ifdef MODULE
+
+int init_module(void)
+{
+       f_dprintk("init_module\n");
+       sstfb_init();
+       if (num_sst == 0 )
+               return -ENXIO;
+       return 0;
+}
+
+void cleanup_module(void)
+{
+       f_dprintk("cleanup_module\n");
+       f_ddprintk("conf %d\n",fb_info.configured);
+
+       if (fb_info.configured) {
+               sst_shutdown();
+               iounmap((void*)fb_info.mmio.vbase);
+               iounmap((void*)fb_info.video.vbase);
+               unregister_framebuffer(&fb_info.info);
+       }
+}
+
+MODULE_AUTHOR("(c) 2000,2001 Ghozlane Toumi <gtoumi@messel.emse.fr>");
+MODULE_DESCRIPTION("FBDev driver for 3dfx Voodoo Graphics and Voodoo2 based video boards");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(mem, "i");
+MODULE_PARM_DESC(mem, "Size of frame buffer memory in MiB (1, 2, 4 Mb, default=autodetect)");
+MODULE_PARM(vgapass, "i");
+MODULE_PARM_DESC(vgapass, "Enable VGA PassThrough cable (0 or 1) (default=0)");
+MODULE_PARM(inverse, "i");
+MODULE_PARM_DESC(inverse, "Inverse colormap (0 or 1) (default=0)");
+MODULE_PARM(clipping , "i");
+MODULE_PARM_DESC(clipping, "Enable clipping (slower, safer) (0 or 1) (default=1)");
+MODULE_PARM(gfxclk , "i");
+MODULE_PARM_DESC(gfxclk, "Force graphic chip frequency in Mhz. DANGEROUS. (default=auto)");
+MODULE_PARM(slowpci, "i");
+MODULE_PARM_DESC(slowpci, "Uses slow PCI settings (0 or 1) (default=0)");
+MODULE_PARM(dev,"i");
+MODULE_PARM_DESC(dev , "Attach to device ID (0..n) (default=1st device)");
+#endif /* MODULE */
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
+
+#if 0
+void Dump_regs ( void)
+{
+       struct { u32 reg ; char * reg_name;}  pci_regs [] =  {
+               { PCI_INIT_ENABLE, "initenable"},
+               { PCI_VCLK_ENABLE, "enable vclk"}, 
+               { PCI_VCLK_DISABLE, "disable vclk"}, 
+       };
+
+       struct { u32 reg ; char * reg_name;}  sst_regs [] =  {
+               {FBIINIT0,"fbiinit0"},
+               {FBIINIT1,"fbiinit1"},
+               {FBIINIT2,"fbiinit2"},
+               {FBIINIT3,"fbiinit3"},
+               {FBIINIT4,"fbiinit4"},
+               {FBIINIT5,"fbiinit5"},
+               {FBIINIT6,"fbiinit6"},
+               {FBIINIT7,"fbiinit7"},
+               {LFBMODE,"lfbmode"},
+               {FBZMODE,"fbzmode"},
+       };
+       u32 pci_res[sizeof(pci_regs)/sizeof(pci_regs[0])];
+       u32 sst_res[sizeof(sst_regs)/sizeof(sst_regs[0])];
+
+       struct pci_dev * dev = fb_info.dev;
+
+       int i;
+
+       for (i=0; i<(sizeof(pci_regs)/sizeof(pci_regs[0])) ; i++ ) {
+               pci_read_config_dword ( dev, pci_regs[i].reg , &pci_res[i]) ;
+       }
+       for (i=0; i<(sizeof(sst_regs)/sizeof(sst_regs[0])) ; i++ ) {
+               sst_res[i]=sst_read(sst_regs[i].reg);
+       }
+
+       dprintk ("Dump regs\n");
+       for (i=0; i<(sizeof(pci_regs)/sizeof(pci_regs[0])) ; i++ ) {
+               dprintk("%s = %0#10x\n", pci_regs[i].reg_name , pci_res[i]) ;
+       }
+       for (i=0; i<(sizeof(sst_regs)/sizeof(sst_regs[0])) ; i++ ) {
+               dprintk("%s = %0#10x\n", sst_regs[i].reg_name , sst_res[i]) ;
+       }
+}
+#endif
diff --git a/drivers/video/sstfb.h b/drivers/video/sstfb.h
new file mode 100644 (file)
index 0000000..8175f65
--- /dev/null
@@ -0,0 +1,353 @@
+/*
+ * linux/drivers/video/sstfb.h -- voodoo graphics frame buffer
+ *
+ *     Copyright (c) 2000,2001 Ghozlane Toumi <gtoumi@messel.emse.fr>
+ *
+ *     Created 28 Aug 2001 by Ghozlane Toumi
+ *
+ * $Id: sstfb.h,v 1.1.4.1 2001/08/29 01:30:38 ghoz Exp $
+ */
+
+
+#ifndef _SSTFB_H_
+#define _SSTFB_H_
+/*
+ *
+ *  Debug Stuff
+ *
+ */
+
+#ifdef SST_DEBUG
+#  define dprintk(X...)        printk(KERN_DEBUG "sstfb: " X)
+#else
+#  define dprintk(X...)
+#  undef SST_DEBUG_REG
+#  undef SST_DEBUG_FUNC
+#  undef SST_DEBUG_VAR
+#  undef SST_DEBUG_IOCTL
+#endif
+
+#if (SST_DEBUG_REG > 0)
+#  define r_dprintk(X...)      dprintk(X)
+#else
+#  define r_dprintk(X...)
+#endif
+#if (SST_DEBUG_REG > 1)
+#  define r_ddprintk(X...)     dprintk(" " X)
+#else
+#  define r_ddprintk(X...)
+#endif
+
+#if (SST_DEBUG_FUNC > 0)
+#  define f_dprintk(X...)      dprintk(X)
+#else
+#  define f_dprintk(X...)
+#endif
+#if (SST_DEBUG_FUNC > 1)
+#  define f_ddprintk(X...)     dprintk(" " X)
+#else
+#  define f_ddprintk(X...)
+#endif
+#if (SST_DEBUG_FUNC > 2)
+#  define f_dddprintk(X...)    dprintk(" " X)
+#else
+#  define f_dddprintk(X...)
+#endif
+
+#if (SST_DEBUG_VAR > 0)
+#  define v_dprintk(X...)      dprintk(X)
+#  define print_var(V, X...)   \
+   {                           \
+     dprintk(X);               \
+     printk(" :\n");           \
+     sst_dbg_print_var(V);     \
+   }
+#else
+#  define v_dprintk(X...)
+#  define print_var(X,Y...)
+#endif
+
+#define eprintk(X...)  printk(KERN_ERR "sstfb: " X)
+#define iprintk(X...)  printk(KERN_INFO "sstfb: " X)
+#define wprintk(X...)  printk(KERN_WARNING "sstfb: " X)
+
+#define BIT(x)         (1ul << (x))
+#define PS2KHZ(a)      (1000000000UL/(a))      /* picoseconds to KHz */
+#define KHZ2PS(a)      (1000000000UL/(a))
+
+#ifndef ABS
+# define ABS(x)                (((x)<0)?-(x):(x))
+#endif
+
+//void Dump_regs(void);
+
+/*
+ *
+ *  Const
+ *
+ */
+
+/* pci stuff */
+#define PCI_INIT_ENABLE                0x40
+#  define PCI_EN_INIT_WR         BIT(0)
+#  define PCI_EN_FIFO_WR         BIT(1)
+#  define PCI_REMAP_DAC                  BIT(2)
+#define PCI_VCLK_ENABLE                0xc0    /* enable video */
+#define PCI_VCLK_DISABLE       0xe0
+
+/* register offsets from memBaseAddr */
+#define STATUS                 0x0000
+#  define STATUS_FBI_BUSY        BIT(7)
+#define FBZMODE                        0x0110
+#  define EN_CLIPPING            BIT(0)        /* enable clipping */
+#  define EN_RGB_WRITE           BIT(9)        /* enable writes to rgb area */
+#  define EN_ALPHA_WRITE         BIT(10)
+#  define ENGINE_INVERT_Y        BIT(17)       /* invert Y origin (pipe) */
+#define LFBMODE                        0x0114
+#  define LFB_565                0             /* bits 3:0 .16 bits RGB */
+#  define LFB_888                4             /* 24 bits RGB */
+#  define LFB_8888               5             /* 32 bits ARGB */
+#  define WR_BUFF_FRONT                  0             /* write buf select (front) */
+#  define WR_BUFF_BACK           (1 << 4)      /* back */
+#  define RD_BUFF_FRONT                  0             /* read buff select (front) */
+#  define RD_BUFF_BACK           (1 << 6)      /* back */
+#  define EN_PXL_PIPELINE        BIT(8)        /* pixel pipeline (clip..)*/
+#  define LFB_INVERT_Y           BIT(13)       /* invert Y origin (LFB) */
+#define CLIP_LEFT_RIGHT                0x0118
+#define CLIP_LOWY_HIGHY                0x011c
+#define NOPCMD                 0x0120
+#define FASTFILLCMD            0x0124
+#define SWAPBUFFCMD            0x0128
+#define FBIINIT4               0x0200          /* misc controls */
+#  define FAST_PCI_READS         0             /* 1 waitstate */
+#  define SLOW_PCI_READS         BIT(0)        /* 2 ws */
+#  define LFB_READ_AHEAD         BIT(1)
+#define BACKPORCH              0x0208
+#define VIDEODIMENSIONS                0x020c
+#define FBIINIT0               0x0210          /* misc+fifo  controls */
+#  define EN_VGA_PASSTHROUGH     BIT(0)
+#  define FBI_RESET              BIT(1)
+#  define FIFO_RESET             BIT(2)
+#define FBIINIT1               0x0214          /* PCI + video controls */
+#  define VIDEO_MASK             0x8080010f    /* masks video related bits V1+V2*/
+#  define FAST_PCI_WRITES        0             /* 0 ws */
+#  define SLOW_PCI_WRITES        BIT(1)        /* 1 ws */
+#  define EN_LFB_READ            BIT(3)
+#  define TILES_IN_X_SHIFT       4
+#  define VIDEO_RESET            BIT(8)
+#  define EN_BLANKING            BIT(12)
+#  define EN_DATA_OE             BIT(13)
+#  define EN_BLANK_OE            BIT(14)
+#  define EN_HVSYNC_OE           BIT(15)
+#  define EN_DCLK_OE             BIT(16)
+#  define SEL_INPUT_VCLK_2X      0             /* bit 17 */
+#  define SEL_INPUT_VCLK_SLAVE   BIT(17)
+#  define SEL_SOURCE_VCLK_SLAVE          0             /* bits 21:20 */
+#  define SEL_SOURCE_VCLK_2X_DIV2 (0x01 << 20)
+#  define SEL_SOURCE_VCLK_2X_SEL  (0x02 << 20)
+#  define EN_24BPP               BIT(22)
+#  define TILES_IN_X_MSB_SHIFT   24            /* v2 */
+#  define VCLK_2X_SEL_DEL_SHIFT          27            /* vclk out delay 0,4,6,8ns */
+#  define VCLK_DEL_SHIFT         29            /* vclk in delay */
+#define FBIINIT2               0x0218          /* Dram controls */
+#  define EN_FAST_RAS_READ       BIT(5)
+#  define EN_DRAM_OE             BIT(6)
+#  define EN_FAST_RD_AHEAD_WR    BIT(7)
+#  define VIDEO_OFFSET_SHIFT     11            /* unit: #rows tile 64x16/2 */
+#  define SWAP_DACVSYNC                  0
+#  define SWAP_DACDATA0                  (1 << 9)
+#  define SWAP_FIFO_STALL        (2 << 9)
+#  define EN_RD_AHEAD_FIFO       BIT(21)
+#  define EN_DRAM_REFRESH        BIT(22)
+#  define DRAM_REFRESH_16        (0x30 << 23)  /* dram 16 ms */
+#define DAC_READ               FBIINIT2        /* in remap mode */
+#define FBIINIT3               0x021c          /* fbi controls */
+#  define DISABLE_TEXTURE        BIT(6)
+#  define Y_SWAP_ORIGIN_SHIFT    22            /* Y swap substraction value */
+#define HSYNC                  0x0220
+#define VSYNC                  0x0224
+#define DAC_DATA               0x022c
+#  define DAC_READ_CMD           BIT(11)       /* set read dacreg mode */
+#define FBIINIT5               0x0244          /* v2 specific */
+#define FBIINIT6               0x0248          /* v2 specific */
+#define FBIINIT7               0x024c          /* v2 specific */
+#  define TILES_IN_X_LSB_SHIFT   30            /* v2 */
+
+/* Dac Registers */
+#define DACREG_WMA             0x0     /* pixel write mode address */
+#define DACREG_LUT             0x01    /* color value */
+#define DACREG_RMR             0x02    /* pixel mask */
+#define DACREG_RMA             0x03    /* pixel read mode address */
+/*Dac registers in indexed mode (TI, ATT dacs) */
+#define DACREG_ADDR_I          DACREG_WMA
+#define DACREG_DATA_I          DACREG_RMR
+#define DACREG_RMR_I           0x00
+#define DACREG_CR0_I           0x01
+#  define DACREG_CR0_EN_INDEXED          BIT(0)        /* enable indexec mode */
+#  define DACREG_CR0_8BIT        BIT(1)        /* set dac to 8 bits/read */
+#  define DACREG_CR0_PWDOWN      BIT(3)        /* powerdown dac */
+#  define DACREG_CR0_16BPP       0x30          /* mode 3 */
+#  define DACREG_CR0_24BPP       0x50          /* mode 5 */
+#define        DACREG_CR1_I            0x05
+#define DACREG_CC_I            0x06
+#  define DACREG_CC_CLKA         BIT(7)        /* clk A controled by regs */
+#  define DACREG_CC_CLKA_C       (2<<4)        /* clk A uses reg C */
+#  define DACREG_CC_CLKB         BIT(3)        /* clk B controled by regs */
+#  define DACREG_CC_CLKB_D       3             /* clkB uses reg D */
+#define DACREG_AC0_I           0x48            /* clock A reg C */
+#define DACREG_AC1_I           0x49
+#define DACREG_BD0_I           0x6c            /* clock B reg D */
+#define DACREG_BD1_I           0x6d
+
+/* identification constants */
+#define DACREG_MIR_TI          0x97
+#define DACREG_DIR_TI          0x09
+#define DACREG_MIR_ATT         0x84
+#define DACREG_DIR_ATT         0x09
+/* ics dac specific registers*/
+#define DACREG_ICS_PLLWMA      0x04    /* PLL write mode address */
+#define DACREG_ICS_PLLDATA     0x05    /* PLL data /parameter */
+#define DACREG_ICS_CMD         0x06    /* command */
+#  define DACREG_ICS_CMD_16BPP   0x50  /* ics color mode 6 (16bpp bypass)*/
+#  define DACREG_ICS_CMD_24BPP   0x70  /* ics color mode 7 (24bpp bypass)*/
+#  define DACREG_ICS_CMD_PWDOWN BIT(0) /* powerdown dac */
+#define DACREG_ICS_PLLRMA      0x07    /* PLL read mode address */
+/*
+ * pll parameter register:
+ * indexed : write addr to PLLWMA, write data in PLLDATA.
+ * for reads use PLLRMA .
+ * 8 freq registers (0-7) for video clock (CLK0)
+ * 2 freq registers (a-b) for graphic clock (CLK1)
+ */
+#define DACREG_ICS_PLL_CLK0_1_INI 0x55 /* initial pll M value for freq f1  */
+#define DACREG_ICS_PLL_CLK0_7_INI 0x71 /* f7 */
+#define DACREG_ICS_PLL_CLK1_B_INI 0x79 /* fb */
+#define DACREG_ICS_PLL_CTRL    0x0e
+#  define DACREG_ICS_CLK0        BIT(5)
+#  define DACREG_ICS_CLK0_0      0
+#  define DACREG_ICS_CLK1_A      0     /* bit4 */
+
+/* sst default init registers */
+#define FBIINIT0_DEFAULT EN_VGA_PASSTHROUGH
+
+#define FBIINIT1_DEFAULT       \
+       (                       \
+         FAST_PCI_WRITES       \
+/*       SLOW_PCI_WRITES*/     \
+       | VIDEO_RESET           \
+       | 10 << TILES_IN_X_SHIFT\
+       | SEL_SOURCE_VCLK_2X_SEL\
+       | EN_LFB_READ           \
+       )
+
+#define FBIINIT2_DEFAULT       \
+       (                       \
+        SWAP_DACVSYNC          \
+       | EN_DRAM_OE            \
+       | DRAM_REFRESH_16       \
+       | EN_DRAM_REFRESH       \
+       | EN_FAST_RAS_READ      \
+       | EN_RD_AHEAD_FIFO      \
+       | EN_FAST_RD_AHEAD_WR   \
+       )
+
+#define FBIINIT3_DEFAULT       \
+       ( DISABLE_TEXTURE )
+
+#define FBIINIT4_DEFAULT       \
+       (                       \
+         FAST_PCI_READS        \
+/*       SLOW_PCI_READS*/      \
+       | LFB_READ_AHEAD        \
+       )
+/* Careful with this one : writing back the data just read will trash the DAC
+   reading some fields give logic value on pins, but setting this field will
+   set the source signal driving the pin. conclusion : just use the default
+   as a base before writing back .
+*/
+#define FBIINIT6_DEFAULT       (0x0)
+
+/*
+ *
+ * Misc Const
+ *
+ */
+
+/* used to know witch clock to set */
+#define VID_CLOCK      0
+#define GFX_CLOCK      1
+
+/* freq max */
+#define DAC_FREF       14318   /* DAC reference freq (Khz) */
+#define VCO_MAX                260000
+
+/*
+ *
+ *  Declarations
+ *
+ */
+
+struct pll_timing {
+       u8 m;
+       u8 n;
+       u8 p;
+};
+
+struct dac_switch {
+       char * name;
+       int (*detect) (void);
+       int (*set_pll) (const struct pll_timing *t, const int clock);
+       void (*set_vidmod) (const int bpp);
+};
+
+struct sst_spec {
+       char * name;
+       int default_gfx_clock;  /* 50000 for voodoo1, 75000 for voodoo2 */
+       int max_gfxclk;         /* ! in Mhz ie 60 for voodoo 1 */
+};
+
+struct sstfb_par {
+       unsigned int bpp;
+       unsigned int xDim;      /* xres */
+       unsigned int hSyncOn;   /* hsync_len */
+       unsigned int hSyncOff;  /* left_margin + xres + right_margin */
+       unsigned int hBackPorch;/* left_margin */
+       unsigned int yDim;
+       unsigned int vSyncOn;
+       unsigned int vSyncOff;
+       unsigned int vBackPorch;
+       unsigned int freq;      /* freq in picoseconds */
+       unsigned int tiles_in_X; /* num of tiles in X res */
+};
+
+struct sstfb_info {
+       struct fb_info          info;
+       struct sstfb_par        current_par;
+       struct pci_dev  *       dev;
+
+       struct {
+               unsigned long   base;   /* physical */
+               unsigned long   vbase;  /* virtual (CPU view) */
+               unsigned long   len;
+       } video;                        /* fb memory info */
+       struct {
+               unsigned long   base;
+               unsigned long   vbase;
+       } mmio;                         /* registers memory info */
+
+       struct dac_switch *     dac_sw; /* dac specific functions */
+       struct sst_spec *       spec;
+
+       int     is_voodoo2;
+       u8      revision;
+
+       /* status */
+       int     configured;
+/*     int     indexed_mode;
+       int     vgapass;
+       int     clipping; */
+       int     gfx_clock;
+};
+
+#endif /* _SSTFB_H_ */
diff --git a/drivers/video/tx3912fb.c b/drivers/video/tx3912fb.c
new file mode 100644 (file)
index 0000000..8f102a8
--- /dev/null
@@ -0,0 +1,529 @@
+/*
+ * linux/drivers/video/tx3912fb.c
+ *
+ * Copyright (C) 1999 Harald Koerfgen
+ * Copyright (C) 2001 Steven Hill (sjhill@realitydiluted.com)
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ * Framebuffer for LCD controller in TMPR3912/05 and PR31700 processors
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/fb.h>
+#include <asm/bootinfo.h>
+#include <asm/uaccess.h>
+#include <video/fbcon.h>
+#include <video/fbcon-mfb.h>
+#include <video/fbcon-cfb2.h>
+#include <video/fbcon-cfb4.h>
+#include <video/fbcon-cfb8.h>
+#include "tx3912fb.h"
+
+/*
+ * Frame buffer, palette and console structures
+ */
+static struct fb_info fb_info;
+static struct { u_char red, green, blue, pad; } palette[256];
+static struct display global_disp;
+static int currcon = 0;
+
+/*
+ * Interface used by the world
+ */
+static int tx3912fb_get_fix(struct fb_fix_screeninfo *fix, int con,
+                               struct fb_info *info);
+static int tx3912fb_get_var(struct fb_var_screeninfo *var, int con,
+                               struct fb_info *info);
+static int tx3912fb_set_var(struct fb_var_screeninfo *var, int con,
+                               struct fb_info *info);
+static int tx3912fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+                               struct fb_info *info);
+static int tx3912fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+                               struct fb_info *info);
+static int tx3912fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+                               u_long arg, int con, struct fb_info *info);
+
+/*
+ * Interface used by console driver
+ */
+int tx3912fb_init(void);
+static int tx3912fbcon_switch(int con, struct fb_info *info);
+static int tx3912fbcon_updatevar(int con, struct fb_info *info);
+static void tx3912fbcon_blank(int blank, struct fb_info *info);
+
+/*
+ * Macros
+ */
+#define get_line_length(xres_virtual, bpp) \
+               (u_long) (((int) xres_virtual * (int) bpp + 7) >> 3)
+
+/*
+ * Internal routines
+ */
+static int tx3912fb_getcolreg(u_int regno, u_int *red, u_int *green,
+                       u_int *blue, u_int *transp, struct fb_info *info);
+static int tx3912fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                       u_int transp, struct fb_info *info);
+static void tx3912fb_install_cmap(int con, struct fb_info *info);
+
+
+/*
+ * Frame buffer operations structure used by console driver
+ */
+static struct fb_ops tx3912fb_ops = {
+       owner: THIS_MODULE,
+       fb_get_fix: tx3912fb_get_fix,
+       fb_get_var: tx3912fb_get_var,
+       fb_set_var: tx3912fb_set_var,
+       fb_get_cmap: tx3912fb_get_cmap,
+       fb_set_cmap: tx3912fb_set_cmap,
+       fb_ioctl: tx3912fb_ioctl,
+};
+
+
+/*
+ *  Get fixed display data
+ */
+static int tx3912fb_get_fix(struct fb_fix_screeninfo *fix, int con,
+                               struct fb_info *info)
+{
+       struct display *display;
+
+       memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+       strcpy(fix->id, TX3912FB_NAME);
+
+       if (con == -1)
+               display = &global_disp;
+       else
+               display = &fb_display[con];
+
+       fix->smem_start         = tx3912fb_vaddr;
+       fix->smem_len           = tx3912fb_size;
+       fix->type               = display->type;
+       fix->type_aux           = display->type_aux;
+       fix->xpanstep           = 0;
+       fix->ypanstep           = display->ypanstep;
+       fix->ywrapstep          = display->ywrapstep;
+       fix->visual             = display->visual;
+       fix->line_length        = display->line_length;
+       fix->accel              = FB_ACCEL_NONE;
+
+       return 0;
+}
+
+/*
+ * Get user display data
+ */
+static int tx3912fb_get_var(struct fb_var_screeninfo *var, int con,
+                               struct fb_info *info)
+{
+       if (con == -1)
+               *var = tx3912fb_info;
+       else
+               *var = fb_display[con].var;
+
+       return 0;
+}
+
+/*
+ *  Set user display data
+ */
+static int tx3912fb_set_var(struct fb_var_screeninfo *var, int con,
+                               struct fb_info *info)
+{
+       int err, activate = var->activate;
+       int oldxres, oldyres, oldvxres, oldvyres, oldbpp;
+       u_long line_length;
+       struct display *display;
+
+       if (con == -1)
+               display = &global_disp;
+       else
+               display = &fb_display[con];
+
+       /*
+        * FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal
+        * as FB_VMODE_SMOOTH_XPAN is only used internally
+        */
+       if (var->vmode & FB_VMODE_CONUPDATE) {
+               var->xoffset = display->var.xoffset;
+               var->yoffset = display->var.yoffset;
+               var->vmode |= FB_VMODE_YWRAP;
+       }
+
+       /*
+        * Make sure values are in range
+        */
+       if (!var->xres)
+               var->xres = 1;
+       if (!var->yres)
+               var->yres = 1;
+       if (var->xres > var->xres_virtual)
+               var->xres_virtual = var->xres;
+       if (var->yres > var->yres_virtual)
+               var->yres_virtual = var->yres;
+       if (var->bits_per_pixel <= 1)
+               var->bits_per_pixel = 1;
+       else if (var->bits_per_pixel <= 2)
+               var->bits_per_pixel = 2;
+       else if (var->bits_per_pixel <= 4)
+               var->bits_per_pixel = 4;
+       else if (var->bits_per_pixel <= 8)
+               var->bits_per_pixel = 8;
+       else
+               return -EINVAL;
+
+       /*
+        * Memory limit
+        */
+       line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
+       if ((line_length * var->yres_virtual) > tx3912fb_size)
+               return -ENOMEM;
+
+       /*
+        * This is only for color and we only support 8-bit color
+        */
+       if (var->bits_per_pixel) {
+               /* RGB 332 */
+               var->red.offset = 5;
+               var->red.length = 3;
+               var->green.offset = 2;
+               var->green.length = 3;
+               var->blue.offset = 0;
+               var->blue.length = 2;
+               var->transp.offset = 0;
+               var->transp.length = 0;
+       }
+       var->red.msb_right = 0;
+       var->green.msb_right = 0;
+       var->blue.msb_right = 0;
+       var->transp.msb_right = 0;
+
+       /*
+        * Make changes if necessary
+        */
+       if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+
+               oldxres = display->var.xres;
+               oldyres = display->var.yres;
+               oldvxres = display->var.xres_virtual;
+               oldvyres = display->var.yres_virtual;
+               oldbpp = display->var.bits_per_pixel;
+               display->var = *var;
+
+               if (oldxres != var->xres || oldyres != var->yres ||
+                   oldvxres != var->xres_virtual ||
+                   oldvyres != var->yres_virtual ||
+                   oldbpp != var->bits_per_pixel) {
+
+                       display->screen_base = (u_char *) tx3912fb_vaddr;
+
+                       switch (var->bits_per_pixel) {
+                       case 1:
+                               display->visual = FB_VISUAL_MONO10;
+                               break;
+                       case 2:
+                               display->visual = FB_VISUAL_PSEUDOCOLOR;
+                       case 4:
+                       case 8:
+                               display->visual = FB_VISUAL_TRUECOLOR;
+                               break;
+                       }
+
+                       display->type = FB_TYPE_PACKED_PIXELS;
+                       display->type_aux = 0;
+                       display->ypanstep = 0;
+                       display->ywrapstep = 0;
+                       display->next_line =
+                       display->line_length =
+                               get_line_length(var->xres_virtual,
+                                       var->bits_per_pixel);
+                       display->can_soft_blank = 0;
+                       display->inverse = FB_IS_INVERSE;
+
+                       switch (var->bits_per_pixel) {
+#ifdef CONFIG_FBCON_MFB
+                       case 1:
+                               display->dispsw = &fbcon_mfb;
+                               break;
+#endif
+#ifdef CONFIG_FBCON_CFB2
+                       case 2:
+                               display->dispsw = &fbcon_cfb2;
+                               break;
+#endif
+#ifdef CONFIG_FBCON_CFB4
+                       case 4:
+                               display->dispsw = &fbcon_cfb4;
+                               break;
+#endif
+#ifdef CONFIG_FBCON_CFB8
+                       case 8:
+                               display->dispsw = &fbcon_cfb8;
+                               display->dispsw_data = fbcon_cmap.cfb8;
+                               break;
+#endif
+                       default:
+                               display->dispsw = &fbcon_dummy;
+                               break;
+                       }
+
+                       if (fb_info.changevar)
+                               (*fb_info.changevar)(con);
+               }
+
+               if (oldbpp != var->bits_per_pixel) {
+                       if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
+                               return err;
+                       tx3912fb_install_cmap(con, info);
+               }
+       }
+
+       return 0;
+}
+
+/*
+ *  Get the colormap
+ */
+static int tx3912fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+                       struct fb_info *info)
+{
+       if (con == currcon)
+               return fb_get_cmap(cmap, kspc, tx3912fb_getcolreg, info);
+       else if (fb_display[con].cmap.len) /* non default colormap? */
+               fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+       else
+               fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), cmap, kspc ? 0 : 2);
+
+       return 0;
+}
+
+/*
+ *  Set the Colormap
+ */
+static int tx3912fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+                       struct fb_info *info)
+{
+       int err;
+
+       if (!fb_display[con].cmap.len)
+               if ((err = fb_alloc_cmap(&fb_display[con].cmap,
+                               1<<fb_display[con].var.bits_per_pixel, 0)))
+                       return err;
+
+       if (con == currcon)
+               return fb_set_cmap(cmap, kspc, tx3912fb_setcolreg, info);
+       else
+               fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+
+       return 0;
+}
+
+/*
+ *  Framebuffer ioctl
+ */
+static int tx3912fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+                               u_long arg, int con, struct fb_info *info)
+{
+       return -EINVAL;
+}
+
+/*
+ * Initialization of the framebuffer
+ */
+int __init tx3912fb_init(void)
+{
+       /* Stop the video logic when frame completes */
+       VidCtrl1 |= ENFREEZEFRAME;
+       IntClear1 |= INT1_LCDINT;
+       while (!(IntStatus1 & INT1_LCDINT));
+
+       /* Disable the video logic */
+       VidCtrl1 &= ~(ENVID | DISPON);
+       udelay(200);
+
+       /* Set start address for DMA transfer */
+       VidCtrl3 = tx3912fb_paddr &
+               (TX3912_VIDCTRL3_VIDBANK_MASK | TX3912_VIDCTRL3_VIDBASEHI_MASK);
+
+       /* Set end address for DMA transfer */
+       VidCtrl4 = (tx3912fb_paddr + tx3912fb_size + 1) &
+               TX3912_VIDCTRL4_VIDBASELO_MASK;
+
+       /* Set the pixel depth */
+       switch (tx3912fb_info.bits_per_pixel) {
+       case 1:
+               /* Monochrome */
+               VidCtrl1 &= ~TX3912_VIDCTRL1_BITSEL_MASK;
+               break;
+       case 4:
+               /* 4-bit gray */
+               VidCtrl1 &= ~TX3912_VIDCTRL1_BITSEL_MASK;
+               VidCtrl1 |= TX3912_VIDCTRL1_4BIT_GRAY;
+               break;
+       case 8:
+               /* 8-bit color */
+               VidCtrl1 &= ~TX3912_VIDCTRL1_BITSEL_MASK;
+               VidCtrl1 |= TX3912_VIDCTRL1_8BIT_COLOR;
+               break;
+       case 2:
+       default:
+               /* 2-bit gray */
+               VidCtrl1 &= ~TX3912_VIDCTRL1_BITSEL_MASK;
+               VidCtrl1 |= TX3912_VIDCTRL1_2BIT_GRAY;
+               break;
+       }
+
+       /* Unfreeze video logic and enable DF toggle */
+       VidCtrl1 &= ~(ENFREEZEFRAME | DFMODE);
+       udelay(200);
+
+       /* Clear the framebuffer */
+       memset((void *) tx3912fb_vaddr, 0xff, tx3912fb_size);
+       udelay(200);
+
+       /* Enable the video logic */
+       VidCtrl1 |= (DISPON | ENVID);
+
+       strcpy(fb_info.modename, TX3912FB_NAME);
+       fb_info.changevar = NULL;
+       fb_info.node = -1;
+       fb_info.fbops = &tx3912fb_ops;
+       fb_info.disp = &global_disp;
+       fb_info.switch_con = &tx3912fbcon_switch;
+       fb_info.updatevar = &tx3912fbcon_updatevar;
+       fb_info.blank = &tx3912fbcon_blank;
+       fb_info.flags = FBINFO_FLAG_DEFAULT;
+
+       tx3912fb_set_var(&tx3912fb_info, -1, &fb_info);
+
+       if (register_framebuffer(&fb_info) < 0)
+               return -1;
+
+       printk (KERN_INFO "fb%d: TX3912 frame buffer using %uKB.\n",
+               GET_FB_IDX(fb_info.node), (u_int) (tx3912fb_size >> 10));
+
+       return 0;
+}
+
+/*
+ * Switch the console to be the framebuffer
+ */
+static int tx3912fbcon_switch(int con, struct fb_info *info)
+{
+       /* Save off the color map if needed */
+       if (fb_display[currcon].cmap.len)
+               fb_get_cmap(&fb_display[currcon].cmap, 1,
+                       tx3912fb_getcolreg, info);
+
+       /* Make the switch */
+       currcon = con;
+
+       /* Install new colormap */
+       tx3912fb_install_cmap(con, info);
+
+       return 0;
+}
+
+/*
+ * Update variable structure
+ */
+static int tx3912fbcon_updatevar(int con, struct fb_info *info)
+{
+       /* Nothing */
+       return 0;
+}
+
+/*
+ * Blank the display
+ */
+static void tx3912fbcon_blank(int blank, struct fb_info *info)
+{
+       /* FIXME */
+       printk("tx3912fbcon_blank\n");
+}
+
+/*
+ * Read a single color register
+ */
+static int tx3912fb_getcolreg(u_int regno, u_int *red, u_int *green,
+                       u_int *blue, u_int *transp, struct fb_info *info)
+{
+       if (regno > 255)
+               return 1;
+
+#if FB_IS_GREY
+       {
+               u_int grey;
+            
+               grey = regno * 255 / 15;
+
+#if FB_IS_INVERSE
+               grey ^= 255;
+#endif
+               grey |= grey << 8;
+               *red = grey;
+               *green = grey;
+               *blue = grey;
+       }
+#else
+       *red = (palette[regno].red<<8) | palette[regno].red;
+       *green = (palette[regno].green<<8) | palette[regno].green;
+       *blue = (palette[regno].blue<<8) | palette[regno].blue;
+#endif
+       *transp = 0;
+
+       return 0;
+}
+
+/*
+ * Set a single color register
+ */
+static int tx3912fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                               u_int transp, struct fb_info *info)
+{
+       if (regno > 255)
+               return 1;
+
+#ifdef FBCON_HAS_CFB8
+       if( regno < 16 )
+               fbcon_cmap.cfb8[regno] = ((red & 0xe000) >> 8)
+                                       | ((green & 0xe000) >> 11)
+                                       | ((blue & 0xc000) >> 14);
+#endif 
+
+       red >>= 8;
+       green >>= 8;
+       blue >>= 8;
+       palette[regno].red = red;
+       palette[regno].green = green;
+       palette[regno].blue = blue;
+
+       return 0;
+}
+
+/*
+ * Install the color map
+ */
+static void tx3912fb_install_cmap(int con, struct fb_info *info)
+{
+       if (con != currcon)
+               return;
+
+       if (fb_display[con].cmap.len)
+               fb_set_cmap(&fb_display[con].cmap, 1, tx3912fb_setcolreg, info);
+       else
+               fb_set_cmap(fb_default_cmap(1 << fb_display[con].var.bits_per_pixel), 1, tx3912fb_setcolreg, info);
+}
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/tx3912fb.h b/drivers/video/tx3912fb.h
new file mode 100644 (file)
index 0000000..09d7dd0
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * linux/drivers/video/tx3912fb.h
+ *
+ * Copyright (C) 2001 Steven Hill (sjhill@realitydiluted.com)
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ * Includes for TMPR3912/05 and PR31700 LCD controller registers
+ */
+#include <asm/tx3912.h>
+
+#define VidCtrl1        REG_AT(0x028)
+#define VidCtrl2        REG_AT(0x02C)
+#define VidCtrl3        REG_AT(0x030)
+#define VidCtrl4        REG_AT(0x034)
+#define VidCtrl5        REG_AT(0x038)
+#define VidCtrl6        REG_AT(0x03C)
+#define VidCtrl7        REG_AT(0x040)
+#define VidCtrl8        REG_AT(0x044)
+#define VidCtrl9        REG_AT(0x048)
+#define VidCtrl10       REG_AT(0x04C)
+#define VidCtrl11       REG_AT(0x050)
+#define VidCtrl12       REG_AT(0x054)
+#define VidCtrl13       REG_AT(0x058)
+#define VidCtrl14       REG_AT(0x05C)
+
+/* Video Control 1 Register */
+#define LINECNT         0xffc00000
+#define LINECNT_SHIFT   22
+#define LOADDLY         BIT(21)
+#define BAUDVAL         (BIT(20) | BIT(19) | BIT(18) | BIT(17) | BIT(16))
+#define BAUDVAL_SHIFT   16
+#define VIDDONEVAL      (BIT(15) | BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) | BIT(9))
+#define VIDDONEVAL_SHIFT  9
+#define ENFREEZEFRAME   BIT(8)
+#define TX3912_VIDCTRL1_BITSEL_MASK    0x000000c0
+#define TX3912_VIDCTRL1_2BIT_GRAY      0x00000040
+#define TX3912_VIDCTRL1_4BIT_GRAY      0x00000080
+#define TX3912_VIDCTRL1_8BIT_COLOR     0x000000c0
+#define BITSEL_SHIFT    6
+#define DISPSPLIT       BIT(5)
+#define DISP8           BIT(4)
+#define DFMODE          BIT(3)
+#define INVVID          BIT(2)
+#define DISPON          BIT(1)
+#define ENVID           BIT(0)
+
+/* Video Control 2 Register */
+#define VIDRATE_MASK    0xffc00000
+#define VIDRATE_SHIFT   22
+#define HORZVAL_MASK    0x001ff000
+#define HORZVAL_SHIFT   12
+#define LINEVAL_MASK    0x000001ff
+
+/* Video Control 3 Register */
+#define TX3912_VIDCTRL3_VIDBANK_MASK    0xfff00000
+#define TX3912_VIDCTRL3_VIDBASEHI_MASK  0x000ffff0
+
+/* Video Control 4 Register */
+#define TX3912_VIDCTRL4_VIDBASELO_MASK  0x000ffff0
+
+
+/*
+ * Begin platform specific configurations
+ */
+#if defined(CONFIG_NINO_4MB) || defined(CONFIG_NINO_8MB)
+#define FB_X_RES       240
+#define FB_Y_RES       320
+#if defined(CONFIG_FBCON_CFB4)
+#define FB_BPP         4
+#else
+#if defined(CONFIG_FBCON_CFB2)
+#define FB_BPP         2
+#else
+#define FB_BPP         1
+#endif
+#endif
+#define FB_IS_GREY     1
+#define FB_IS_INVERSE  0
+#endif
+
+#ifdef CONFIG_NINO_16MB
+#define FB_X_RES       240
+#define FB_Y_RES       320
+#define FB_BPP         8
+#define FB_IS_GREY     0
+#define FB_IS_INVERSE  0
+#endif
+
+/*
+ * Define virtual resolutions if necessary
+ */
+#ifndef FB_X_VIRTUAL_RES
+#define FB_X_VIRTUAL_RES FB_X_RES
+#endif
+#ifndef FB_Y_VIRTUAL_RES
+#define FB_Y_VIRTUAL_RES FB_Y_RES
+#endif
+
+/*
+ * Framebuffer address and size
+ */
+u_long tx3912fb_paddr = 0;
+u_long tx3912fb_vaddr = 0;
+u_long tx3912fb_size = (FB_X_RES * FB_Y_RES * FB_BPP / 8);
+
+/*
+ * Framebuffer info structure
+ */
+static struct fb_var_screeninfo tx3912fb_info = {
+       FB_X_RES, FB_Y_RES,
+       FB_X_VIRTUAL_RES, FB_Y_VIRTUAL_RES,
+       0, 0,
+       FB_BPP, FB_IS_GREY,
+       {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
+       0, FB_ACTIVATE_NOW,
+       -1, -1, 0, 20000,
+       64, 64, 32, 32, 64, 2,
+       0, FB_VMODE_NONINTERLACED,
+       {0,0,0,0,0,0}
+};
+
+/*
+ * Framebuffer name
+ */
+static char TX3912FB_NAME[16] = "tx3912fb";
index c7299c891e80bf35a30a5b1e31d78553a7dbdf0c..0dd532d3a5d60e5a1d62965b89e5b530f15777a2 100644 (file)
@@ -37,9 +37,9 @@ struct zorro_manuf_info {
  * real memory.. Parse the same file multiple times
  * to get all the info.
  */
-#define MANUF( manuf, name )           static const char __manufstr_##manuf[] __initdata = name;
+#define MANUF( manuf, name )           static char __manufstr_##manuf[] __initdata = name;
 #define ENDMANUF()
-#define PRODUCT( manuf, prod, name )   static const char __prodstr_##manuf##prod[] __initdata = name;
+#define PRODUCT( manuf, prod, name )   static char __prodstr_##manuf##prod[] __initdata = name;
 #include "devlist.h"
 
 
@@ -48,7 +48,7 @@ struct zorro_manuf_info {
 #define PRODUCT( manuf, prod, name )   { 0x##prod, 0, __prodstr_##manuf##prod },
 #include "devlist.h"
 
-static const struct zorro_manuf_info __initdata zorro_manuf_list[] = {
+static struct zorro_manuf_info __initdata zorro_manuf_list[] = {
 #define MANUF( manuf, name )           { 0x##manuf, sizeof(__prods_##manuf) / sizeof(struct zorro_prod_info), __manufstr_##manuf, __prods_##manuf },
 #define ENDMANUF()
 #define PRODUCT( manuf, prod, name )
index 114a27ebbbcfa976866d9610487e5c84c9cb60db..ec77dc7e926130b24ae634b27698393aa32b2214 100644 (file)
@@ -173,3 +173,5 @@ void __init zorro_init(void)
 
 EXPORT_SYMBOL(zorro_find_device);
 EXPORT_SYMBOL(zorro_unused_z2ram);
+
+MODULE_LICENSE("GPL");
index b4ea3a1a9de9ad9db03a08f4f622af0063b61f04..4f033cff6ebcdf5ecd8802b08a7841551021d787 100644 (file)
@@ -220,7 +220,7 @@ adfs_unix2adfs_time(struct inode *inode, unsigned int secs)
        if (inode->u.adfs_i.stamped) {
                /* convert 32-bit seconds to 40-bit centi-seconds */
                low  = (secs & 255) * 100;
-               high = (secs / 256) * 100 + (low << 8) + 0x336e996a;
+               high = (secs / 256) * 100 + (low >> 8) + 0x336e996a;
 
                inode->u.adfs_i.loadaddr = (high >> 24) |
                                (inode->u.adfs_i.loadaddr & ~0xff);
index bc06e38f32aef78e52cc83d98ad1736195d29f9c..e148ab4431aa10e6c2ffefaa85f1a682f18141c8 100644 (file)
@@ -660,7 +660,6 @@ static int dqinit_needed(struct inode *inode, short type)
 static void add_dquot_ref(struct super_block *sb, short type)
 {
        struct list_head *p;
-       struct inode *inode;
 
        if (!sb->dq_op)
                return; /* nothing to do */
@@ -669,13 +668,15 @@ restart:
        file_list_lock();
        for (p = sb->s_files.next; p != &sb->s_files; p = p->next) {
                struct file *filp = list_entry(p, struct file, f_list);
-               if (!filp->f_dentry)
-                       continue;
-               inode = filp->f_dentry->d_inode;
+               struct inode *inode = filp->f_dentry->d_inode;
                if (filp->f_mode & FMODE_WRITE && dqinit_needed(inode, type)) {
+                       struct vfsmount *mnt = mntget(file->f_vfsmnt);
+                       struct dentry *dentry = dget(file->f_dentry);
                        file_list_unlock();
                        sb->dq_op->initialize(inode, type);
                        inode->i_flags |= S_QUOTA;
+                       dput(dentry);
+                       mntput(mnt);
                        /* As we may have blocked we had better restart... */
                        goto restart;
                }
index 012b1a02319ae50b432e56a37b6cfefbf5a24c4f..33177a7f60d3db430c3f5f56cba32c4d6a91f809 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -45,6 +45,8 @@
 #include <linux/kmod.h>
 #endif
 
+int core_uses_pid;
+
 static struct linux_binfmt *formats;
 static rwlock_t binfmt_lock = RW_LOCK_UNLOCKED;
 
@@ -159,11 +161,9 @@ static int count(char ** argv, int max)
        if (argv != NULL) {
                for (;;) {
                        char * p;
-                       int error;
 
-                       error = get_user(p,argv);
-                       if (error)
-                               return error;
+                       if (get_user(p, argv))
+                               return -EFAULT;
                        if (!p)
                                break;
                        argv++;
@@ -262,7 +262,7 @@ void put_dirty_page(struct task_struct * tsk, struct page *page, unsigned long a
        pte_t * pte;
 
        if (page_count(page) != 1)
-               printk("mem_map disagrees with %p at %08lx\n", page, address);
+               printk(KERN_ERR "mem_map disagrees with %p at %08lx\n", page, address);
        pgd = pgd_offset(tsk->mm, address);
 
        spin_lock(&tsk->mm->page_table_lock);
@@ -580,9 +580,10 @@ int flush_old_exec(struct linux_binprm * bprm)
 mmap_failed:
 flush_failed:
        spin_lock_irq(&current->sigmask_lock);
-       if (current->sig != oldsig)
+       if (current->sig != oldsig) {
                kfree(current->sig);
-       current->sig = oldsig;
+               current->sig = oldsig;
+       }
        spin_unlock_irq(&current->sigmask_lock);
        return retval;
 }
@@ -924,7 +925,7 @@ void set_binfmt(struct linux_binfmt *new)
 int do_coredump(long signr, struct pt_regs * regs)
 {
        struct linux_binfmt * binfmt;
-       char corename[6+sizeof(current->comm)];
+       char corename[6+sizeof(current->comm)+10];
        struct file * file;
        struct inode * inode;
        int retval = 0;
@@ -940,11 +941,9 @@ int do_coredump(long signr, struct pt_regs * regs)
                goto fail;
 
        memcpy(corename,"core.", 5);
-#if 0
-       memcpy(corename+5,current->comm,sizeof(current->comm));
-#else
        corename[4] = '\0';
-#endif
+       if (core_uses_pid || atomic_read(&current->mm->mm_users) != 1)
+               sprintf(&corename[4], ".%d", current->pid);
        file = filp_open(corename, O_CREAT | 2 | O_NOFOLLOW, 0600);
        if (IS_ERR(file))
                goto fail;
index d49a2a960940a10b19b5a319718b4576900f9999..b76e93acc19683729c5d4a63b5ca48b6a0067593 100644 (file)
@@ -107,18 +107,17 @@ void fput(struct file * file)
                if (file->f_op && file->f_op->release)
                        file->f_op->release(inode, file);
                fops_put(file->f_op);
-               file->f_dentry = NULL;
-               file->f_vfsmnt = NULL;
                if (file->f_mode & FMODE_WRITE)
                        put_write_access(inode);
-               dput(dentry);
-               if (mnt)
-                       mntput(mnt);
                file_list_lock();
+               file->f_dentry = NULL;
+               file->f_vfsmnt = NULL;
                list_del(&file->f_list);
                list_add(&file->f_list, &free_list);
                files_stat.nr_free_files++;
                file_list_unlock();
+               dput(dentry);
+               mntput(mnt);
        }
 }
 
@@ -158,14 +157,6 @@ void file_move(struct file *file, struct list_head *list)
        file_list_unlock();
 }
 
-void file_moveto(struct file *new, struct file *old)
-{
-       file_list_lock();
-       list_del(&new->f_list);
-       list_add(&new->f_list, &old->f_list);
-       file_list_unlock();
-}
-
 int fs_may_remount_ro(struct super_block *sb)
 {
        struct list_head *p;
@@ -174,12 +165,7 @@ int fs_may_remount_ro(struct super_block *sb)
        file_list_lock();
        for (p = sb->s_files.next; p != &sb->s_files; p = p->next) {
                struct file *file = list_entry(p, struct file, f_list);
-               struct inode *inode;
-
-               if (!file->f_dentry)
-                       continue;
-
-               inode = file->f_dentry->d_inode;
+               struct inode *inode = file->f_dentry->d_inode;
 
                /* File with pending delete? */
                if (inode->i_nlink == 0)
index b5194b56125add6837b23f6ee2a3f9345da47724..167b7ee0b6c7ac698982d1ad7e24947b9d8b6372 100644 (file)
@@ -164,6 +164,11 @@ reclaimer(void *ptr)
        struct nlm_wait   *block;
        struct list_head *tmp;
 
+       reparent_to_init();
+       snprintf(current->comm, sizeof(current->comm),
+                "%s-reclaim",
+                host->h_name);
+       
        /* This one ensures that our parent doesn't terminate while the
         * reclaim is in progress */
        lock_kernel();
index 49f757e809a93555e6cf017e6e120b50b6c7457f..491a7fd5d6b2a4db39df7044fe0c19b38ef9582a 100644 (file)
 
 /* bitmap.c contains the code that handles the inode and block bitmaps */
 
-#include <linux/sched.h>
+#include <linux/fs.h>
 #include <linux/minix_fs.h>
-#include <linux/stat.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
 #include <linux/locks.h>
-#include <linux/quotaops.h>
 
 #include <asm/bitops.h>
 
@@ -68,10 +64,6 @@ void minix_free_block(struct inode * inode, int block)
                printk("trying to free block not in datazone\n");
                return;
        }
-       bh = get_hash_table(sb->s_dev,block,BLOCK_SIZE);
-       if (bh)
-               clear_bit(BH_Dirty, &bh->b_state);
-       brelse(bh);
        zone = block - sb->u.minix_sb.s_firstdatazone + 1;
        bit = zone & 8191;
        zone >>= 13;
@@ -126,60 +118,53 @@ unsigned long minix_count_free_blocks(struct super_block *sb)
                << sb->u.minix_sb.s_log_zone_size);
 }
 
-static struct buffer_head *V1_minix_clear_inode(struct inode *inode)
+struct minix_inode *
+minix_V1_raw_inode(struct super_block *sb, ino_t ino, struct buffer_head **bh)
 {
-       struct buffer_head *bh;
-       struct minix_inode *raw_inode;
-       int ino, block;
+       int block;
+       struct minix_sb_info *sbi = &sb->u.minix_sb;
+       struct minix_inode *p;
 
-       ino = inode->i_ino;
-       if (!ino || ino > inode->i_sb->u.minix_sb.s_ninodes) {
-               printk("Bad inode number on dev %s: %d is out of range\n",
-                      kdevname(inode->i_dev), ino);
+       if (!ino || ino > sbi->s_ninodes) {
+               printk("Bad inode number on dev %s: %ld is out of range\n",
+                      bdevname(sb->s_dev), ino);
                return NULL;
        }
-       block = (2 + inode->i_sb->u.minix_sb.s_imap_blocks +
-                inode->i_sb->u.minix_sb.s_zmap_blocks +
-                (ino - 1) / MINIX_INODES_PER_BLOCK);
-       bh = bread(inode->i_dev, block, BLOCK_SIZE);
-       if (!bh) {
+       ino--;
+       block = 2 + sbi->s_imap_blocks + sbi->s_zmap_blocks +
+                ino / MINIX_INODES_PER_BLOCK;
+       *bh = bread(sb->s_dev, block, BLOCK_SIZE);
+       if (!*bh) {
                printk("unable to read i-node block\n");
                return NULL;
        }
-       raw_inode = ((struct minix_inode *)bh->b_data +
-                    (ino - 1) % MINIX_INODES_PER_BLOCK);
-       raw_inode->i_nlinks = 0;
-       raw_inode->i_mode = 0;
-       mark_buffer_dirty(bh);
-       return bh;
+       p = (void *)(*bh)->b_data;
+       return p + ino % MINIX_INODES_PER_BLOCK;
 }
 
-static struct buffer_head *V2_minix_clear_inode(struct inode *inode)
+struct minix2_inode *
+minix_V2_raw_inode(struct super_block *sb, ino_t ino, struct buffer_head **bh)
 {
-       struct buffer_head *bh;
-       struct minix2_inode *raw_inode;
-       int ino, block;
+       int block;
+       struct minix_sb_info *sbi = &sb->u.minix_sb;
+       struct minix2_inode *p;
 
-       ino = inode->i_ino;
-       if (!ino || ino > inode->i_sb->u.minix_sb.s_ninodes) {
-               printk("Bad inode number on dev %s: %d is out of range\n",
-                      kdevname(inode->i_dev), ino);
+       *bh = NULL;
+       if (!ino || ino > sbi->s_ninodes) {
+               printk("Bad inode number on dev %s: %ld is out of range\n",
+                      bdevname(sb->s_dev), ino);
                return NULL;
        }
-       block = (2 + inode->i_sb->u.minix_sb.s_imap_blocks +
-                inode->i_sb->u.minix_sb.s_zmap_blocks +
-                (ino - 1) / MINIX2_INODES_PER_BLOCK);
-       bh = bread(inode->i_dev, block, BLOCK_SIZE);
-       if (!bh) {
+       ino--;
+       block = 2 + sbi->s_imap_blocks + sbi->s_zmap_blocks +
+                ino / MINIX2_INODES_PER_BLOCK;
+       *bh = bread(sb->s_dev, block, BLOCK_SIZE);
+       if (!*bh) {
                printk("unable to read i-node block\n");
                return NULL;
        }
-       raw_inode = ((struct minix2_inode *) bh->b_data +
-                    (ino - 1) % MINIX2_INODES_PER_BLOCK);
-       raw_inode->i_nlinks = 0;
-       raw_inode->i_mode = 0;
-       mark_buffer_dirty(bh);
-       return bh;
+       p = (void *)(*bh)->b_data;
+       return p + ino % MINIX2_INODES_PER_BLOCK;
 }
 
 /* Clear the link count and mode of a deleted inode on disk. */
@@ -187,11 +172,25 @@ static struct buffer_head *V2_minix_clear_inode(struct inode *inode)
 static void minix_clear_inode(struct inode *inode)
 {
        struct buffer_head *bh;
-       if (INODE_VERSION(inode) == MINIX_V1)
-               bh = V1_minix_clear_inode(inode);
-       else
-               bh = V2_minix_clear_inode(inode);
-       brelse (bh);
+       if (INODE_VERSION(inode) == MINIX_V1) {
+               struct minix_inode *raw_inode;
+               raw_inode = minix_V1_raw_inode(inode->i_sb, inode->i_ino, &bh);
+               if (raw_inode) {
+                       raw_inode->i_nlinks = 0;
+                       raw_inode->i_mode = 0;
+               }
+       } else {
+               struct minix2_inode *raw_inode;
+               raw_inode = minix_V2_raw_inode(inode->i_sb, inode->i_ino, &bh);
+               if (raw_inode) {
+                       raw_inode->i_nlinks = 0;
+                       raw_inode->i_mode = 0;
+               }
+       }
+       if (bh) {
+               mark_buffer_dirty(bh);
+               brelse (bh);
+       }
 }
 
 void minix_free_inode(struct inode * inode)
index 1cc918910db788d9521d57819f23bf34a9348779..d8b5f8469c1057ee60482b1cf1ca4da84df84f4d 100644 (file)
  *  minix directory handling functions
  */
 
-#include <linux/string.h>
-#include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/minix_fs.h>
-#include <linux/stat.h>
+#include <linux/pagemap.h>
+
+typedef struct minix_dir_entry minix_dirent;
 
 static int minix_readdir(struct file *, void *, filldir_t);
 
 struct file_operations minix_dir_operations = {
        read:           generic_read_dir,
        readdir:        minix_readdir,
-       fsync:          file_fsync,
+       fsync:          minix_sync_file,
 };
 
-static int minix_readdir(struct file * filp,
-       void * dirent, filldir_t filldir)
+static inline void dir_put_page(struct page *page)
 {
-       unsigned int offset;
-       struct buffer_head * bh;
-       struct minix_dir_entry * de;
-       struct minix_sb_info * info;
+       kunmap(page);
+       page_cache_release(page);
+}
+
+static inline unsigned long dir_pages(struct inode *inode)
+{
+       return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT;
+}
+
+static int dir_commit_chunk(struct page *page, unsigned from, unsigned to)
+{
+       struct inode *dir = (struct inode *)page->mapping->host;
+       int err = 0;
+       page->mapping->a_ops->commit_write(NULL, page, from, to);
+       if (IS_SYNC(dir))
+               err = waitfor_one_page(page);
+       return err;
+}
+
+static struct page * dir_get_page(struct inode *dir, unsigned long n)
+{
+       struct address_space *mapping = dir->i_mapping;
+       struct page *page = read_cache_page(mapping, n,
+                               (filler_t*)mapping->a_ops->readpage, NULL);
+       if (!IS_ERR(page)) {
+               wait_on_page(page);
+               kmap(page);
+               if (!Page_Uptodate(page))
+                       goto fail;
+       }
+       return page;
+
+fail:
+       dir_put_page(page);
+       return ERR_PTR(-EIO);
+}
+
+static inline void *minix_next_entry(void *de, struct minix_sb_info *sbi)
+{
+       return (void*)((char*)de + sbi->s_dirsize);
+}
+
+static int minix_readdir(struct file * filp, void * dirent, filldir_t filldir)
+{
+       unsigned long pos = filp->f_pos;
        struct inode *inode = filp->f_dentry->d_inode;
+       struct super_block *sb = inode->i_sb;
+       unsigned offset = pos & ~PAGE_CACHE_MASK;
+       unsigned long n = pos >> PAGE_CACHE_SHIFT;
+       unsigned long npages = dir_pages(inode);
+       struct minix_sb_info *sbi = &sb->u.minix_sb;
+       unsigned chunk_size = sbi->s_dirsize;
+
+       pos = (pos + chunk_size-1) & ~(chunk_size-1);
+       if (pos >= inode->i_size)
+               goto done;
+
+       for ( ; n < npages; n++, offset = 0) {
+               char *p, *kaddr, *limit;
+               struct page *page = dir_get_page(inode, n);
 
-       info = &inode->i_sb->u.minix_sb;
-       if (filp->f_pos & (info->s_dirsize - 1))
-               return -EBADF;
-       while (filp->f_pos < inode->i_size) {
-               offset = filp->f_pos & 1023;
-               bh = minix_bread(inode,(filp->f_pos)>>BLOCK_SIZE_BITS,0);
-               if (!bh) {
-                       filp->f_pos += 1024-offset;
+               if (IS_ERR(page))
                        continue;
-               }
-               do {
-                       de = (struct minix_dir_entry *) (offset + bh->b_data);
+               kaddr = (char *)page_address(page);
+               p = kaddr+offset;
+               limit = kaddr + PAGE_CACHE_SIZE - chunk_size;
+               for ( ; p <= limit ; p = minix_next_entry(p, sbi)) {
+                       minix_dirent *de = (minix_dirent *)p;
                        if (de->inode) {
-                               int size = strnlen(de->name, info->s_namelen);
-                               if (filldir(dirent, de->name, size, filp->f_pos, de->inode, DT_UNKNOWN) < 0) {
-                                       brelse(bh);
-                                       return 0;
+                               int over;
+                               unsigned l = strnlen(de->name,sbi->s_namelen);
+
+                               offset = p - kaddr;
+                               over = filldir(dirent, de->name, l,
+                                               (n<<PAGE_CACHE_SHIFT) | offset,
+                                               de->inode, DT_UNKNOWN);
+                               if (over) {
+                                       dir_put_page(page);
+                                       goto done;
                                }
                        }
-                       offset += info->s_dirsize;
-                       filp->f_pos += info->s_dirsize;
-               } while (offset < 1024 && filp->f_pos < inode->i_size);
-               brelse(bh);
+               }
+               dir_put_page(page);
        }
+
+done:
+       filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
        UPDATE_ATIME(inode);
        return 0;
 }
+
+static inline int namecompare(int len, int maxlen,
+       const char * name, const char * buffer)
+{
+       if (len < maxlen && buffer[len])
+               return 0;
+       return !memcmp(name, buffer, len);
+}
+
+/*
+ *     minix_find_entry()
+ *
+ * finds an entry in the specified directory with the wanted name. It
+ * returns the cache buffer in which the entry was found, and the entry
+ * itself (as a parameter - res_dir). It does NOT read the inode of the
+ * entry - you'll have to do that yourself if you want to.
+ */
+minix_dirent *minix_find_entry(struct dentry *dentry, struct page **res_page)
+{
+       const char * name = dentry->d_name.name;
+       int namelen = dentry->d_name.len;
+       struct inode * dir = dentry->d_parent->d_inode;
+       struct super_block * sb = dir->i_sb;
+       struct minix_sb_info * sbi = &sb->u.minix_sb;
+       unsigned long n;
+       unsigned long npages = dir_pages(dir);
+       struct page *page = NULL;
+       struct minix_dir_entry *de;
+
+       *res_page = NULL;
+
+       for (n = 0; n < npages; n++) {
+               char *kaddr;
+               page = dir_get_page(dir, n);
+               if (IS_ERR(page))
+                       continue;
+
+               kaddr = (char*)page_address(page);
+               de = (struct minix_dir_entry *) kaddr;
+               kaddr += PAGE_CACHE_SIZE - sbi->s_dirsize;
+               for ( ; (char *) de <= kaddr ; de = minix_next_entry(de,sbi)) {
+                       if (!de->inode)
+                               continue;
+                       if (namecompare(namelen,sbi->s_namelen,name,de->name))
+                               goto found;
+               }
+               dir_put_page(page);
+       }
+       return NULL;
+
+found:
+       *res_page = page;
+       return de;
+}
+
+int minix_add_link(struct dentry *dentry, struct inode *inode)
+{
+       struct inode *dir = dentry->d_parent->d_inode;
+       const char * name = dentry->d_name.name;
+       int namelen = dentry->d_name.len;
+       struct super_block * sb = dir->i_sb;
+       struct minix_sb_info * sbi = &sb->u.minix_sb;
+       struct page *page = NULL;
+       struct minix_dir_entry * de;
+       unsigned long npages = dir_pages(dir);
+       unsigned long n;
+       char *kaddr;
+       unsigned from, to;
+       int err;
+
+       /* We take care of directory expansion in the same loop */
+       for (n = 0; n <= npages; n++) {
+               page = dir_get_page(dir, n);
+               err = PTR_ERR(page);
+               if (IS_ERR(page))
+                       goto out;
+               kaddr = (char*)page_address(page);
+               de = (minix_dirent *)kaddr;
+               kaddr += PAGE_CACHE_SIZE - sbi->s_dirsize;
+               while ((char *)de <= kaddr) {
+                       if (!de->inode)
+                               goto got_it;
+                       err = -EEXIST;
+                       if (namecompare(namelen,sbi->s_namelen,name,de->name))
+                               goto out_page;
+                       de = minix_next_entry(de, sbi);
+               }
+               dir_put_page(page);
+       }
+       BUG();
+       return -EINVAL;
+
+got_it:
+       from = (char*)de - (char*)page_address(page);
+       to = from + sbi->s_dirsize;
+       lock_page(page);
+       err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
+       if (err)
+               goto out_unlock;
+       memcpy (de->name, name, namelen);
+       memset (de->name + namelen, 0, sbi->s_dirsize - namelen - 2);
+       de->inode = inode->i_ino;
+       err = dir_commit_chunk(page, from, to);
+       dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+       mark_inode_dirty(dir);
+out_unlock:
+       UnlockPage(page);
+out_page:
+       dir_put_page(page);
+out:
+       return err;
+}
+
+int minix_delete_entry(struct minix_dir_entry *de, struct page *page)
+{
+       struct address_space *mapping = page->mapping;
+       struct inode *inode = (struct inode*)mapping->host;
+       char *kaddr = (char*)page_address(page);
+       unsigned from = (char*)de - kaddr;
+       unsigned to = from + inode->i_sb->u.minix_sb.s_dirsize;
+       int err;
+
+       lock_page(page);
+       err = mapping->a_ops->prepare_write(NULL, page, from, to);
+       if (err)
+               BUG();
+       de->inode = 0;
+       err = dir_commit_chunk(page, from, to);
+       UnlockPage(page);
+       dir_put_page(page);
+       inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+       mark_inode_dirty(inode);
+       return err;
+}
+
+int minix_make_empty(struct inode *inode, struct inode *dir)
+{
+       struct address_space *mapping = inode->i_mapping;
+       struct page *page = grab_cache_page(mapping, 0);
+       struct minix_sb_info * sbi = &inode->i_sb->u.minix_sb;
+       struct minix_dir_entry * de;
+       char *base;
+       int err;
+
+       if (!page)
+               return -ENOMEM;
+       err = mapping->a_ops->prepare_write(NULL, page, 0, 2 * sbi->s_dirsize);
+       if (err)
+               goto fail;
+
+       base = (char*)page_address(page);
+       memset(base, 0, PAGE_CACHE_SIZE);
+
+       de = (struct minix_dir_entry *) base;
+       de->inode = inode->i_ino;
+       strcpy(de->name,".");
+       de = minix_next_entry(de, sbi);
+       de->inode = dir->i_ino;
+       strcpy(de->name,"..");
+
+       err = dir_commit_chunk(page, 0, 2 * sbi->s_dirsize);
+fail:
+       UnlockPage(page);
+       page_cache_release(page);
+       return err;
+}
+
+/*
+ * routine to check that the specified directory is empty (for rmdir)
+ */
+int minix_empty_dir(struct inode * inode)
+{
+       struct page *page = NULL;
+       unsigned long i, npages = dir_pages(inode);
+       struct minix_sb_info *sbi = &inode->i_sb->u.minix_sb;
+
+       for (i = 0; i < npages; i++) {
+               char *kaddr;
+               minix_dirent * de;
+               page = dir_get_page(inode, i);
+
+               if (IS_ERR(page))
+                       continue;
+
+               kaddr = (char *)page_address(page);
+               de = (minix_dirent *)kaddr;
+               kaddr += PAGE_CACHE_SIZE - sbi->s_dirsize;
+
+               while ((char *)de <= kaddr) {
+                       if (de->inode != 0) {
+                               /* check for . and .. */
+                               if (de->name[0] != '.')
+                                       goto not_empty;
+                               if (!de->name[1]) {
+                                       if (de->inode != inode->i_ino)
+                                               goto not_empty;
+                               } else if (de->name[1] != '.')
+                                       goto not_empty;
+                               else if (de->name[2])
+                                       goto not_empty;
+                       }
+                       de = minix_next_entry(de, sbi);
+               }
+               dir_put_page(page);
+       }
+       return 1;
+
+not_empty:
+       dir_put_page(page);
+       return 0;
+}
+
+/* Releases the page */
+void minix_set_link(struct minix_dir_entry *de, struct page *page,
+       struct inode *inode)
+{
+       struct inode *dir = (struct inode*)page->mapping->host;
+       struct minix_sb_info *sbi = &dir->i_sb->u.minix_sb;
+       unsigned from = (char *)de-(char*)page_address(page);
+       unsigned to = from + sbi->s_dirsize;
+       int err;
+
+       lock_page(page);
+       err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
+       if (err)
+               BUG();
+       de->inode = inode->i_ino;
+       err = dir_commit_chunk(page, from, to);
+       UnlockPage(page);
+       dir_put_page(page);
+       dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+       mark_inode_dirty(dir);
+}
+
+struct minix_dir_entry * minix_dotdot (struct inode *dir, struct page **p)
+{
+       struct page *page = dir_get_page(dir, 0);
+       struct minix_sb_info *sbi = &dir->i_sb->u.minix_sb;
+       struct minix_dir_entry *de = NULL;
+
+       if (!IS_ERR(page)) {
+               de = minix_next_entry(page_address(page), sbi);
+               *p = page;
+       }
+       return de;
+}
+
+ino_t minix_inode_by_name(struct dentry *dentry)
+{
+       struct page *page;
+       struct minix_dir_entry *de = minix_find_entry(dentry, &page);
+       ino_t res = 0;
+
+       if (de) {
+               res = de->inode;
+               dir_put_page(page);
+       }
+       return res;
+}
index 63534d4bc5a1d5a55b5f60083170a22e2b3a63f9..593c0f0b6f1a424171d7ba6537f73566201cfd4a 100644 (file)
@@ -13,7 +13,7 @@
  * We have mostly NULLs here: the current defaults are OK for
  * the minix filesystem.
  */
-static int minix_sync_file(struct file *, struct dentry *, int);
+int minix_sync_file(struct file *, struct dentry *, int);
 
 struct file_operations minix_file_operations = {
        read:           generic_file_read,
@@ -26,14 +26,16 @@ struct inode_operations minix_file_inode_operations = {
        truncate:       minix_truncate,
 };
 
-static int minix_sync_file(struct file * file,
-                          struct dentry *dentry,
-                          int datasync)
+int minix_sync_file(struct file * file, struct dentry *dentry, int datasync)
 {
        struct inode *inode = dentry->d_inode;
+       int err  = fsync_inode_buffers(inode);
 
-       if (INODE_VERSION(inode) == MINIX_V1)
-               return V1_minix_sync_file(inode);
-       else
-               return V2_minix_sync_file(inode);
+       if (!(inode->i_state & I_DIRTY))
+               return err;
+       if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
+               return err;
+       
+       err |= minix_sync_inode(inode);
+       return err ? -EIO : 0;
 }
index ec8b2e4b6af8cc07c5e12a87d5abae84d400b54a..7530c2955d40b7bb5fbf569387f227c2f7c6faf8 100644 (file)
 
 #include <linux/module.h>
 
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/minix_fs.h>
 #include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/stat.h>
 #include <linux/locks.h>
 #include <linux/init.h>
 #include <linux/smp_lock.h>
 #include <linux/highuid.h>
 #include <linux/blkdev.h>
 
-#include <asm/system.h>
-#include <asm/bitops.h>
-
-#include <linux/minix_fs.h>
-
 static void minix_read_inode(struct inode * inode);
 static void minix_write_inode(struct inode * inode, int wait);
 static int minix_statfs(struct super_block *sb, struct statfs *buf);
@@ -127,48 +119,6 @@ static int minix_remount (struct super_block * sb, int * flags, char * data)
        return 0;
 }
 
-/*
- * Check the root directory of the filesystem to make sure
- * it really _is_ a Minix filesystem, and to check the size
- * of the directory entry.
- */
-static const char * minix_checkroot(struct super_block *s, struct inode *dir)
-{
-       struct buffer_head *bh;
-       struct minix_dir_entry *de;
-       const char * errmsg;
-       int dirsize;
-
-       if (!S_ISDIR(dir->i_mode))
-               return "root directory is not a directory";
-
-       bh = minix_bread(dir, 0, 0);
-       if (!bh)
-               return "unable to read root directory";
-
-       de = (struct minix_dir_entry *) bh->b_data;
-       errmsg = "bad root directory '.' entry";
-       dirsize = BLOCK_SIZE;
-       if (de->inode == MINIX_ROOT_INO && strcmp(de->name, ".") == 0) {
-               errmsg = "bad root directory '..' entry";
-               dirsize = 8;
-       }
-
-       while ((dirsize <<= 1) < BLOCK_SIZE) {
-               de = (struct minix_dir_entry *) (bh->b_data + dirsize);
-               if (de->inode != MINIX_ROOT_INO)
-                       continue;
-               if (strcmp(de->name, ".."))
-                       continue;
-               s->u.minix_sb.s_dirsize = dirsize;
-               s->u.minix_sb.s_namelen = dirsize - 2;
-               errmsg = NULL;
-               break;
-       }
-       brelse(bh);
-       return errmsg;
-}
-
 static struct super_block *minix_read_super(struct super_block *s, void *data,
                                     int silent)
 {
@@ -177,9 +127,9 @@ static struct super_block *minix_read_super(struct super_block *s, void *data,
        struct minix_super_block *ms;
        int i, block;
        kdev_t dev = s->s_dev;
-       const char * errmsg;
        struct inode *root_inode;
        unsigned int hblock;
+       struct minix_sb_info *sbi = &s->u.minix_sb;
 
        /* N.B. These should be compile-time tests.
           Unfortunately that is impossible. */
@@ -197,104 +147,96 @@ static struct super_block *minix_read_super(struct super_block *s, void *data,
                goto out_bad_sb;
 
        ms = (struct minix_super_block *) bh->b_data;
-       s->u.minix_sb.s_ms = ms;
-       s->u.minix_sb.s_sbh = bh;
-       s->u.minix_sb.s_mount_state = ms->s_state;
+       sbi->s_ms = ms;
+       sbi->s_sbh = bh;
+       sbi->s_mount_state = ms->s_state;
        s->s_blocksize = BLOCK_SIZE;
        s->s_blocksize_bits = BLOCK_SIZE_BITS;
-       s->u.minix_sb.s_ninodes = ms->s_ninodes;
-       s->u.minix_sb.s_nzones = ms->s_nzones;
-       s->u.minix_sb.s_imap_blocks = ms->s_imap_blocks;
-       s->u.minix_sb.s_zmap_blocks = ms->s_zmap_blocks;
-       s->u.minix_sb.s_firstdatazone = ms->s_firstdatazone;
-       s->u.minix_sb.s_log_zone_size = ms->s_log_zone_size;
-       s->u.minix_sb.s_max_size = ms->s_max_size;
+       sbi->s_ninodes = ms->s_ninodes;
+       sbi->s_nzones = ms->s_nzones;
+       sbi->s_imap_blocks = ms->s_imap_blocks;
+       sbi->s_zmap_blocks = ms->s_zmap_blocks;
+       sbi->s_firstdatazone = ms->s_firstdatazone;
+       sbi->s_log_zone_size = ms->s_log_zone_size;
+       sbi->s_max_size = ms->s_max_size;
        s->s_magic = ms->s_magic;
        if (s->s_magic == MINIX_SUPER_MAGIC) {
-               s->u.minix_sb.s_version = MINIX_V1;
-               s->u.minix_sb.s_dirsize = 16;
-               s->u.minix_sb.s_namelen = 14;
-               s->u.minix_sb.s_link_max = MINIX_LINK_MAX;
+               sbi->s_version = MINIX_V1;
+               sbi->s_dirsize = 16;
+               sbi->s_namelen = 14;
+               sbi->s_link_max = MINIX_LINK_MAX;
        } else if (s->s_magic == MINIX_SUPER_MAGIC2) {
-               s->u.minix_sb.s_version = MINIX_V1;
-               s->u.minix_sb.s_dirsize = 32;
-               s->u.minix_sb.s_namelen = 30;
-               s->u.minix_sb.s_link_max = MINIX_LINK_MAX;
+               sbi->s_version = MINIX_V1;
+               sbi->s_dirsize = 32;
+               sbi->s_namelen = 30;
+               sbi->s_link_max = MINIX_LINK_MAX;
        } else if (s->s_magic == MINIX2_SUPER_MAGIC) {
-               s->u.minix_sb.s_version = MINIX_V2;
-               s->u.minix_sb.s_nzones = ms->s_zones;
-               s->u.minix_sb.s_dirsize = 16;
-               s->u.minix_sb.s_namelen = 14;
-               s->u.minix_sb.s_link_max = MINIX2_LINK_MAX;
+               sbi->s_version = MINIX_V2;
+               sbi->s_nzones = ms->s_zones;
+               sbi->s_dirsize = 16;
+               sbi->s_namelen = 14;
+               sbi->s_link_max = MINIX2_LINK_MAX;
        } else if (s->s_magic == MINIX2_SUPER_MAGIC2) {
-               s->u.minix_sb.s_version = MINIX_V2;
-               s->u.minix_sb.s_nzones = ms->s_zones;
-               s->u.minix_sb.s_dirsize = 32;
-               s->u.minix_sb.s_namelen = 30;
-               s->u.minix_sb.s_link_max = MINIX2_LINK_MAX;
+               sbi->s_version = MINIX_V2;
+               sbi->s_nzones = ms->s_zones;
+               sbi->s_dirsize = 32;
+               sbi->s_namelen = 30;
+               sbi->s_link_max = MINIX2_LINK_MAX;
        } else
                goto out_no_fs;
 
        /*
         * Allocate the buffer map to keep the superblock small.
         */
-       i = (s->u.minix_sb.s_imap_blocks + s->u.minix_sb.s_zmap_blocks) * sizeof(bh);
+       i = (sbi->s_imap_blocks + sbi->s_zmap_blocks) * sizeof(bh);
        map = kmalloc(i, GFP_KERNEL);
        if (!map)
                goto out_no_map;
        memset(map, 0, i);
-       s->u.minix_sb.s_imap = &map[0];
-       s->u.minix_sb.s_zmap = &map[s->u.minix_sb.s_imap_blocks];
+       sbi->s_imap = &map[0];
+       sbi->s_zmap = &map[sbi->s_imap_blocks];
 
        block=2;
-       for (i=0 ; i < s->u.minix_sb.s_imap_blocks ; i++) {
-               if (!(s->u.minix_sb.s_imap[i]=bread(dev,block,BLOCK_SIZE)))
+       for (i=0 ; i < sbi->s_imap_blocks ; i++) {
+               if (!(sbi->s_imap[i]=bread(dev,block,BLOCK_SIZE)))
                        goto out_no_bitmap;
                block++;
        }
-       for (i=0 ; i < s->u.minix_sb.s_zmap_blocks ; i++) {
-               if (!(s->u.minix_sb.s_zmap[i]=bread(dev,block,BLOCK_SIZE)))
+       for (i=0 ; i < sbi->s_zmap_blocks ; i++) {
+               if (!(sbi->s_zmap[i]=bread(dev,block,BLOCK_SIZE)))
                        goto out_no_bitmap;
                block++;
        }
 
-       minix_set_bit(0,s->u.minix_sb.s_imap[0]->b_data);
-       minix_set_bit(0,s->u.minix_sb.s_zmap[0]->b_data);
+       minix_set_bit(0,sbi->s_imap[0]->b_data);
+       minix_set_bit(0,sbi->s_zmap[0]->b_data);
 
        /* set up enough so that it can read an inode */
        s->s_op = &minix_sops;
        root_inode = iget(s, MINIX_ROOT_INO);
        if (!root_inode)
                goto out_no_root;
-       /*
-        * Check the fs before we get the root dentry ...
-        */
-       errmsg = minix_checkroot(s, root_inode);
-       if (errmsg)
-               goto out_bad_root;
 
        s->s_root = d_alloc_root(root_inode);
        if (!s->s_root)
                goto out_iput;
 
-       s->s_root->d_op = &minix_dentry_operations;
+       if (!NO_TRUNCATE)
+               s->s_root->d_op = &minix_dentry_operations;
 
        if (!(s->s_flags & MS_RDONLY)) {
                ms->s_state &= ~MINIX_VALID_FS;
                mark_buffer_dirty(bh);
                s->s_dirt = 1;
        }
-       if (!(s->u.minix_sb.s_mount_state & MINIX_VALID_FS))
+       if (!(sbi->s_mount_state & MINIX_VALID_FS))
                printk ("MINIX-fs: mounting unchecked file system, "
                        "running fsck is recommended.\n");
-       else if (s->u.minix_sb.s_mount_state & MINIX_ERROR_FS)
+       else if (sbi->s_mount_state & MINIX_ERROR_FS)
                printk ("MINIX-fs: mounting file system with errors, "
                        "running fsck is recommended.\n");
        return s;
 
-out_bad_root:
-       if (!silent)
-               printk("MINIX-fs: %s\n", errmsg);
 out_iput:
        iput(root_inode);
        goto out_freemap;
@@ -307,11 +249,11 @@ out_no_root:
 out_no_bitmap:
        printk("MINIX-fs: bad superblock or unable to read bitmaps\n");
     out_freemap:
-       for (i = 0; i < s->u.minix_sb.s_imap_blocks; i++)
-               brelse(s->u.minix_sb.s_imap[i]);
-       for (i = 0; i < s->u.minix_sb.s_zmap_blocks; i++)
-               brelse(s->u.minix_sb.s_zmap[i]);
-       kfree(s->u.minix_sb.s_imap);
+       for (i = 0; i < sbi->s_imap_blocks; i++)
+               brelse(sbi->s_imap[i]);
+       for (i = 0; i < sbi->s_zmap_blocks; i++)
+               brelse(sbi->s_zmap[i]);
+       kfree(sbi->s_imap);
        goto out_release;
 
 out_no_map:
@@ -359,45 +301,6 @@ static int minix_get_block(struct inode *inode, long block,
                return V2_minix_get_block(inode, block, bh_result, create);
 }
 
-/*
- * the global minix fs getblk function.
- */
-struct buffer_head *minix_getblk(struct inode *inode, int block, int create)
-{
-       struct buffer_head dummy;
-       int error;
-
-       dummy.b_state = 0;
-       dummy.b_blocknr = -1000;
-       error = minix_get_block(inode, block, &dummy, create);
-       if (!error && buffer_mapped(&dummy)) {
-               struct buffer_head *bh;
-               bh = getblk(dummy.b_dev, dummy.b_blocknr, BLOCK_SIZE);
-               if (buffer_new(&dummy)) {
-                       memset(bh->b_data, 0, BLOCK_SIZE);
-                       mark_buffer_uptodate(bh, 1);
-                       mark_buffer_dirty(bh);
-               }
-               return bh;
-       }
-       return NULL;
-}
-
-struct buffer_head * minix_bread(struct inode * inode, int block, int create)
-{
-       struct buffer_head * bh;
-
-       bh = minix_getblk(inode, block, create);
-       if (!bh || buffer_uptodate(bh))
-               return bh;
-       ll_rw_block(READ, 1, &bh);
-       wait_on_buffer(bh);
-       if (buffer_uptodate(bh))
-               return bh;
-       brelse(bh);
-       return NULL;
-}
-
 static int minix_writepage(struct page *page)
 {
        return block_write_full_page(page,minix_get_block);
@@ -414,7 +317,7 @@ static int minix_bmap(struct address_space *mapping, long block)
 {
        return generic_block_bmap(mapping,block,minix_get_block);
 }
-struct address_space_operations minix_aops = {
+static struct address_space_operations minix_aops = {
        readpage: minix_readpage,
        writepage: minix_writepage,
        sync_page: block_sync_page,
@@ -423,6 +326,23 @@ struct address_space_operations minix_aops = {
        bmap: minix_bmap
 };
 
+void minix_set_inode(struct inode *inode, dev_t rdev)
+{
+       if (S_ISREG(inode->i_mode)) {
+               inode->i_op = &minix_file_inode_operations;
+               inode->i_fop = &minix_file_operations;
+               inode->i_mapping->a_ops = &minix_aops;
+       } else if (S_ISDIR(inode->i_mode)) {
+               inode->i_op = &minix_dir_inode_operations;
+               inode->i_fop = &minix_dir_operations;
+               inode->i_mapping->a_ops = &minix_aops;
+       } else if (S_ISLNK(inode->i_mode)) {
+               inode->i_op = &page_symlink_inode_operations;
+               inode->i_mapping->a_ops = &minix_aops;
+       } else
+               init_special_inode(inode, inode->i_mode, rdev);
+}
+
 /*
  * The minix V1 function to read an inode.
  */
@@ -430,26 +350,11 @@ static void V1_minix_read_inode(struct inode * inode)
 {
        struct buffer_head * bh;
        struct minix_inode * raw_inode;
-       int block, ino;
-
-       ino = inode->i_ino;
-       inode->i_mode = 0;
-       if (!ino || ino > inode->i_sb->u.minix_sb.s_ninodes) {
-               printk("Bad inode number on dev %s"
-                      ": %d is out of range\n",
-                       kdevname(inode->i_dev), ino);
-               return;
-       }
-       block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks +
-                   inode->i_sb->u.minix_sb.s_zmap_blocks +
-                   (ino-1)/MINIX_INODES_PER_BLOCK;
-       if (!(bh=bread(inode->i_dev,block, BLOCK_SIZE))) {
-               printk("Major problem: unable to read inode from dev "
-                      "%s\n", kdevname(inode->i_dev));
+       int i;
+
+       raw_inode = minix_V1_raw_inode(inode->i_sb, inode->i_ino, &bh);
+       if (!raw_inode)
                return;
-       }
-       raw_inode = ((struct minix_inode *) bh->b_data) +
-                   (ino-1)%MINIX_INODES_PER_BLOCK;
        inode->i_mode = raw_inode->i_mode;
        inode->i_uid = (uid_t)raw_inode->i_uid;
        inode->i_gid = (gid_t)raw_inode->i_gid;
@@ -457,20 +362,9 @@ static void V1_minix_read_inode(struct inode * inode)
        inode->i_size = raw_inode->i_size;
        inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time;
        inode->i_blocks = inode->i_blksize = 0;
-       for (block = 0; block < 9; block++)
-               inode->u.minix_i.u.i1_data[block] = raw_inode->i_zone[block];
-       if (S_ISREG(inode->i_mode)) {
-               inode->i_op = &minix_file_inode_operations;
-               inode->i_fop = &minix_file_operations;
-               inode->i_mapping->a_ops = &minix_aops;
-       } else if (S_ISDIR(inode->i_mode)) {
-               inode->i_op = &minix_dir_inode_operations;
-               inode->i_fop = &minix_dir_operations;
-       } else if (S_ISLNK(inode->i_mode)) {
-               inode->i_op = &page_symlink_inode_operations;
-               inode->i_mapping->a_ops = &minix_aops;
-       } else
-               init_special_inode(inode, inode->i_mode, raw_inode->i_zone[0]);
+       for (i = 0; i < 9; i++)
+               inode->u.minix_i.u.i1_data[i] = raw_inode->i_zone[i];
+       minix_set_inode(inode, raw_inode->i_zone[0]);
        brelse(bh);
 }
 
@@ -481,26 +375,11 @@ static void V2_minix_read_inode(struct inode * inode)
 {
        struct buffer_head * bh;
        struct minix2_inode * raw_inode;
-       int block, ino;
-
-       ino = inode->i_ino;
-       inode->i_mode = 0;
-       if (!ino || ino > inode->i_sb->u.minix_sb.s_ninodes) {
-               printk("Bad inode number on dev %s"
-                      ": %d is out of range\n",
-                       kdevname(inode->i_dev), ino);
-               return;
-       }
-       block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks +
-                   inode->i_sb->u.minix_sb.s_zmap_blocks +
-                   (ino-1)/MINIX2_INODES_PER_BLOCK;
-       if (!(bh=bread(inode->i_dev,block, BLOCK_SIZE))) {
-               printk("Major problem: unable to read inode from dev "
-                      "%s\n", kdevname(inode->i_dev));
+       int i;
+
+       raw_inode = minix_V2_raw_inode(inode->i_sb, inode->i_ino, &bh);
+       if (!raw_inode)
                return;
-       }
-       raw_inode = ((struct minix2_inode *) bh->b_data) +
-                   (ino-1)%MINIX2_INODES_PER_BLOCK;
        inode->i_mode = raw_inode->i_mode;
        inode->i_uid = (uid_t)raw_inode->i_uid;
        inode->i_gid = (gid_t)raw_inode->i_gid;
@@ -510,20 +389,9 @@ static void V2_minix_read_inode(struct inode * inode)
        inode->i_atime = raw_inode->i_atime;
        inode->i_ctime = raw_inode->i_ctime;
        inode->i_blocks = inode->i_blksize = 0;
-       for (block = 0; block < 10; block++)
-               inode->u.minix_i.u.i2_data[block] = raw_inode->i_zone[block];
-       if (S_ISREG(inode->i_mode)) {
-               inode->i_op = &minix_file_inode_operations;
-               inode->i_fop = &minix_file_operations;
-               inode->i_mapping->a_ops = &minix_aops;
-       } else if (S_ISDIR(inode->i_mode)) {
-               inode->i_op = &minix_dir_inode_operations;
-               inode->i_fop = &minix_dir_operations;
-       } else if (S_ISLNK(inode->i_mode)) {
-               inode->i_op = &page_symlink_inode_operations;
-               inode->i_mapping->a_ops = &minix_aops;
-       } else
-               init_special_inode(inode, inode->i_mode, raw_inode->i_zone[0]);
+       for (i = 0; i < 10; i++)
+               inode->u.minix_i.u.i2_data[i] = raw_inode->i_zone[i];
+       minix_set_inode(inode, raw_inode->i_zone[0]);
        brelse(bh);
 }
 
@@ -545,23 +413,11 @@ static struct buffer_head * V1_minix_update_inode(struct inode * inode)
 {
        struct buffer_head * bh;
        struct minix_inode * raw_inode;
-       int ino, block;
+       int i;
 
-       ino = inode->i_ino;
-       if (!ino || ino > inode->i_sb->u.minix_sb.s_ninodes) {
-               printk("Bad inode number on dev %s"
-                      ": %d is out of range\n",
-                       kdevname(inode->i_dev), ino);
-               return 0;
-       }
-       block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks + inode->i_sb->u.minix_sb.s_zmap_blocks +
-               (ino-1)/MINIX_INODES_PER_BLOCK;
-       if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE))) {
-               printk("unable to read i-node block\n");
+       raw_inode = minix_V1_raw_inode(inode->i_sb, inode->i_ino, &bh);
+       if (!raw_inode)
                return 0;
-       }
-       raw_inode = ((struct minix_inode *)bh->b_data) +
-               (ino-1)%MINIX_INODES_PER_BLOCK;
        raw_inode->i_mode = inode->i_mode;
        raw_inode->i_uid = fs_high2lowuid(inode->i_uid);
        raw_inode->i_gid = fs_high2lowgid(inode->i_gid);
@@ -570,8 +426,8 @@ static struct buffer_head * V1_minix_update_inode(struct inode * inode)
        raw_inode->i_time = inode->i_mtime;
        if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
                raw_inode->i_zone[0] = kdev_t_to_nr(inode->i_rdev);
-       else for (block = 0; block < 9; block++)
-               raw_inode->i_zone[block] = inode->u.minix_i.u.i1_data[block];
+       else for (i = 0; i < 9; i++)
+               raw_inode->i_zone[i] = inode->u.minix_i.u.i1_data[i];
        mark_buffer_dirty(bh);
        return bh;
 }
@@ -583,23 +439,11 @@ static struct buffer_head * V2_minix_update_inode(struct inode * inode)
 {
        struct buffer_head * bh;
        struct minix2_inode * raw_inode;
-       int ino, block;
+       int i;
 
-       ino = inode->i_ino;
-       if (!ino || ino > inode->i_sb->u.minix_sb.s_ninodes) {
-               printk("Bad inode number on dev %s"
-                      ": %d is out of range\n",
-                       kdevname(inode->i_dev), ino);
+       raw_inode = minix_V2_raw_inode(inode->i_sb, inode->i_ino, &bh);
+       if (!raw_inode)
                return 0;
-       }
-       block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks + inode->i_sb->u.minix_sb.s_zmap_blocks +
-               (ino-1)/MINIX2_INODES_PER_BLOCK;
-       if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE))) {
-               printk("unable to read i-node block\n");
-               return 0;
-       }
-       raw_inode = ((struct minix2_inode *)bh->b_data) +
-               (ino-1)%MINIX2_INODES_PER_BLOCK;
        raw_inode->i_mode = inode->i_mode;
        raw_inode->i_uid = fs_high2lowuid(inode->i_uid);
        raw_inode->i_gid = fs_high2lowgid(inode->i_gid);
@@ -610,8 +454,8 @@ static struct buffer_head * V2_minix_update_inode(struct inode * inode)
        raw_inode->i_ctime = inode->i_ctime;
        if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
                raw_inode->i_zone[0] = kdev_t_to_nr(inode->i_rdev);
-       else for (block = 0; block < 10; block++)
-               raw_inode->i_zone[block] = inode->u.minix_i.u.i2_data[block];
+       else for (i = 0; i < 10; i++)
+               raw_inode->i_zone[i] = inode->u.minix_i.u.i2_data[i];
        mark_buffer_dirty(bh);
        return bh;
 }
index 9af34f1c879e4715069febefadf32d4f42659926..061aad0e835995853bc09364482850cc21129e3a 100644 (file)
@@ -87,7 +87,7 @@ static int alloc_branch(struct inode *inode,
                *branch[n].p = branch[n].key;
                mark_buffer_uptodate(bh, 1);
                unlock_buffer(bh);
-               mark_buffer_dirty(bh);
+               mark_buffer_dirty_inode(bh, inode);
                parent = nr;
        }
        if (n == num)
@@ -127,7 +127,7 @@ static inline int splice_branch(struct inode *inode,
 
        /* had we spliced it onto indirect block? */
        if (where->bh)
-               mark_buffer_dirty(where->bh);
+               mark_buffer_dirty_inode(where->bh, inode);
 
        mark_inode_dirty(inode);
        return 0;
@@ -320,14 +320,14 @@ static inline void truncate (struct inode * inode)
                if (partial == chain)
                        mark_inode_dirty(inode);
                else
-                       mark_buffer_dirty(partial->bh);
+                       mark_buffer_dirty_inode(partial->bh, inode);
                free_branches(inode, &nr, &nr+1, (chain+n-1) - partial);
        }
        /* Clear the ends of indirect blocks on the shared branch */
        while (partial > chain) {
                free_branches(inode, partial->p + 1, block_end(partial->bh),
                                (chain+n-1) - partial);
-               mark_buffer_dirty(partial->bh);
+               mark_buffer_dirty_inode(partial->bh, inode);
                brelse (partial->bh);
                partial--;
        }
@@ -345,73 +345,3 @@ do_indirects:
        inode->i_mtime = inode->i_ctime = CURRENT_TIME;
        mark_inode_dirty(inode);
 }
-
-static int sync_block (struct inode * inode, block_t block, int wait)
-{
-       struct buffer_head * bh;
-       
-       if (!block)
-               return 0;
-       bh = get_hash_table(inode->i_dev, block_to_cpu(block), BLOCK_SIZE);
-       if (!bh)
-               return 0;
-       if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
-               brelse(bh);
-               return -1;
-       }
-       if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh))
-       {
-               brelse(bh);
-               return 0;
-       }
-       ll_rw_block(WRITE, 1, &bh);
-       atomic_dec(&bh->b_count);
-       return 0;
-}
-
-static int sync_indirect(struct inode *inode, block_t iblock, int depth,
-                        int wait)
-{
-       struct buffer_head * ind_bh = NULL;
-       int rc, err = 0;
-
-       if (!iblock)
-               return 0;
-
-       rc = sync_block (inode, iblock, wait);
-       if (rc)
-               return rc;
-
-       ind_bh = bread(inode->i_dev, block_to_cpu(iblock), BLOCK_SIZE);
-       if (!ind_bh)
-               return -1;
-
-       if (--depth) {
-               block_t *p = (block_t*)ind_bh->b_data;
-               block_t *end = block_end(ind_bh);
-               while (p < end) {
-                       rc = sync_indirect (inode, *p++, depth, wait);
-                       if (rc > 0)
-                               break;
-                       if (rc)
-                               err = rc;
-               }
-       }
-       brelse(ind_bh);
-       return err;
-}
-
-static inline int sync_file(struct inode * inode)
-{
-       int wait, err = 0, i;
-       block_t *idata = i_data(inode);
-       
-       lock_kernel();
-       err = generic_buffer_fdatasync(inode, 0, ~0UL);
-       for (wait=0; wait<=1; wait++)
-               for (i=1; i<DEPTH; i++)
-                       err |= sync_indirect(inode, idata[DIRECT+i-1], i, wait);
-       err |= minix_sync_inode (inode);
-       unlock_kernel();
-       return (err < 0) ? -EIO : 0;
-}
index 47aee63e1c3c3c29ffb3c6ef1a67dd550c854411..990dddd0d73e25d153ba0595d1611c83d2a33dc5 100644 (file)
@@ -1,6 +1,6 @@
-#include <linux/sched.h>
-#include <linux/locks.h>
+#include <linux/fs.h>
 #include <linux/minix_fs.h>
+#include <linux/locks.h>
 #include <linux/smp_lock.h>
 
 enum {DEPTH = 3, DIRECT = 7};  /* Only double indirect */
@@ -56,8 +56,3 @@ void V1_minix_truncate(struct inode * inode)
 {
        truncate(inode);
 }
-
-int V1_minix_sync_file(struct inode * inode)
-{
-       return sync_file(inode);
-}
index 333d5f7850d51cc940de0dd136e3739059f4248f..bbff60d850fc8c04621fc71cf8e41543a369cbf9 100644 (file)
@@ -1,6 +1,6 @@
-#include <linux/sched.h>
-#include <linux/locks.h>
+#include <linux/fs.h>
 #include <linux/minix_fs.h>
+#include <linux/locks.h>
 #include <linux/smp_lock.h>
 
 enum {DIRECT = 7, DEPTH = 4};  /* Have triple indirect */
@@ -61,8 +61,3 @@ void V2_minix_truncate(struct inode * inode)
 {
        truncate(inode);
 }
-
-int V2_minix_sync_file(struct inode * inode)
-{
-       return sync_file(inode);
-}
index eadbb79e388296305d65c4986455673df2fa24ce..c0e9ea190812e50737afb6b0a3d91159ddb65f64 100644 (file)
@@ -4,85 +4,34 @@
  *  Copyright (C) 1991, 1992  Linus Torvalds
  */
 
-#include <linux/sched.h>
+#include <linux/fs.h>
 #include <linux/minix_fs.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/stat.h>
-#include <linux/fcntl.h>
-#include <linux/errno.h>
-#include <linux/quotaops.h>
+#include <linux/pagemap.h>
 
-#include <asm/uaccess.h>
-
-/*
- * comment out this line if you want names > info->s_namelen chars to be
- * truncated. Else they will be disallowed (ENAMETOOLONG).
- */
-/* #define NO_TRUNCATE */
+static inline void inc_count(struct inode *inode)
+{
+       inode->i_nlink++;
+       mark_inode_dirty(inode);
+}
 
-static inline int namecompare(int len, int maxlen,
-       const char * name, const char * buffer)
+static inline void dec_count(struct inode *inode)
 {
-       if (len < maxlen && buffer[len])
-               return 0;
-       return !memcmp(name, buffer, len);
+       inode->i_nlink--;
+       mark_inode_dirty(inode);
 }
 
-/*
- *     minix_find_entry()
- *
- * finds an entry in the specified directory with the wanted name. It
- * returns the cache buffer in which the entry was found, and the entry
- * itself (as a parameter - res_dir). It does NOT read the inode of the
- * entry - you'll have to do that yourself if you want to.
- */
-static struct buffer_head * minix_find_entry(struct inode * dir,
-       const char * name, int namelen, struct minix_dir_entry ** res_dir)
+static int add_nondir(struct dentry *dentry, struct inode *inode)
 {
-       unsigned long block, offset;
-       struct buffer_head * bh;
-       struct minix_sb_info * info;
-       struct minix_dir_entry *de;
-
-       *res_dir = NULL;
-       info = &dir->i_sb->u.minix_sb;
-       if (namelen > info->s_namelen) {
-#ifdef NO_TRUNCATE
-               return NULL;
-#else
-               namelen = info->s_namelen;
-#endif
-       }
-       bh = NULL;
-       block = offset = 0;
-       while (block*BLOCK_SIZE+offset < dir->i_size) {
-               if (!bh) {
-                       bh = minix_bread(dir,block,0);
-                       if (!bh) {
-                               block++;
-                               continue;
-                       }
-               }
-               de = (struct minix_dir_entry *) (bh->b_data + offset);
-               offset += info->s_dirsize;
-               if (de->inode && namecompare(namelen,info->s_namelen,name,de->name)) {
-                       *res_dir = de;
-                       return bh;
-               }
-               if (offset < bh->b_size)
-                       continue;
-               brelse(bh);
-               bh = NULL;
-               offset = 0;
-               block++;
+       int err = minix_add_link(dentry, inode);
+       if (!err) {
+               d_instantiate(dentry, inode);
+               return 0;
        }
-       brelse(bh);
-       return NULL;
+       dec_count(inode);
+       iput(inode);
+       return err;
 }
 
-#ifndef NO_TRUNCATE
-
 static int minix_hash(struct dentry *dentry, struct qstr *qstr)
 {
        unsigned long hash;
@@ -103,27 +52,22 @@ static int minix_hash(struct dentry *dentry, struct qstr *qstr)
        return 0;
 }
 
-#endif
-
 struct dentry_operations minix_dentry_operations = {
-#ifndef NO_TRUNCATE
        d_hash:         minix_hash,
-#endif
 };
 
 static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry)
 {
        struct inode * inode = NULL;
-       struct minix_dir_entry * de;
-       struct buffer_head * bh;
-
-#ifndef NO_TRUNCATE
-       dentry->d_op = &minix_dentry_operations;
-#endif
-       bh = minix_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de);
-       if (bh) {
-               int ino = de->inode;
-               brelse (bh);
+       ino_t ino;
+
+       dentry->d_op = dir->i_sb->s_root->d_op;
+
+       if (dentry->d_name.len > dir->i_sb->u.minix_sb.s_namelen)
+               return ERR_PTR(-ENAMETOOLONG);
+
+       ino = minix_inode_by_name(dentry);
+       if (ino) {
                inode = iget(dir->i_sb, ino);
  
                if (!inode)
@@ -133,481 +77,226 @@ static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry)
        return NULL;
 }
 
-/*
- *     minix_add_entry()
- *
- * adds a file entry to the specified directory, returning a possible
- * error value if it fails.
- *
- * NOTE!! The inode part of 'de' is left at 0 - which means you
- * may not sleep between calling this and putting something into
- * the entry, as someone else might have used it while you slept.
- */
-static int minix_add_entry(struct inode * dir,
-       const char * name, int namelen,
-       struct buffer_head ** res_buf,
-       struct minix_dir_entry ** res_dir)
-{
-       int i;
-       unsigned long block, offset;
-       struct buffer_head * bh;
-       struct minix_dir_entry * de;
-       struct minix_sb_info * info;
-
-       *res_buf = NULL;
-       *res_dir = NULL;
-       info = &dir->i_sb->u.minix_sb;
-       if (namelen > info->s_namelen) {
-#ifdef NO_TRUNCATE
-               return -ENAMETOOLONG;
-#else
-               namelen = info->s_namelen;
-#endif
-       }
-       if (!namelen)
-               return -ENOENT;
-       bh = NULL;
-       block = offset = 0;
-       while (1) {
-               if (!bh) {
-                       bh = minix_bread(dir,block,1);
-                       if (!bh)
-                               return -ENOSPC;
-               }
-               de = (struct minix_dir_entry *) (bh->b_data + offset);
-               offset += info->s_dirsize;
-               if (block*bh->b_size + offset > dir->i_size) {
-                       de->inode = 0;
-                       dir->i_size = block*bh->b_size + offset;
-                       mark_inode_dirty(dir);
-               }
-               if (!de->inode) {
-                       dir->i_mtime = dir->i_ctime = CURRENT_TIME;
-                       mark_inode_dirty(dir);
-                       for (i = 0; i < info->s_namelen ; i++)
-                               de->name[i] = (i < namelen) ? name[i] : 0;
-                       dir->i_version = ++event;
-                       mark_buffer_dirty(bh);
-                       *res_dir = de;
-                       break;
-               }
-               if (offset < bh->b_size)
-                       continue;
-               brelse(bh);
-               bh = NULL;
-               offset = 0;
-               block++;
-       }
-       *res_buf = bh;
-       return 0;
-}
-
-static int minix_create(struct inode * dir, struct dentry *dentry, int mode)
+static int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, int rdev)
 {
        int error;
-       struct inode * inode;
-       struct buffer_head * bh;
-       struct minix_dir_entry * de;
+       struct inode * inode = minix_new_inode(dir, &error);
 
-       inode = minix_new_inode(dir, &error);
-       if (!inode)
-               return error;
-       inode->i_op = &minix_file_inode_operations;
-       inode->i_fop = &minix_file_operations;
-       inode->i_mapping->a_ops = &minix_aops;
-       inode->i_mode = mode;
-       mark_inode_dirty(inode);
-       error = minix_add_entry(dir, dentry->d_name.name,
-                               dentry->d_name.len, &bh ,&de);
-       if (error) {
-               inode->i_nlink--;
+       if (inode) {
+               inode->i_mode = mode;
+               minix_set_inode(inode, rdev);
                mark_inode_dirty(inode);
-               iput(inode);
-               return error;
+               error = add_nondir(dentry, inode);
        }
-       de->inode = inode->i_ino;
-       mark_buffer_dirty(bh);
-       brelse(bh);
-       d_instantiate(dentry, inode);
-       return 0;
+       return error;
 }
 
-static int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, int rdev)
+static int minix_create(struct inode * dir, struct dentry *dentry, int mode)
 {
-       int error;
-       struct inode * inode;
-       struct buffer_head * bh;
-       struct minix_dir_entry * de;
-
-       inode = minix_new_inode(dir, &error);
-       if (!inode)
-               return error;
-       inode->i_uid = current->fsuid;
-       init_special_inode(inode, mode, rdev);
-       mark_inode_dirty(inode);
-       error = minix_add_entry(dir, dentry->d_name.name, dentry->d_name.len, &bh, &de);
-       if (error) {
-               inode->i_nlink--;
-               mark_inode_dirty(inode);
-               iput(inode);
-               return error;
-       }
-       de->inode = inode->i_ino;
-       mark_buffer_dirty(bh);
-       brelse(bh);
-       d_instantiate(dentry, inode);
-       return 0;
+       return minix_mknod(dir, dentry, mode, 0);
 }
 
-static int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode)
+static int minix_symlink(struct inode * dir, struct dentry *dentry,
+         const char * symname)
 {
-       int error;
+       int err = -ENAMETOOLONG;
+       int i = strlen(symname)+1;
        struct inode * inode;
-       struct buffer_head * bh, *dir_block;
-       struct minix_dir_entry * de;
-       struct minix_sb_info * info;
 
-       info = &dir->i_sb->u.minix_sb;
-       if (dir->i_nlink >= info->s_link_max)
-               return -EMLINK;
-       inode = minix_new_inode(dir, &error);
+       if (i > dir->i_sb->s_blocksize)
+               goto out;
+
+       inode = minix_new_inode(dir, &err);
        if (!inode)
-               return error;
-       inode->i_op = &minix_dir_inode_operations;
-       inode->i_fop = &minix_dir_operations;
-       inode->i_size = 2 * info->s_dirsize;
-       dir_block = minix_bread(inode,0,1);
-       if (!dir_block) {
-               inode->i_nlink--;
-               mark_inode_dirty(inode);
-               iput(inode);
-               return -ENOSPC;
-       }
-       de = (struct minix_dir_entry *) dir_block->b_data;
-       de->inode=inode->i_ino;
-       strcpy(de->name,".");
-       de = (struct minix_dir_entry *) (dir_block->b_data + info->s_dirsize);
-       de->inode = dir->i_ino;
-       strcpy(de->name,"..");
-       inode->i_nlink = 2;
-       mark_buffer_dirty(dir_block);
-       brelse(dir_block);
-       inode->i_mode = S_IFDIR | mode;
-       if (dir->i_mode & S_ISGID)
-               inode->i_mode |= S_ISGID;
-       mark_inode_dirty(inode);
-       error = minix_add_entry(dir, dentry->d_name.name,
-                               dentry->d_name.len, &bh, &de);
-       if (error) {
-               inode->i_nlink=0;
-               iput(inode);
-               return error;
-       }
-       de->inode = inode->i_ino;
-       mark_buffer_dirty(bh);
-       dir->i_nlink++;
-       mark_inode_dirty(dir);
-       brelse(bh);
-       d_instantiate(dentry, inode);
-       return 0;
-}
+               goto out;
 
-/*
- * routine to check that the specified directory is empty (for rmdir)
- */
-static int empty_dir(struct inode * inode)
-{
-       unsigned int block, offset;
-       struct buffer_head * bh;
-       struct minix_dir_entry * de;
-       struct minix_sb_info * info;
-
-       info = &inode->i_sb->u.minix_sb;
-       block = 0;
-       bh = NULL;
-       offset = 2*info->s_dirsize;
-       if (inode->i_size & (info->s_dirsize-1))
-               goto bad_dir;
-       if (inode->i_size < offset)
-               goto bad_dir;
-       bh = minix_bread(inode,0,0);
-       if (!bh)
-               goto bad_dir;
-       de = (struct minix_dir_entry *) bh->b_data;
-       if (!de->inode || strcmp(de->name,"."))
-               goto bad_dir;
-       de = (struct minix_dir_entry *) (bh->b_data + info->s_dirsize);
-       if (!de->inode || strcmp(de->name,".."))
-               goto bad_dir;
-       while (block*BLOCK_SIZE+offset < inode->i_size) {
-               if (!bh) {
-                       bh = minix_bread(inode,block,0);
-                       if (!bh) {
-                               block++;
-                               continue;
-                       }
-               }
-               de = (struct minix_dir_entry *) (bh->b_data + offset);
-               offset += info->s_dirsize;
-               if (de->inode) {
-                       brelse(bh);
-                       return 0;
-               }
-               if (offset < bh->b_size)
-                       continue;
-               brelse(bh);
-               bh = NULL;
-               offset = 0;
-               block++;
-       }
-       brelse(bh);
-       return 1;
-bad_dir:
-       brelse(bh);
-       printk("Bad directory on device %s\n",
-              kdevname(inode->i_dev));
-       return 1;
-}
+       inode->i_mode = S_IFLNK | 0777;
+       minix_set_inode(inode, 0);
+       err = block_symlink(inode, symname, i);
+       if (err)
+               goto out_fail;
 
-static int minix_rmdir(struct inode * dir, struct dentry *dentry)
-{
-       int retval;
-       struct inode * inode;
-       struct buffer_head * bh;
-       struct minix_dir_entry * de;
+       err = add_nondir(dentry, inode);
+out:
+       return err;
 
-       inode = NULL;
-       bh = minix_find_entry(dir, dentry->d_name.name,
-                             dentry->d_name.len, &de);
-       retval = -ENOENT;
-       if (!bh)
-               goto end_rmdir;
-       inode = dentry->d_inode;
-
-       if (!empty_dir(inode)) {
-               retval = -ENOTEMPTY;
-               goto end_rmdir;
-       }
-       if (de->inode != inode->i_ino) {
-               retval = -ENOENT;
-               goto end_rmdir;
-       }
-       if (inode->i_nlink != 2)
-               printk("empty directory has nlink!=2 (%d)\n",inode->i_nlink);
-       de->inode = 0;
-       dir->i_version = ++event;
-       mark_buffer_dirty(bh);
-       inode->i_nlink=0;
-       mark_inode_dirty(inode);
-       inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
-       dir->i_nlink--;
-       mark_inode_dirty(dir);
-       retval = 0;
-end_rmdir:
-       brelse(bh);
-       return retval;
+out_fail:
+       dec_count(inode);
+       iput(inode);
+       goto out;
 }
 
-static int minix_unlink(struct inode * dir, struct dentry *dentry)
+static int minix_link(struct dentry * old_dentry, struct inode * dir,
+       struct dentry *dentry)
 {
-       int retval;
-       struct inode * inode;
-       struct buffer_head * bh;
-       struct minix_dir_entry * de;
+       struct inode *inode = old_dentry->d_inode;
 
-       retval = -ENOENT;
-       inode = dentry->d_inode;
-       bh = minix_find_entry(dir, dentry->d_name.name,
-                             dentry->d_name.len, &de);
-       if (!bh || de->inode != inode->i_ino)
-               goto end_unlink;
-       if (!inode->i_nlink) {
-               printk("Deleting nonexistent file (%s:%lu), %d\n",
-                       kdevname(inode->i_dev),
-                      inode->i_ino, inode->i_nlink);
-               inode->i_nlink=1;
-       }
-       de->inode = 0;
-       dir->i_version = ++event;
-       mark_buffer_dirty(bh);
-       dir->i_ctime = dir->i_mtime = CURRENT_TIME;
-       mark_inode_dirty(dir);
-       inode->i_nlink--;
-       inode->i_ctime = dir->i_ctime;
-       mark_inode_dirty(inode);
-       retval = 0;
-end_unlink:
-       brelse(bh);
-       return retval;
+       if (S_ISDIR(inode->i_mode))
+               return -EPERM;
+
+       if (inode->i_nlink >= inode->i_sb->u.minix_sb.s_link_max)
+               return -EMLINK;
+
+       inode->i_ctime = CURRENT_TIME;
+       inc_count(inode);
+       atomic_inc(&inode->i_count);
+       return add_nondir(dentry, inode);
 }
 
-static int minix_symlink(struct inode * dir, struct dentry *dentry,
-                 const char * symname)
+static int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode)
 {
-       struct minix_dir_entry * de;
-       struct inode * inode = NULL;
-       struct buffer_head * bh = NULL;
-       int i;
-       int err;
+       struct inode * inode;
+       int err = -EMLINK;
 
-       err = -ENAMETOOLONG;
-       i = strlen(symname)+1;
-       if (i>1024)
+       if (dir->i_nlink >= dir->i_sb->u.minix_sb.s_link_max)
                goto out;
+
+       inc_count(dir);
+
        inode = minix_new_inode(dir, &err);
        if (!inode)
-               goto out;
+               goto out_dir;
 
-       inode->i_mode = S_IFLNK | 0777;
-       inode->i_op = &page_symlink_inode_operations;
-       inode->i_mapping->a_ops = &minix_aops;
-       err = block_symlink(inode, symname, i);
+       inode->i_mode = S_IFDIR | mode;
+       if (dir->i_mode & S_ISGID)
+               inode->i_mode |= S_ISGID;
+       minix_set_inode(inode, 0);
+
+       inc_count(inode);
+
+       err = minix_make_empty(inode, dir);
        if (err)
-               goto fail;
+               goto out_fail;
 
-       err = minix_add_entry(dir, dentry->d_name.name,
-                           dentry->d_name.len, &bh, &de);
+       err = minix_add_link(dentry, inode);
        if (err)
-               goto fail;
+               goto out_fail;
 
-       de->inode = inode->i_ino;
-       mark_buffer_dirty(bh);
-       brelse(bh);
        d_instantiate(dentry, inode);
 out:
        return err;
-fail:
-       inode->i_nlink--;
-       mark_inode_dirty(inode);
+
+out_fail:
+       dec_count(inode);
+       dec_count(inode);
        iput(inode);
+out_dir:
+       dec_count(dir);
        goto out;
 }
 
-static int minix_link(struct dentry * old_dentry, struct inode * dir,
-              struct dentry *dentry)
+static int minix_unlink(struct inode * dir, struct dentry *dentry)
 {
-       int error;
-       struct inode *inode = old_dentry->d_inode;
+       int err = -ENOENT;
+       struct inode * inode = dentry->d_inode;
+       struct page * page;
        struct minix_dir_entry * de;
-       struct buffer_head * bh;
 
-       if (S_ISDIR(inode->i_mode))
-               return -EPERM;
+       de = minix_find_entry(dentry, &page);
+       if (!de)
+               goto end_unlink;
 
-       if (inode->i_nlink >= inode->i_sb->u.minix_sb.s_link_max)
-               return -EMLINK;
+       err = minix_delete_entry(de, page);
+       if (err)
+               goto end_unlink;
 
-       error = minix_add_entry(dir, dentry->d_name.name,
-                               dentry->d_name.len, &bh, &de);
-       if (error) {
-               brelse(bh);
-               return error;
-       }
-       de->inode = inode->i_ino;
-       mark_buffer_dirty(bh);
-       brelse(bh);
-       inode->i_nlink++;
-       inode->i_ctime = CURRENT_TIME;
-       mark_inode_dirty(inode);
-       atomic_inc(&inode->i_count);
-       d_instantiate(dentry, inode);
-       return 0;
+       inode->i_ctime = dir->i_ctime;
+       dec_count(inode);
+end_unlink:
+       return err;
 }
 
-#define PARENT_INO(buffer) \
-(((struct minix_dir_entry *) ((buffer)+info->s_dirsize))->inode)
+static int minix_rmdir(struct inode * dir, struct dentry *dentry)
+{
+       struct inode * inode = dentry->d_inode;
+       int err = -ENOTEMPTY;
+
+       if (minix_empty_dir(inode)) {
+               err = minix_unlink(dir, dentry);
+               if (!err) {
+                       dec_count(dir);
+                       dec_count(inode);
+               }
+       }
+       return err;
+}
 
-/*
- * Anybody can rename anything with this: the permission checks are left to the
- * higher-level routines.
- */
 static int minix_rename(struct inode * old_dir, struct dentry *old_dentry,
                           struct inode * new_dir, struct dentry *new_dentry)
 {
-       struct inode * old_inode, * new_inode;
-       struct buffer_head * old_bh, * new_bh, * dir_bh;
-       struct minix_dir_entry * old_de, * new_de;
-       struct minix_sb_info * info;
-       int retval;
-
-       info = &old_dir->i_sb->u.minix_sb;
-       new_bh = dir_bh = NULL;
-       old_inode = old_dentry->d_inode;
-       new_inode = new_dentry->d_inode;
-       old_bh = minix_find_entry(old_dir, old_dentry->d_name.name,
-                                 old_dentry->d_name.len, &old_de);
-       retval = -ENOENT;
-       if (!old_bh || old_de->inode != old_inode->i_ino)
-               goto end_rename;
-       retval = -EPERM;
-       new_bh = minix_find_entry(new_dir, new_dentry->d_name.name,
-                                 new_dentry->d_name.len, &new_de);
-       if (new_bh) {
-               if (!new_inode) {
-                       brelse(new_bh);
-                       new_bh = NULL;
-               }
-       }
+       struct minix_sb_info * info = &old_dir->i_sb->u.minix_sb;
+       struct inode * old_inode = old_dentry->d_inode;
+       struct inode * new_inode = new_dentry->d_inode;
+       struct page * dir_page = NULL;
+       struct minix_dir_entry * dir_de = NULL;
+       struct page * old_page;
+       struct minix_dir_entry * old_de;
+       int err = -ENOENT;
+
+       old_de = minix_find_entry(old_dentry, &old_page);
+       if (!old_de)
+               goto out;
+
        if (S_ISDIR(old_inode->i_mode)) {
-               if (new_inode) {
-                       retval = -ENOTEMPTY;
-                       if (!empty_dir(new_inode))
-                               goto end_rename;
-               }
-               retval = -EIO;
-               dir_bh = minix_bread(old_inode,0,0);
-               if (!dir_bh)
-                       goto end_rename;
-               if (PARENT_INO(dir_bh->b_data) != old_dir->i_ino)
-                       goto end_rename;
-               retval = -EMLINK;
-               if (!new_inode && new_dir != old_dir &&
-                               new_dir->i_nlink >= info->s_link_max)
-                       goto end_rename;
-       }
-       if (!new_bh) {
-               retval = minix_add_entry(new_dir,
-                                        new_dentry->d_name.name,
-                                        new_dentry->d_name.len,
-                                        &new_bh, &new_de);
-               if (retval)
-                       goto end_rename;
+               err = -EIO;
+               dir_de = minix_dotdot(old_inode, &dir_page);
+               if (!dir_de)
+                       goto out_old;
        }
-/* ok, that's it */
-       new_de->inode = old_inode->i_ino;
-       old_de->inode = 0;
-       old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
-       old_dir->i_version = ++event;
-       mark_inode_dirty(old_dir);
-       new_dir->i_ctime = new_dir->i_mtime = CURRENT_TIME;
-       new_dir->i_version = ++event;
-       mark_inode_dirty(new_dir);
+
        if (new_inode) {
-               new_inode->i_nlink--;
+               struct page * new_page;
+               struct minix_dir_entry * new_de;
+
+               err = -ENOTEMPTY;
+               if (dir_de && !minix_empty_dir(new_inode))
+                       goto out_dir;
+
+               err = -ENOENT;
+               new_de = minix_find_entry(new_dentry, &new_page);
+               if (!new_de)
+                       goto out_dir;
+               inc_count(old_inode);
+               minix_set_link(new_de, new_page, old_inode);
                new_inode->i_ctime = CURRENT_TIME;
-               mark_inode_dirty(new_inode);
-       }
-       mark_buffer_dirty(old_bh);
-       mark_buffer_dirty(new_bh);
-       if (dir_bh) {
-               PARENT_INO(dir_bh->b_data) = new_dir->i_ino;
-               mark_buffer_dirty(dir_bh);
-               old_dir->i_nlink--;
-               mark_inode_dirty(old_dir);
-               if (new_inode) {
+               if (dir_de)
                        new_inode->i_nlink--;
-                       mark_inode_dirty(new_inode);
-               } else {
-                       new_dir->i_nlink++;
-                       mark_inode_dirty(new_dir);
+               dec_count(new_inode);
+       } else {
+               if (dir_de) {
+                       err = -EMLINK;
+                       if (new_dir->i_nlink >= info->s_link_max)
+                               goto out_dir;
+               }
+               inc_count(old_inode);
+               err = minix_add_link(new_dentry, old_inode);
+               if (err) {
+                       dec_count(old_inode);
+                       goto out_dir;
                }
+               if (dir_de)
+                       inc_count(new_dir);
+       }
+
+       minix_delete_entry(old_de, old_page);
+       dec_count(old_inode);
+
+       if (dir_de) {
+               minix_set_link(dir_de, dir_page, new_dir);
+               dec_count(old_dir);
        }
-       retval = 0;
-end_rename:
-       brelse(dir_bh);
-       brelse(old_bh);
-       brelse(new_bh);
-       return retval;
+       return 0;
+
+out_dir:
+       if (dir_de) {
+               kunmap(dir_page);
+               page_cache_release(dir_page);
+       }
+out_old:
+       kunmap(old_page);
+       page_cache_release(old_page);
+out:
+       return err;
 }
 
 /*
index 92ed9fb5ebc64f1c589a3a55588edea6a5c1f226..9cadce66cbf5c1a98b71e56fe62c5b01455b2d62 100644 (file)
@@ -155,16 +155,15 @@ nfs_fsync(struct file *file, struct dentry *dentry, int datasync)
  */
 static int nfs_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
 {
-       kmap(page);
        return nfs_flush_incompatible(file, page);
 }
+
 static int nfs_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to)
 {
        long status;
        loff_t pos = ((loff_t)page->index<<PAGE_CACHE_SHIFT) + to;
        struct inode *inode = page->mapping->host;
 
-       kunmap(page);
        lock_kernel();
        status = nfs_updatepage(file, page, offset, to-offset);
        unlock_kernel();
index c48ebbc15c81df52b38e920b07c8ad1b4e877627..1742244077f59523f71f7bf3a8ce5b77c9c9bccc 100644 (file)
@@ -660,7 +660,7 @@ nfs_inode_is_stale(struct inode *inode, struct nfs_fh *fh, struct nfs_fattr *fat
        if ((fattr->mode & S_IFMT) != (inode->i_mode & S_IFMT))
                return 1;
 
-       if (is_bad_inode(inode))
+       if (is_bad_inode(inode) || NFS_STALE(inode))
                return 1;
 
        /* Has the filehandle changed? If so is the old one stale? */
@@ -862,24 +862,22 @@ int nfs_release(struct inode *inode, struct file *filp)
 int
 __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
 {
-       int              status = 0;
+       int              status = -ESTALE;
        struct nfs_fattr fattr;
 
        dfprintk(PAGECACHE, "NFS: revalidating (%x/%Ld)\n",
                inode->i_dev, (long long)NFS_FILEID(inode));
 
        lock_kernel();
-       if (!inode || is_bad_inode(inode) || NFS_STALE(inode)) {
-               unlock_kernel();
-               return -ESTALE;
-       }
+       if (!inode || is_bad_inode(inode))
+               goto out_nowait;
+       if (NFS_STALE(inode) && inode != inode->i_sb->s_root->d_inode)
+               goto out_nowait;
 
        while (NFS_REVALIDATING(inode)) {
                status = nfs_wait_on_inode(inode, NFS_INO_REVALIDATING);
-               if (status < 0) {
-                       unlock_kernel();
-                       return status;
-               }
+               if (status < 0)
+                       goto out_nowait;
                if (time_before(jiffies,NFS_READTIME(inode)+NFS_ATTRTIMEO(inode))) {
                        status = NFS_STALE(inode) ? -ESTALE : 0;
                        goto out_nowait;
@@ -893,7 +891,8 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
                         inode->i_dev, (long long)NFS_FILEID(inode), status);
                if (status == -ESTALE) {
                        NFS_FLAGS(inode) |= NFS_INO_STALE;
-                       remove_inode_hash(inode);
+                       if (inode != inode->i_sb->s_root->d_inode)
+                               remove_inode_hash(inode);
                }
                goto out;
        }
@@ -906,6 +905,8 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
        }
        dfprintk(PAGECACHE, "NFS: (%x/%Ld) revalidation complete\n",
                inode->i_dev, (long long)NFS_FILEID(inode));
+
+       NFS_FLAGS(inode) &= ~NFS_INO_STALE;
 out:
        NFS_FLAGS(inode) &= ~NFS_INO_REVALIDATING;
        wake_up(&inode->i_wait);
index 546f2e38e35e51943c1f1fd23e94b464ea4b548d..46340e88f1c8c49fca82adea6d12badf01e4586f 100644 (file)
@@ -582,6 +582,38 @@ exp_flags(char *buffer, int flag)
     return len;
 }
 
+
+
+/* mangling borrowed from fs/super.c */
+/* Use octal escapes, like mount does, for embedded spaces etc. */
+static unsigned char need_escaping[] = { ' ', '\t', '\n', '\\' };
+
+static int
+mangle(const unsigned char *s, char *buf, int len) {
+        char *sp;
+        int n;
+
+        sp = buf;
+        while(*s && sp-buf < len-3) {
+                for (n = 0; n < sizeof(need_escaping); n++) {
+                        if (*s == need_escaping[n]) {
+                                *sp++ = '\\';
+                                *sp++ = '0' + ((*s & 0300) >> 6);
+                                *sp++ = '0' + ((*s & 070) >> 3);
+                                *sp++ = '0' + (*s & 07);
+                                goto next;
+                        }
+                }
+                *sp++ = *s;
+        next:
+                s++;
+        }
+        return sp - buf;       /* no trailing NUL */
+}
+
+#define FREEROOM       ((int)PAGE_SIZE-200-len)
+#define MANGLE(s)      len += mangle((s), buffer+len, FREEROOM);
+
 int
 exp_procfs_exports(char *buffer, char **start, off_t offset,
                              int length, int *eof, void *data)
@@ -594,7 +626,7 @@ exp_procfs_exports(char *buffer, char **start, off_t offset,
         int    len = 0;
        int     i,j;
 
-        len += sprintf(buffer, "# Version 1.0\n");
+        len += sprintf(buffer, "# Version 1.1\n");
         len += sprintf(buffer+len, "# Path Client(Flags) # IPs\n");
 
        for (clp = clients; clp; clp = clp->cl_next) {
@@ -602,9 +634,10 @@ exp_procfs_exports(char *buffer, char **start, off_t offset,
                        exp = clp->cl_export[i];
                        while (exp) {
                                int first = 0;
-                               len += sprintf(buffer+len, "%s\t", exp->ex_path);
-                               len += sprintf(buffer+len, "%s", clp->cl_ident);
-                               len += sprintf(buffer+len, "(");
+                               MANGLE(exp->ex_path);
+                               buffer[len++]='\t';
+                               MANGLE(clp->cl_ident);
+                               buffer[len++]='(';
 
                                len += exp_flags(buffer+len, exp->ex_flags);
                                len += sprintf(buffer+len, ") # ");
index 476eeb55a650a41e2f964b807ddb1b7e1a498659..3dc89a7c3b043cf94ad2428d905b265300c55d83 100644 (file)
@@ -275,7 +275,6 @@ struct dentry *nfsd_findparent(struct dentry *child)
        d_drop(tdentry); /* we never want ".." hashed */
        if (!pdentry && tdentry->d_inode == NULL) {
                /* File system cannot find ".." ... sad but possible */
-               dput(tdentry);
                pdentry = ERR_PTR(-EINVAL);
        }
        if (!pdentry) {
@@ -714,9 +713,8 @@ out:
  * before the fh goes out on the wire ...
  */
 inline int _fh_update(struct dentry *dentry, struct svc_export *exp,
-                     __u32 **datapp, int maxsize)
+                     __u32 *datap, int *maxsize)
 {
-       __u32 *datap= *datapp;
        struct super_block *sb = dentry->d_inode->i_sb;
        
        if (dentry == exp->ex_dentry)
@@ -726,20 +724,22 @@ inline int _fh_update(struct dentry *dentry, struct svc_export *exp,
                int need_parent = !S_ISDIR(dentry->d_inode->i_mode) &&
                        !(exp->ex_flags & NFSEXP_NOSUBTREECHECK);
                
-               int type = sb->s_op->dentry_to_fh(dentry, datap, &maxsize, need_parent);
-               datap += maxsize;
-               *datapp = datap;
+               int type = sb->s_op->dentry_to_fh(dentry, datap, maxsize, need_parent);
                return type;
        }
-       
+
+       if (*maxsize < 2)
+               return 255;
        *datap++ = ino_t_to_u32(dentry->d_inode->i_ino);
        *datap++ = dentry->d_inode->i_generation;
-       if (S_ISDIR(dentry->d_inode->i_mode) || (exp->ex_flags & NFSEXP_NOSUBTREECHECK)){
-               *datapp = datap;
+       if (*maxsize ==2 ||
+           S_ISDIR(dentry->d_inode->i_mode) ||
+           (exp->ex_flags & NFSEXP_NOSUBTREECHECK)) {
+               *maxsize = 2;
                return 1;
        }
        *datap++ = ino_t_to_u32(dentry->d_parent->d_inode->i_ino);
-       *datapp = datap;
+       *maxsize = 3;
        return 2;
 }
 
@@ -809,10 +809,13 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st
                /* fsid_type 0 == 2byte major, 2byte minor, 4byte inode */
                *datap++ = htonl((MAJOR(exp->ex_dev)<<16)| MINOR(exp->ex_dev));
                *datap++ = ino_t_to_u32(exp->ex_ino);
-               if (inode)
+               fhp->fh_handle.fh_size = 3*4;
+               if (inode) {
+                       int size = fhp->fh_maxsize/4 - 3;
                        fhp->fh_handle.fh_fileid_type =
-                               _fh_update(dentry, exp, &datap, fhp->fh_maxsize-3);
-               fhp->fh_handle.fh_size = (datap-fhp->fh_handle.fh_auth+1)*4;
+                               _fh_update(dentry, exp, datap, &size);
+                       fhp->fh_handle.fh_size += size*4;
+               }
        }
 
        nfsd_nr_verified++;
@@ -840,13 +843,15 @@ fh_update(struct svc_fh *fhp)
        if (fhp->fh_handle.fh_version != 1) {
                _fh_update_old(dentry, fhp->fh_export, &fhp->fh_handle);
        } else {
+               int size;
                if (fhp->fh_handle.fh_fileid_type != 0)
                        goto out_uptodate;
                datap = fhp->fh_handle.fh_auth+
                        fhp->fh_handle.fh_size/4 -1;
+               size = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4;
                fhp->fh_handle.fh_fileid_type =
-                       _fh_update(dentry, fhp->fh_export, &datap, fhp->fh_maxsize-fhp->fh_handle.fh_size);
-               fhp->fh_handle.fh_size = (datap-fhp->fh_handle.fh_auth+1)*4;
+                       _fh_update(dentry, fhp->fh_export, datap, &size);
+               fhp->fh_handle.fh_size += size*4;
        }
 out:
        return 0;
index 6e23ef56a51c2e39985310d29fb4c201144ab90a..ed70f76713f8a7634d8dcbe81316879f7cd517a6 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -634,6 +634,7 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
 {
        struct file * f;
        struct inode *inode;
+       static LIST_HEAD(kill_list);
        int error;
 
        error = -ENFILE;
@@ -654,8 +655,7 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
        f->f_pos = 0;
        f->f_reada = 0;
        f->f_op = fops_get(inode->i_fop);
-       if (inode->i_sb)
-               file_move(f, &inode->i_sb->s_files);
+       file_move(f, &inode->i_sb->s_files);
        if (f->f_op && f->f_op->open) {
                error = f->f_op->open(inode,f);
                if (error)
@@ -669,6 +669,7 @@ cleanup_all:
        fops_put(f->f_op);
        if (f->f_mode & FMODE_WRITE)
                put_write_access(inode);
+       file_move(f, &kill_list); /* out of the way.. */
        f->f_dentry = NULL;
        f->f_vfsmnt = NULL;
 cleanup_file:
index 89ef2495affc93b8fe904434ec0f8832ba092f7e..657773ed99060dfd4da8b8cef149216c84081228 100644 (file)
@@ -96,12 +96,11 @@ EXPORT_SYMBOL(genhd_dasd_name);
 
 char *disk_name (struct gendisk *hd, int minor, char *buf)
 {
-       unsigned int part;
        const char *maj = hd->major_name;
-       int unit = (minor >> hd->minor_shift) + 'a';
+       unsigned int unit = (minor >> hd->minor_shift);
+       unsigned int part = (minor & ((1 << hd->minor_shift) -1 ));
 
-       part = minor & ((1 << hd->minor_shift) - 1);
-       if (hd->part[minor].de) {
+       if ((unit < hd->nr_real) && hd->part[minor].de) {
                int pos;
 
                pos = devfs_generate_path (hd->part[minor].de, buf, 64);
@@ -111,7 +110,7 @@ char *disk_name (struct gendisk *hd, int minor, char *buf)
 
 #ifdef CONFIG_ARCH_S390
        if (genhd_dasd_name
-           && genhd_dasd_name (buf, unit - 'a', part, hd) == 0)
+           && genhd_dasd_name (buf, unit, part, hd) == 0)
                return buf;
 #endif
        /*
@@ -142,13 +141,13 @@ char *disk_name (struct gendisk *hd, int minor, char *buf)
                        maj = "hd";
                        break;
                case MD_MAJOR:
-                       sprintf(buf, "%s%d", maj, unit - 'a');
+                       sprintf(buf, "%s%d", maj, unit);
                        return buf;
        }
        if (hd->major >= SCSI_DISK1_MAJOR && hd->major <= SCSI_DISK7_MAJOR) {
                unit = unit + (hd->major - SCSI_DISK1_MAJOR + 1) * 16;
-               if (unit > 'z') {
-                       unit -= 'z' + 1;
+               if (unit+'a' > 'z') {
+                       unit -= 26;
                        sprintf(buf, "sd%c%c", 'a' + unit / 26, 'a' + unit % 26);
                        if (part)
                                sprintf(buf + 4, "%d", part);
@@ -157,38 +156,32 @@ char *disk_name (struct gendisk *hd, int minor, char *buf)
        }
        if (hd->major >= COMPAQ_SMART2_MAJOR && hd->major <= COMPAQ_SMART2_MAJOR+7) {
                int ctlr = hd->major - COMPAQ_SMART2_MAJOR;
-               int disk = minor >> hd->minor_shift;
-               int part = minor & (( 1 << hd->minor_shift) - 1);
                if (part == 0)
-                       sprintf(buf, "%s/c%dd%d", maj, ctlr, disk);
+                       sprintf(buf, "%s/c%dd%d", maj, ctlr, unit);
                else
-                       sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, disk, part);
+                       sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, unit, part);
                return buf;
        }
        if (hd->major >= COMPAQ_CISS_MAJOR && hd->major <= COMPAQ_CISS_MAJOR+7) {
                 int ctlr = hd->major - COMPAQ_CISS_MAJOR;
-                int disk = minor >> hd->minor_shift;
-                int part = minor & (( 1 << hd->minor_shift) - 1);
                 if (part == 0)
-                        sprintf(buf, "%s/c%dd%d", maj, ctlr, disk);
+                        sprintf(buf, "%s/c%dd%d", maj, ctlr, unit);
                 else
-                        sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, disk, part);
+                        sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, unit, part);
                 return buf;
        }
        if (hd->major >= DAC960_MAJOR && hd->major <= DAC960_MAJOR+7) {
                int ctlr = hd->major - DAC960_MAJOR;
-               int disk = minor >> hd->minor_shift;
-               int part = minor & (( 1 << hd->minor_shift) - 1);
                if (part == 0)
-                       sprintf(buf, "%s/c%dd%d", maj, ctlr, disk);
+                       sprintf(buf, "%s/c%dd%d", maj, ctlr, unit);
                else
-                       sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, disk, part);
+                       sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, unit, part);
                return buf;
        }
        if (part)
-               sprintf(buf, "%s%c%d", maj, unit, part);
+               sprintf(buf, "%s%c%d", maj, unit+'a', part);
        else
-               sprintf(buf, "%s%c", maj, unit);
+               sprintf(buf, "%s%c", maj, unit+'a');
        return buf;
 }
 
index 81a059505baf261e00456fa917fc9613c58db798..9da28781cf529d7b12244dd0a4add6b0494ce94a 100644 (file)
@@ -23,7 +23,7 @@
  * in the file COPYING); if not, write to the Free Software Foundation,
  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
-#include <asm/types.h>
+#include <linux/types.h>
 #include <asm/unaligned.h>
 #include <asm/byteorder.h>
 #include <linux/genhd.h>
@@ -141,7 +141,8 @@ static int parse_vblk(const u8 *buffer, const int buf_size, struct vblk *vb)
                printk(LDM_CRIT "Cannot find VBLK, database may be corrupt.\n");
                return -1;
        }
-       if (BE16(buffer + 0x0E) == 0)   /* Record is not in use. */
+       if ((BE16(buffer + 0x0E) == 0) ||       /* Record is not in use. */
+           (BE16(buffer + 0x0C) != 0))         /* Part 2 of an ext. record */
                return 0;
        /* FIXME: What about extended VBLKs? */
        switch (buffer[0x13]) {
index 24c095bc980e1f7e2dae237f2b980da2a2b8a8c2..d29c9bdfb7b9b8885d1e21b6ab61ed75b7833060 100644 (file)
@@ -397,19 +397,18 @@ static void proc_kill_inodes(struct proc_dir_entry *de)
        file_list_lock();
        for (p = sb->s_files.next; p != &sb->s_files; p = p->next) {
                struct file * filp = list_entry(p, struct file, f_list);
-               struct dentry * dentry;
+               struct dentry * dentry = filp->f_dentry;
                struct inode * inode;
+               struct file_operations *fops;
 
-               dentry = filp->f_dentry;
-               if (!dentry)
-                       continue;
                if (dentry->d_op != &proc_dentry_operations)
                        continue;
                inode = dentry->d_inode;
                if (inode->u.generic_ip != de)
                        continue;
-               fops_put(filp->f_op);
+               fops = filp->f_op;
                filp->f_op = NULL;
+               fops_put(fops);
        }
        file_list_unlock();
 }
index 490c3d047ed0473eb2b62e351193ed3bdef00b7f..107470d34be5de9f5d1caf8409007391def21c57 100644 (file)
@@ -396,7 +396,6 @@ static struct super_block *qnx4_read_super(struct super_block *s,
                goto outi;
 
        brelse(bh);
-       s->s_dirt = 1;
 
        return s;
 
index 607d7a7bef4355cd8c62b6fcb2b0781d6762bb0e..05da47a79566765de006049c97226eee3d684cfe 100644 (file)
@@ -1163,6 +1163,24 @@ struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, __u32 *data,
     struct list_head *lp;
     struct dentry *result;
 
+    /* fhtype happens to reflect the number of u32s encoded.
+     * due to a bug in earlier code, fhtype might indicate there
+     * are more u32s then actually fitted.
+     * so if fhtype seems to be more than len, reduce fhtype.
+     * Valid types are:
+     *   2 - objectid + dir_id - legacy support
+     *   3 - objectid + dir_id + generation
+     *   4 - objectid + dir_id + objectid and dirid of parent - legacy
+     *   5 - objectid + dir_id + generation + objectid and dirid of parent
+     *   6 - as above plus generation of directory
+     * 6 does not fit in NFSv2 handles
+     */
+    if (fhtype > len) {
+           if (fhtype != 6 || len != 5)
+                   printk(KERN_WARNING "nfsd/reiserfs, fhtype=%d, len=%d - odd\n",
+                          fhtype, len);
+           fhtype = 5;
+    }
     if (fhtype < 2 || (parent && fhtype < 4)) 
        goto out ;
 
@@ -1173,14 +1191,14 @@ struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, __u32 *data,
            key.on_disk_key.k_objectid = data[0] ;
            key.on_disk_key.k_dir_id = data[1] ;
            inode = reiserfs_iget(sb, &key) ;
-           if (inode && (fhtype == 3 || fhtype == 6) &&
+           if (inode && (fhtype == 3 || fhtype >= 5) &&
                data[2] != inode->i_generation) {
                    iput(inode) ;
                    inode = NULL ;
            }
     } else {
-           key.on_disk_key.k_objectid = data[fhtype==6?3:2] ;
-           key.on_disk_key.k_dir_id = data[fhtype==6?4:3] ;
+           key.on_disk_key.k_objectid = data[fhtype>=5?3:2] ;
+           key.on_disk_key.k_dir_id = data[fhtype>=5?4:3] ;
            inode = reiserfs_iget(sb, &key) ;
            if (inode && fhtype == 6 &&
                data[5] != inode->i_generation) {
@@ -1227,17 +1245,20 @@ int reiserfs_dentry_to_fh(struct dentry *dentry, __u32 *data, int *lenp, int nee
     data[0] = inode->i_ino ;
     data[1] = le32_to_cpu(INODE_PKEY (inode)->k_dir_id) ;
     data[2] = inode->i_generation ;
-    *lenp = 3;
+    *lenp = 3 ;
     /* no room for directory info? return what we've stored so far */
-    if (maxlen < 6 || ! need_parent)
-        return 3;
+    if (maxlen < 5 || ! need_parent)
+        return 3 ;
 
     inode = dentry->d_parent->d_inode ;
     data[3] = inode->i_ino ;
     data[4] = le32_to_cpu(INODE_PKEY (inode)->k_dir_id) ;
+    *lenp = 5 ;
+    if (maxlen < 6)
+           return 5 ;
     data[5] = inode->i_generation ;
-    *lenp = 6;
-    return 6
+    *lenp = 6 ;
+    return 6 ;
 }
 
 
index 3370665215ca0801e8c55e2720d3d173afb26a54..0cd43e5b1a5c18550e2b8e1399339f5b33e828a5 100644 (file)
@@ -418,6 +418,9 @@ out:
 
 static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
 {
+       if (mnt->mnt_sb->s_flags & MS_NOUSER)
+               return -EINVAL;
+
        if (S_ISDIR(nd->dentry->d_inode->i_mode) !=
              S_ISDIR(mnt->mnt_root->d_inode->i_mode))
                return -ENOTDIR;
@@ -920,7 +923,6 @@ static struct super_block *get_sb_bdev(struct file_system_type *fs_type,
        bdops = devfs_get_ops ( devfs_get_handle_from_inode (inode) );
        if (bdops) bdev->bd_op = bdops;
        /* Done with lookups, semaphore down */
-       down(&mount_sem);
        dev = to_kdev_t(bdev->bd_dev);
        if (!(flags & MS_RDONLY))
                mode |= FMODE_WRITE;
@@ -995,7 +997,6 @@ out1:
        blkdev_put(bdev, BDEV_FS);
 out:
        path_release(&nd);
-       up(&mount_sem);
        return ERR_PTR(error);
 }
 
@@ -1004,7 +1005,6 @@ static struct super_block *get_sb_nodev(struct file_system_type *fs_type,
 {
        kdev_t dev;
        int error = -EMFILE;
-       down(&mount_sem);
        dev = get_unnamed_dev();
        if (dev) {
                struct super_block * sb;
@@ -1016,7 +1016,6 @@ static struct super_block *get_sb_nodev(struct file_system_type *fs_type,
                }
                put_unnamed_dev(dev);
        }
-       up(&mount_sem);
        return ERR_PTR(error);
 }
 
@@ -1031,7 +1030,6 @@ static struct super_block *get_sb_single(struct file_system_type *fs_type,
         * Get the superblock of kernel-wide instance, but
         * keep the reference to fs_type.
         */
-       down(&mount_sem);
 retry:
        spin_lock(&sb_lock);
        if (!list_empty(&fs_type->fs_supers)) {
@@ -1047,7 +1045,6 @@ retry:
                kdev_t dev = get_unnamed_dev();
                if (!dev) {
                        put_super(s);
-                       up(&mount_sem);
                        return ERR_PTR(-EMFILE);
                }
                s->s_dev = dev;
@@ -1076,7 +1073,6 @@ retry:
                spin_unlock(&sb_lock);
                put_super(s);
                put_unnamed_dev(dev);
-               up(&mount_sem);
                return ERR_PTR(-EINVAL);
        }
 }
@@ -1177,31 +1173,6 @@ static int do_remount_sb(struct super_block *sb, int flags, char *data)
        return 0;
 }
 
-struct vfsmount *kern_mount(struct file_system_type *type)
-{
-       struct super_block *sb;
-       struct vfsmount *mnt = alloc_vfsmnt();
-
-       if (!mnt)
-               return ERR_PTR(-ENOMEM);
-
-       if (type->fs_flags & FS_SINGLE)
-               sb = get_sb_single(type, 0, NULL);
-       else
-               sb = get_sb_nodev(type, 0, NULL);
-       if (IS_ERR(sb)) {
-               kmem_cache_free(mnt_cache, mnt);
-               return (struct vfsmount *)sb;
-       }
-       mnt->mnt_sb = sb;
-       mnt->mnt_root = dget(sb->s_root);
-       mnt->mnt_mountpoint = mnt->mnt_root;
-       mnt->mnt_parent = mnt;
-       up_write(&sb->s_umount);
-       up(&mount_sem);
-       return mnt;
-}
-
 /*
  * Doesn't take quota and stuff into account. IOW, in some cases it will
  * give false negatives. The main reason why it's here is that we need
@@ -1428,74 +1399,91 @@ static int do_remount(struct nameidata *nd, int flags, char *data)
        return err;
 }
 
-static int do_add_mount(struct nameidata *nd, char *type, int flags,
-                       char *name, void *data)
+struct vfsmount *do_kern_mount(char *type, int flags, char *name, void *data)
 {
        struct file_system_type * fstype;
        struct vfsmount *mnt = NULL;
        struct super_block *sb;
-       int retval = 0;
 
        if (!type || !memchr(type, 0, PAGE_SIZE))
-               return -EINVAL;
+               return ERR_PTR(-EINVAL);
 
        /* we need capabilities... */
        if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
+               return ERR_PTR(-EPERM);
 
        /* ... filesystem driver... */
        fstype = get_fs_type(type);
        if (!fstype)            
-               return -ENODEV;
+               return ERR_PTR(-ENODEV);
 
        /* ... allocated vfsmount... */
-       retval = -ENOMEM;
        mnt = alloc_vfsmnt();
-       if (!mnt)
+       if (!mnt) {
+               mnt = ERR_PTR(-ENOMEM);
                goto fs_out;
+       }
        if (name) {
                mnt->mnt_devname = kmalloc(strlen(name)+1, GFP_KERNEL);
                if (mnt->mnt_devname)
                        strcpy(mnt->mnt_devname, name);
        }
 
-       /* get superblock, locks mount_sem on success */
-       if (fstype->fs_flags & FS_NOMOUNT)
-               sb = ERR_PTR(-EINVAL);
-       else if (fstype->fs_flags & FS_REQUIRES_DEV)
+       /* get locked superblock */
+       if (fstype->fs_flags & FS_REQUIRES_DEV)
                sb = get_sb_bdev(fstype, name, flags, data);
        else if (fstype->fs_flags & FS_SINGLE)
                sb = get_sb_single(fstype, flags, data);
        else
                sb = get_sb_nodev(fstype, flags, data);
 
-       retval = PTR_ERR(sb);
        if (IS_ERR(sb)) {
                if (mnt->mnt_devname)
                        kfree(mnt->mnt_devname);
                kmem_cache_free(mnt_cache, mnt);
+               mnt = (struct vfsmount *)sb;
                goto fs_out;
        }
+       if (fstype->fs_flags & FS_NOMOUNT)
+               sb->s_flags |= MS_NOUSER;
 
        mnt->mnt_sb = sb;
        mnt->mnt_root = dget(sb->s_root);
        mnt->mnt_mountpoint = mnt->mnt_root;
        mnt->mnt_parent = mnt;
        up_write(&sb->s_umount);
+fs_out:
+       put_filesystem(fstype);
+       return mnt;
+}
 
+struct vfsmount *kern_mount(struct file_system_type *type)
+{
+       return do_kern_mount((char *)type->name, 0, (char *)type->name, NULL);
+}
+
+static int do_add_mount(struct nameidata *nd, char *type, int flags,
+                       char *name, void *data)
+{
+       struct vfsmount *mnt = do_kern_mount(type, flags, name, data);
+       int retval = PTR_ERR(mnt);
+
+       if (IS_ERR(mnt))
+               goto out;
+
+       down(&mount_sem);
        /* Something was mounted here while we slept */
        while(d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
                ;
 
        /* Refuse the same filesystem on the same mount point */
-       if (nd->mnt->mnt_sb == sb && nd->mnt->mnt_root == nd->dentry)
+       if (nd->mnt->mnt_sb == mnt->mnt_sb && nd->mnt->mnt_root == nd->dentry)
                retval = -EBUSY;
        else
                retval = graft_tree(mnt, nd);
-       mntput(mnt);
        up(&mount_sem);
-fs_out:
-       put_filesystem(fstype);
+       mntput(mnt);
+out:
        return retval;
 }
 
index f5122e386816ccfa0d40deaf80c61ffb7c37e364..d9a5a903a8dd2546af0b0cfec4cb9553a7a3e3de 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: elf.h,v 1.29 2001/03/30 07:10:48 davem Exp $ */
+/* $Id: elf.h,v 1.30 2001/08/30 23:35:38 kanoj Exp $ */
 #ifndef __ASM_SPARC64_ELF_H
 #define __ASM_SPARC64_ELF_H
 
@@ -40,7 +40,7 @@ typedef struct {
 #endif
 
 #define USE_ELF_CORE_DUMP
-#define ELF_EXEC_PAGESIZE      8192
+#define ELF_EXEC_PAGESIZE      PAGE_SIZE
 
 /* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
    use of this is to invoke "./ld.so someprog" to test out a new version of
index acd9ad6494d9d4574c7a22b08383f5ddb26bba4d..d2f008d7fd81812e6566fd40c0a5d7add5429289 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pgtable.h,v 1.143 2001/08/22 22:16:56 kanoj Exp $
+/* $Id: pgtable.h,v 1.145 2001/08/30 03:22:00 kanoj Exp $
  * pgtable.h: SpitFire page table operations.
  *
  * Copyright 1996,1997 David S. Miller (davem@caip.rutgers.edu)
 #define _PAGE_WRITE    0x0000000000000100      /* Writable SW Bit                    */
 #define _PAGE_PRESENT  0x0000000000000080      /* Present Page (ie. not swapped out) */
 
+#if PAGE_SHIFT == 13
+#define _PAGE_SZBITS   _PAGE_SZ8K
+#elif PAGE_SHIFT == 16
+#define _PAGE_SZBITS   _PAGE_SZ64K
+#elif PAGE_SHIFT == 19
+#define _PAGE_SZBITS   _PAGE_SZ512K
+#elif PAGE_SHIFT == 22
+#define _PAGE_SZBITS   _PAGE_SZ4M
+#else
+#error Wrong PAGE_SHIFT specified
+#endif
+
 #define _PAGE_CACHE    (_PAGE_CP | _PAGE_CV)
 
 #define __DIRTY_BITS   (_PAGE_MODIFIED | _PAGE_WRITE | _PAGE_W)
 
 #define _PFN_MASK      _PAGE_PADDR
 
-#define _PAGE_CHG_MASK (_PFN_MASK | _PAGE_MODIFIED | _PAGE_ACCESSED | _PAGE_PRESENT)
+#define _PAGE_CHG_MASK (_PFN_MASK | _PAGE_MODIFIED | _PAGE_ACCESSED | _PAGE_PRESENT | _PAGE_SZBITS)
 
 #define pg_iobits (_PAGE_VALID | _PAGE_PRESENT | __DIRTY_BITS | __ACCESS_BITS | _PAGE_E)
 
 
 #ifndef __ASSEMBLY__
 
-extern pte_t __bad_page(void);
-
-#define BAD_PAGE       __bad_page()
-
 extern unsigned long phys_base;
 
-#define ZERO_PAGE(vaddr)       (mem_map)
+extern struct page *mem_map_zero;
+#define ZERO_PAGE(vaddr)       (mem_map_zero)
 
 /* Warning: These take pointers to page structs now... */
 #define mk_pte(page, pgprot)           \
-       __pte((((page - mem_map) << PAGE_SHIFT)+phys_base) | pgprot_val(pgprot))
+       __pte((((page - mem_map) << PAGE_SHIFT)+phys_base) | pgprot_val(pgprot) | _PAGE_SZBITS)
 #define page_pte_prot(page, prot)      mk_pte(page, prot)
 #define page_pte(page)                 page_pte_prot(page, __pgprot(0))
 
-#define mk_pte_phys(physpage, pgprot)  (__pte((physpage) | pgprot_val(pgprot)))
+#define mk_pte_phys(physpage, pgprot)  (__pte((physpage) | pgprot_val(pgprot) | _PAGE_SZBITS))
 
 extern inline pte_t pte_modify(pte_t orig_pte, pgprot_t new_prot)
 {
index 25c60fe7d466e4bb31fdf75a5312b257d75d65c4..46dea88f62ae7e751b5203e097a0ae755be1b008 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: system.h,v 1.63 2001/04/24 01:09:12 davem Exp $ */
+/* $Id: system.h,v 1.64 2001/08/30 03:22:00 kanoj Exp $ */
 #ifndef __SPARC64_SYSTEM_H
 #define __SPARC64_SYSTEM_H
 
@@ -29,8 +29,6 @@ enum sparc_cpu {
 #define ARCH_SUN4C_SUN4 0
 #define ARCH_SUN4 0
 
-extern unsigned long empty_bad_page;
-extern unsigned long empty_zero_page;
 #endif
 
 #define setipl(__new_ipl) \
index 986599666c2b5d3e507484795e677589e7b70781..e2afb261601a620cdd4d36a27d258890e0523698 100644 (file)
@@ -32,7 +32,7 @@
 #define AC97_PCM_FRONT_DAC_RATE   0x002C       /* PCM Front DAC Rate */
 #define AC97_PCM_SURR_DAC_RATE    0x002E       /* PCM Surround DAC Rate */
 #define AC97_PCM_LFE_DAC_RATE     0x0030       /* PCM LFE DAC Rate */
-#define AC97_PCM_LR_DAC_RATE      0x0032       /* PCM LR DAC Rate */
+#define AC97_PCM_LR_ADC_RATE      0x0032       /* PCM LR DAC Rate */
 #define AC97_PCM_MIC_ADC_RATE     0x0034       /* PCM MIC ADC Rate */
 #define AC97_CENTER_LFE_MASTER    0x0036       /* Center + LFE Master Volume */
 #define AC97_SURROUND_MASTER      0x0038       /* Surround (Rear) Master Volume */
@@ -200,5 +200,8 @@ struct ac97_ops
 extern int ac97_read_proc (char *page_out, char **start, off_t off,
                           int count, int *eof, void *data);
 extern int ac97_probe_codec(struct ac97_codec *);
+extern unsigned int ac97_set_adc_rate(struct ac97_codec *codec, unsigned int rate);
+extern unsigned int ac97_set_dac_rate(struct ac97_codec *codec, unsigned int rate);
+
 
 #endif /* _AC97_CODEC_H_ */
index 1a8efa4044ea54fbada6890445d62bf7679c5505..953d87b4e165974add08777b81ddd19bdc89eab2 100644 (file)
@@ -108,6 +108,7 @@ extern int leases_enable, dir_notify_enable, lease_break_time;
 #define MS_NOATIME     1024    /* Do not update access times. */
 #define MS_NODIRATIME  2048    /* Do not update directory access times */
 #define MS_BIND                4096
+#define MS_NOUSER      (1<<31)
 
 /*
  * Flags that can be altered by MS_REMOUNT
@@ -1297,7 +1298,6 @@ extern void insert_inode_hash(struct inode *);
 extern void remove_inode_hash(struct inode *);
 extern struct file * get_empty_filp(void);
 extern void file_move(struct file *f, struct list_head *list);
-extern void file_moveto(struct file *new, struct file *old);
 extern struct buffer_head * get_hash_table(kdev_t, int, int);
 extern struct buffer_head * getblk(kdev_t, int, int);
 extern void ll_rw_block(int, int, struct buffer_head * bh[]);
index cc89518003c53f2d48d83465a52c38515b6d5b85..1d8b041bfaae7ca1374ee1bf60a24edb38be152b 100644 (file)
@@ -99,6 +99,7 @@ void gs_set_termios (struct tty_struct * tty,
 int  gs_init_port(struct gs_port *port);
 int  gs_setserial(struct gs_port *port, struct serial_struct *sp);
 void gs_getserial(struct gs_port *port, struct serial_struct *sp);
+void gs_got_break(struct gs_port *port);
 
 extern int gs_debug;
 
index b5793e81810542b5bfeb3646d7b6386f9e12914d..b0f62dd14386257971d330dca173dbf5c662323d 100644 (file)
 #define I2C_ALGO_ISA   0x050000        /* lm_sensors ISA pseudo-adapter */
 #define I2C_ALGO_SAA7146 0x060000      /* SAA 7146 video decoder bus   */
 #define I2C_ALGO_ACB   0x070000        /* ACCESS.bus algorithm         */
+#define I2C_ALGO_IIC    0x080000       /* ITE IIC bus */
 
 #define I2C_ALGO_EC     0x100000        /* ACPI embedded controller     */
 
 /* --- MPC8xx PowerPC adapters                                         */
 #define I2C_HW_MPC8XX_EPON 0x00        /* Eponymous MPC8xx I2C adapter         */
 
+/* --- ITE based algorithms                                            */
+#define I2C_HW_I_IIC   0x00    /* controller on the ITE */
+
 /* --- SMBus only adapters                                             */
 #define I2C_HW_SMBUS_PIIX4     0x00
 #define I2C_HW_SMBUS_ALI15X3   0x01
index 5db43159a3be10ba729587a96d6598e92ccb9a23..97e3831a455f42239f4c3e0f4cecf30095a2ab3b 100644 (file)
@@ -446,7 +446,7 @@ typedef int (ide_busproc_t) (struct hwif_s *, int);
  */
 typedef enum { ide_unknown,    ide_generic,    ide_pci,
                ide_cmd640,     ide_dtc2278,    ide_ali14xx,
-               ide_qd6580,     ide_umc8672,    ide_ht6560b,
+               ide_qd65xx,     ide_umc8672,    ide_ht6560b,
                ide_pdc4030,    ide_rz1000,     ide_trm290,
                ide_cmd646,     ide_cy82c693,   ide_4drives,
                ide_pmac,       ide_etrax100
index 72752441ef8c3d7c033665c1fc58ef777edbeb79..9354683a720f7e9408866cac718373d5b8f861ce 100644 (file)
@@ -82,7 +82,6 @@ struct nlm_reboot {
  */
 #define NLMSVC_XDRSIZE         sizeof(struct nlm_args)
 
-void   nlmxdr_init(void);
 int    nlmsvc_decode_testargs(struct svc_rqst *, u32 *, struct nlm_args *);
 int    nlmsvc_encode_testres(struct svc_rqst *, u32 *, struct nlm_res *);
 int    nlmsvc_decode_lockargs(struct svc_rqst *, u32 *, struct nlm_args *);
index b90790341ee4585a7cb7dff4e0e0a84924c75292..cfa7eab9c32279e8c0a051685d110b1e2dc31464 100644 (file)
@@ -89,6 +89,14 @@ struct minix_dir_entry {
 
 #ifdef __KERNEL__
 
+/*
+ * change the define below to 0 if you want names > info->s_namelen chars to be
+ * truncated. Else they will be disallowed (ENAMETOOLONG).
+ */
+#define NO_TRUNCATE 1
+
+extern struct minix_inode * minix_V1_raw_inode(struct super_block *, ino_t, struct buffer_head **);
+extern struct minix2_inode * minix_V2_raw_inode(struct super_block *, ino_t, struct buffer_head **);
 extern struct inode * minix_new_inode(const struct inode * dir, int * error);
 extern void minix_free_inode(struct inode * inode);
 extern unsigned long minix_count_free_inodes(struct super_block *sb);
@@ -96,19 +104,25 @@ extern int minix_new_block(struct inode * inode);
 extern void minix_free_block(struct inode * inode, int block);
 extern unsigned long minix_count_free_blocks(struct super_block *sb);
 
-extern struct buffer_head * minix_getblk(struct inode *, int, int);
-extern struct buffer_head * minix_bread(struct inode *, int, int);
-
 extern void V1_minix_truncate(struct inode *);
 extern void V2_minix_truncate(struct inode *);
 extern void minix_truncate(struct inode *);
 extern int minix_sync_inode(struct inode *);
-extern int V1_minix_sync_file(struct inode *);
-extern int V2_minix_sync_file(struct inode *);
+extern void minix_set_inode(struct inode *, dev_t);
 extern int V1_minix_get_block(struct inode *, long, struct buffer_head *, int);
 extern int V2_minix_get_block(struct inode *, long, struct buffer_head *, int);
 
-extern struct address_space_operations minix_aops;
+extern struct minix_dir_entry *minix_find_entry(struct dentry*, struct page**);
+extern int minix_add_link(struct dentry*, struct inode*);
+extern int minix_delete_entry(struct minix_dir_entry*, struct page*);
+extern int minix_make_empty(struct inode*, struct inode*);
+extern int minix_empty_dir(struct inode*);
+extern void minix_set_link(struct minix_dir_entry*, struct page*, struct inode*);
+extern struct minix_dir_entry *minix_dotdot(struct inode*, struct page**);
+extern ino_t minix_inode_by_name(struct dentry*);
+
+extern int minix_sync_file(struct file *, struct dentry *, int);
+
 extern struct inode_operations minix_file_inode_operations;
 extern struct inode_operations minix_dir_inode_operations;
 extern struct file_operations minix_file_operations;
index 97e91217ad235d9d2b6ae4da8559aa65813a2f93..ab122514d5089c6df44d9b69ea3f7517fe532128 100644 (file)
  * Free memory management - zoned buddy allocator.
  */
 
+#ifndef CONFIG_FORCE_MAX_ZONEORDER
 #define MAX_ORDER 10
+#else
+#define MAX_ORDER CONFIG_FORCE_MAX_ZONEORDER
+#endif
 
 typedef struct free_area_struct {
        struct list_head        free_list;
index afa2e66f01392a5d430d4c8d6adb4235350b373a..fda319cd35f9827252fbc488be11d059ac37f2af 100644 (file)
@@ -250,6 +250,33 @@ static const struct gtype##_id * __module_##gtype##_table \
 #define MODULE_DEVICE_TABLE(type,name)         \
   MODULE_GENERIC_TABLE(type##_device,name)
 
+/*
+ * The following license idents are currently accepted as indicating free
+ * software modules
+ *
+ *     "GPL"                           [GNU Public License v2 or later]
+ *     "GPL and additional rights"     [GNU Public License v2 rights and more]
+ *     "Dual BSD/GPL"                  [GNU Public License v2 or BSD license choice]
+ *
+ * The following other idents are available
+ *
+ *     "Proprietary"                   [Non free products]
+ *
+ * There are dual licensed components, but when running with Linux it is the
+ * GPL that is relevant so this is a non issue. Similarly LGPL linked with GPL
+ * is a GPL combined work.
+ *
+ * This exists for several reasons
+ * 1.  So modinfo can show license info for users wanting to vet their setup 
+ *     is free
+ * 2.  So the community can ignore bug reports including proprietary modules
+ * 3.  So vendors can do likewise based on their own policies
+ */
+#define MODULE_LICENSE(license)        \
+static const char __module_license[] __attribute__((section(".modinfo"))) =   \
+"license=" license
+
 /* Define the module variable, and usage macros.  */
 extern struct module __this_module;
 
@@ -269,6 +296,7 @@ static const char __module_using_checksums[] __attribute__((section(".modinfo"))
 #else /* MODULE */
 
 #define MODULE_AUTHOR(name)
+#define MODULE_LICENSE(license)
 #define MODULE_DESCRIPTION(desc)
 #define MODULE_SUPPORTED_DEVICE(name)
 #define MODULE_PARM(var,type)
diff --git a/include/linux/prefetch.h b/include/linux/prefetch.h
new file mode 100644 (file)
index 0000000..0aaed1f
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ *  Generic cache management functions. Everything is arch-specific,  
+ *  but this header exists to make sure the defines/functions can be
+ *  used in a generic way.
+ *
+ *  2000-11-13  Arjan van de Ven   <arjan@fenrus.demon.nl>
+ *
+ */
+
+#ifndef _LINUX_PREFETCH_H
+#define _LINUX_PREFETCH_H
+
+#include <asm/processor.h>
+#include <asm/cache.h>
+
+/*
+       prefetch(x) attempts to pre-emptively get the memory pointed to
+       by address "x" into the CPU L1 cache. 
+       prefetch(x) should not cause any kind of exception, prefetch(0) is
+       specifically ok.
+
+       prefetch() should be defined by the architecture, if not, the 
+       #define below provides a no-op define.  
+       
+       There are 3 prefetch() macros:
+       
+       prefetch(x)     - prefetches the cacheline at "x" for read
+       prefetchw(x)    - prefetches the cacheline at "x" for write
+       spin_lock_prefetch(x) - prefectches the spinlock *x for taking
+       
+       there is also PREFETCH_STRIDE which is the architecure-prefered 
+       "lookahead" size for prefetching streamed operations.
+       
+*/
+
+/*
+ *     These cannot be do{}while(0) macros. See the mental gymnastics in
+ *     the loop macro.
+ */
+#ifndef ARCH_HAS_PREFETCH
+#define ARCH_HAS_PREFETCH
+static inline void prefetch(const void *x) {;}
+#endif
+
+#ifndef ARCH_HAS_PREFETCHW
+#define ARCH_HAS_PREFETCHW
+static inline void prefetchw(const void *x) {;}
+#endif
+
+#ifndef ARCH_HAS_SPINLOCK_PREFETCH
+#define ARCH_HAS_SPINLOCK_PREFETCH
+#define spin_lock_prefetch(x) prefetchw(x)
+#endif
+
+#ifndef PREFETCH_STRIDE
+#define PREFETCH_STRIDE (4*L1_CACHE_BYTE)
+#endif
+
+#endif
index 98bf0ec20499927cfc829a25617bfc6e8826c76b..f0ec6e7b2e722fce30013e101c4cd01f135b6777 100644 (file)
@@ -34,27 +34,27 @@ struct xdr_netobj {
 typedef int    (*kxdrproc_t)(void *rqstp, u32 *data, void *obj);
 
 /*
- * These variables contain pre-xdr'ed values for faster operation.
- * FIXME: should be replaced by macros for big-endian machines.
+ * pre-xdr'ed macros.
  */
-extern u32     xdr_zero, xdr_one, xdr_two;
-
-extern u32     rpc_success,
-               rpc_prog_unavail,
-               rpc_prog_mismatch,
-               rpc_proc_unavail,
-               rpc_garbage_args,
-               rpc_system_err;
-
-extern u32     rpc_auth_ok,
-               rpc_autherr_badcred,
-               rpc_autherr_rejectedcred,
-               rpc_autherr_badverf,
-               rpc_autherr_rejectedverf,
-               rpc_autherr_tooweak,
-               rpc_autherr_dropit;
-
-void           xdr_init(void);
+
+#define        xdr_zero        __constant_htonl(0)
+#define        xdr_one         __constant_htonl(1)
+#define        xdr_two         __constant_htonl(2)
+
+#define        rpc_success             __constant_htonl(RPC_SUCCESS)
+#define        rpc_prog_unavail        __constant_htonl(RPC_PROG_UNAVAIL)
+#define        rpc_prog_mismatch       __constant_htonl(RPC_PROG_MISMATCH)
+#define        rpc_proc_unavail        __constant_htonl(RPC_PROC_UNAVAIL)
+#define        rpc_garbage_args        __constant_htonl(RPC_GARBAGE_ARGS)
+#define        rpc_system_err          __constant_htonl(RPC_SYSTEM_ERR)
+
+#define        rpc_auth_ok             __constant_htonl(RPC_AUTH_OK)
+#define        rpc_autherr_badcred     __constant_htonl(RPC_AUTH_BADCRED)
+#define        rpc_autherr_rejectedcred __constant_htonl(RPC_AUTH_REJECTEDCRED)
+#define        rpc_autherr_badverf     __constant_htonl(RPC_AUTH_BADVERF)
+#define        rpc_autherr_rejectedverf __constant_htonl(RPC_AUTH_REJECTEDVERF)
+#define        rpc_autherr_tooweak     __constant_htonl(RPC_AUTH_TOOWEAK)
+
 
 /*
  * Miscellaneous XDR helper functions
index 01a87694cf8d7e86b172b84537ca94c8b2f286e7..32f3b852a1f8116ba8b34ced4946adbc4e6ec1b3 100644 (file)
@@ -4,7 +4,7 @@
  *
  *             Basic Linux Telephony Interface
  *
- *             (c) Copyright 1999 Quicknet Technologies, Inc.
+ *             (c) Copyright 1999-2001 Quicknet Technologies, Inc.
  *
  *             This program is free software; you can redistribute it and/or
  *             modify it under the terms of the GNU General Public License
  *    Contributors:  Alan Cox, <alan@redhat.com>
  *                   David W. Erhart, <derhart@quicknet.net>
  *
- * Version:       0.1.0 - December 19, 1999
+ * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET
+ * TECHNOLOGIES, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION
+ * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Version:       $Revision: 4.2 $
+ *
+ * $Id: telephony.h,v 4.2 2001/08/06 07:09:43 craigs Exp $
  *
- * Fixes:
- * 
  *****************************************************************************/
 
 #ifndef TELEPHONY_H
 #define TELEPHONY_H
 
+#define TELEPHONY_VERSION 3013
+
 #define PHONE_VENDOR_IXJ          1
 #define PHONE_VENDOR_QUICKNET    PHONE_VENDOR_IXJ
 #define PHONE_VENDOR_VOICETRONIX  2
@@ -101,7 +114,7 @@ typedef struct {
 #define PHONE_HOOKSTATE                        _IO  ('q', 0x84)
 #define PHONE_MAXRINGS                 _IOW ('q', 0x85, char)
 #define PHONE_RING_CADENCE             _IOW ('q', 0x86, short)
-#define OLD_PHONE_RING_START           _IO  ('q', 0x87)
+#define OLD_PHONE_RING_START            _IO  ('q', 0x87)
 #define PHONE_RING_START               _IOW ('q', 0x87, PHONE_CID *)
 #define PHONE_RING_STOP                        _IO  ('q', 0x88)
 
@@ -113,6 +126,7 @@ typedef struct {
 #define PHONE_REC_DEPTH                        _IOW ('q', 0x8C, int)
 #define PHONE_FRAME                    _IOW ('q', 0x8D, int)
 #define PHONE_REC_VOLUME               _IOW ('q', 0x8E, int)
+#define PHONE_REC_VOLUME_LINEAR                _IOW ('q', 0xDB, int)
 #define PHONE_REC_LEVEL                        _IO  ('q', 0x8F)
 
 #define PHONE_PLAY_CODEC               _IOW ('q', 0x90, int)
@@ -120,6 +134,7 @@ typedef struct {
 #define PHONE_PLAY_STOP                        _IO  ('q', 0x92)
 #define PHONE_PLAY_DEPTH               _IOW ('q', 0x93, int)
 #define PHONE_PLAY_VOLUME              _IOW ('q', 0x94, int)
+#define PHONE_PLAY_VOLUME_LINEAR       _IOW ('q', 0xDC, int)
 #define PHONE_PLAY_LEVEL               _IO  ('q', 0x95)
 #define PHONE_DTMF_READY               _IOR ('q', 0x96, int)
 #define PHONE_GET_DTMF                 _IOR ('q', 0x97, int)
@@ -153,7 +168,7 @@ typedef struct {
 * 
 ******************************************************************************/
 #define PHONE_WINK_DURATION            _IOW ('q', 0xA6, int)
-
+#define PHONE_WINK                     _IOW ('q', 0xAA, int)
 
 /******************************************************************************
 * 
@@ -172,17 +187,18 @@ typedef enum {
        ALAW = 9,
        LINEAR16 = 10,
        LINEAR8 = 11,
-       WSS = 12
+       WSS = 12,
+       G729B = 13
 } phone_codec;
 
 struct phone_codec_data
 {
-       phone_codec type;
-       unsigned short buf_min, buf_opt, buf_max;
+        phone_codec type;
+        unsigned short buf_min, buf_opt, buf_max;
 };
 
-#define PHONE_QUERY_CODEC              _IOWR ('q', 0xA7, struct phone_codec_data *)
-#define PHONE_PSTN_LINETEST            _IO ('q', 0xA8)
+#define PHONE_QUERY_CODEC               _IOWR ('q', 0xA7, struct phone_codec_data *)
+#define PHONE_PSTN_LINETEST             _IO ('q', 0xA8)
 
 /******************************************************************************
 * 
@@ -212,8 +228,8 @@ struct phone_codec_data
 * indicate the current state of the hookswitch.  The pstn_ring bit
 * indicates that the DAA on a LineJACK card has detected ring voltage on
 * the PSTN port.  The caller_id bit indicates that caller_id data has been
-* received and is available.  The pstn_wink bit indicates that the DAA on
-* the LineJACK has received a wink from the telco switch.  The f0, f1, f2
+* recieved and is available.  The pstn_wink bit indicates that the DAA on
+* the LineJACK has recieved a wink from the telco switch.  The f0, f1, f2
 * and f3 bits indicate that the filter has been triggered by detecting the
 * frequency programmed into that filter.
 *
@@ -246,4 +262,5 @@ union telephony_exception {
 };
 
 
-#endif                         /* TELEPHONY_H */
+#endif         /* TELEPHONY_H */
+
index 9fc2074b2d78013eb73c89bb8dc95c1db05b4c1f..542156a0b2620e2736f32b3564c91d1e5eaa1d65 100644 (file)
@@ -589,11 +589,23 @@ struct usb_bus {
        atomic_t refcnt;
 };
 
-#define USB_MAXCHILDREN                (16)    /* This is arbitrary */
+/* This is arbitrary.
+ * From USB 2.0 spec Table 11-13, offset 7, a hub can
+ * have up to 255 ports. The most yet reported is 10.
+ */
+#define USB_MAXCHILDREN                (16)
 
 struct usb_device {
        int devnum;                     /* Device number on USB bus */
-       int slow;                       /* Slow device? */
+
+       enum {
+               USB_SPEED_UNKNOWN = 0,                  /* enumerating */
+               USB_SPEED_LOW, USB_SPEED_FULL,          /* usb 1.1 */
+               USB_SPEED_HIGH                          /* usb 2.0 */
+       } speed;
+
+       struct usb_device *tt;          /* usb1.1 device on usb2.0 bus */
+       int ttport;                     /* device/hub port on that tt */
 
        atomic_t refcnt;                /* Reference count */
        struct semaphore serialize;
@@ -704,6 +716,9 @@ int usb_get_current_frame_number (struct usb_device *usb_dev);
  * up to us. This one happens to share a lot of bit positions with the UHCI
  * specification, so that much of the uhci driver can just mask the bits
  * appropriately.
+ *
+ * NOTE:  there's no encoding (yet?) for a "high speed" endpoint; treat them
+ * like full speed devices.
  */
 
 #define PIPE_ISOCHRONOUS               0
@@ -744,12 +759,13 @@ int usb_get_current_frame_number (struct usb_device *usb_dev);
 
 static inline unsigned int __create_pipe(struct usb_device *dev, unsigned int endpoint)
 {
-       return (dev->devnum << 8) | (endpoint << 15) | (dev->slow << 26);
+       return (dev->devnum << 8) | (endpoint << 15) |
+               ((dev->speed == USB_SPEED_LOW) << 26);
 }
 
 static inline unsigned int __default_pipe(struct usb_device *dev)
 {
-       return (dev->slow << 26);
+       return ((dev->speed == USB_SPEED_LOW) << 26);
 }
 
 /* Create various pipes... */
index 8ab79794a92b65c85a1252ccca76d21fc18deb18..f46a969947de1df4b58a2880780e45c570ca871d 100644 (file)
 */
 
 /*
- *  $Id: bluetooth.h,v 1.1 2001/06/01 08:12:11 davem Exp $
+ *  $Id: bluetooth.h,v 1.6 2001/08/03 04:19:49 maxk Exp $
  */
 
-#ifndef __IF_BLUETOOTH_H
-#define __IF_BLUETOOTH_H
+#ifndef __BLUETOOTH_H
+#define __BLUETOOTH_H
 
 #include <asm/types.h>
 #include <asm/byteorder.h>
 
+#ifndef AF_BLUETOOTH
+#define AF_BLUETOOTH   31
+#define PF_BLUETOOTH   AF_BLUETOOTH
+#endif
+
 #define BTPROTO_L2CAP   0
 #define BTPROTO_HCI     1
 
 #define SOL_HCI     0
 #define SOL_L2CAP   6
 
-typedef struct {
-       __u8 b0, b1, b2, b3, b4, b5;
-} bdaddr_t;
-
-#define BDADDR_ANY ((bdaddr_t *)"\000\000\000\000\000")
-
 /* Connection and socket states */
 enum {
        BT_CONNECTED = 1, /* Equal to TCP_ESTABLISHED to make net code happy */
@@ -56,27 +55,33 @@ enum {
        BT_CLOSED
 };
 
+/* Endianness conversions */
+#define htobs(a)       __cpu_to_le16(a)
+#define htobl(a)       __cpu_to_le32(a)
+#define btohs(a)       __le16_to_cpu(a)
+#define btohl(a)       __le32_to_cpu(a)
+
+/* BD Address */
+typedef struct {
+       __u8 b[6];
+} __attribute__((packed)) bdaddr_t;
+
+#define BDADDR_ANY ((bdaddr_t *)"\000\000\000\000\000")
+
 /* Copy, swap, convert BD Address */
-static __inline__ int bacmp(bdaddr_t *ba1, bdaddr_t *ba2)
+static inline int bacmp(bdaddr_t *ba1, bdaddr_t *ba2)
 {
        return memcmp(ba1, ba2, sizeof(bdaddr_t));
 }
-static __inline__ void bacpy(bdaddr_t *dst, bdaddr_t *src)
+static inline void bacpy(bdaddr_t *dst, bdaddr_t *src)
 {
        memcpy(dst, src, sizeof(bdaddr_t));
 }
 
-extern void baswap(bdaddr_t *dst, bdaddr_t *src);
-
-extern char *batostr(bdaddr_t *ba);
-extern bdaddr_t *strtoba(char *str);
-
-/* Endianness conversions */
-#define htobs(a)       __cpu_to_le16(a)
-#define htobl(a)       __cpu_to_le32(a)
-#define btohs(a)       __le16_to_cpu(a)
-#define btohl(a)       __le32_to_cpu(a)
+void baswap(bdaddr_t *dst, bdaddr_t *src);
+char *batostr(bdaddr_t *ba);
+bdaddr_t *strtoba(char *str);
 
 int bterr(__u16 code);
 
-#endif /* __IF_BLUETOOTH_H */
+#endif /* __BLUETOOTH_H */
index c738d308d34a34a1170f5714fb870bffe13c1770..a1852c8712f0365db52e9fcaea6973e56986a311 100644 (file)
@@ -23,7 +23,7 @@
 */
 
 /*
- *  $Id: bluez.h,v 1.1 2001/06/01 08:12:11 davem Exp $
+ *  $Id: bluez.h,v 1.4 2001/08/03 04:19:49 maxk Exp $
  */
 
 #ifndef __IF_BLUEZ_H
@@ -31,8 +31,6 @@
 
 #include <net/sock.h>
 
-#define BLUEZ_VER "1.0"
-
 #define BLUEZ_MAX_PROTO        2
 
 /* Reserv for core and drivers use */
@@ -81,91 +79,41 @@ extern void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *s);
 
 /* ----- SKB helpers ----- */
 struct bluez_skb_cb {
-       int    incomming, fragmented;
-       struct sk_buff_head frags;
+       int    incomming;
 };
 #define bluez_cb(skb)  ((struct bluez_skb_cb *)(skb->cb)) 
 
-static __inline__ struct sk_buff *bluez_skb_alloc(unsigned int len, int how)
+static inline struct sk_buff *bluez_skb_alloc(unsigned int len, int how)
 {
        struct sk_buff *skb;
 
        if ((skb = alloc_skb(len + BLUEZ_SKB_RESERVE, how))) {
-               bluez_cb(skb)->incomming  = 0;
-               bluez_cb(skb)->fragmented = 0;
                skb_reserve(skb, BLUEZ_SKB_RESERVE);
+               bluez_cb(skb)->incomming  = 0;
        }
        return skb;
 }
 
-static __inline__ struct sk_buff *bluez_skb_clone(struct sk_buff *skb, int how)
-{
-       struct sk_buff *new;
-
-       if ((new = skb_clone(skb, how)))
-               bluez_cb(new)->fragmented = 0;
-       return new;
-}
-
-static __inline__ struct sk_buff *bluez_skb_send_alloc(struct sock *sk, unsigned long len, 
+static inline struct sk_buff *bluez_skb_send_alloc(struct sock *sk, unsigned long len, 
                                                       int nb, int *err)
 {
        struct sk_buff *skb;
 
        if ((skb = sock_alloc_send_skb(sk, len + BLUEZ_SKB_RESERVE, nb, err))) {
-               bluez_cb(skb)->incomming  = 0;
-               bluez_cb(skb)->fragmented = 0;
                skb_reserve(skb, BLUEZ_SKB_RESERVE);
+               bluez_cb(skb)->incomming  = 0;
        }
 
        return skb;
 }
 
-static __inline__ int bluez_skb_frags(struct sk_buff *skb)
-{
-       if (bluez_cb(skb)->fragmented)
-               return skb_queue_len(&bluez_cb(skb)->frags);
-       return 0;
-}
-
-static __inline__ void bluez_skb_add_frag(struct sk_buff *skb, struct sk_buff *frag)
-{
-       if (!bluez_cb(skb)->fragmented) {
-               skb_queue_head_init(&bluez_cb(skb)->frags);
-               bluez_cb(skb)->fragmented = 1;
-       }
-       __skb_queue_tail(&bluez_cb(skb)->frags, frag);
-}
-
-static __inline__ struct sk_buff *bluez_skb_next_frag(struct sk_buff *skb)
+static inline int skb_frags_no(struct sk_buff *skb)
 {
-       if (bluez_cb(skb)->fragmented)
-               return skb_peek(&bluez_cb(skb)->frags);
-       if (skb->next == (void *) skb->list)
-               return NULL;
-       return skb->next;
-}
-
-static __inline__ struct sk_buff *bluez_skb_get_frag(struct sk_buff *skb)
-{
-       if (bluez_cb(skb)->fragmented)
-               return __skb_dequeue(&bluez_cb(skb)->frags);
-       return NULL;
-}
-
-static __inline__ void bluez_skb_free(struct sk_buff *skb)
-{
-       if (bluez_cb(skb)->fragmented)
-               __skb_queue_purge(&bluez_cb(skb)->frags);
-       kfree_skb(skb);
-}
-
-static __inline__ void bluez_skb_queue_purge(struct sk_buff_head *q)
-{
-       struct sk_buff *skb;
+       register struct sk_buff *frag = skb_shinfo(skb)->frag_list;
+       register int n = 1;
 
-       while((skb = skb_dequeue(q)))
-               bluez_skb_free(skb);
+       for (; frag; frag=frag->next, n++);
+       return n;
 }
 
 extern int hci_core_init(void);
index 3a017b9f878fa5a1dfd5defbbe682182ef786512..35320cc535aeeb5e160f138eea0e4de27923c77c 100644 (file)
 */
 
 /*
- *  $Id: hci.h,v 1.1 2001/06/01 08:12:11 davem Exp $
+ *  $Id: hci.h,v 1.15 2001/08/05 06:02:15 maxk Exp $
  */
 
-#ifndef __IF_HCI_H
-#define __IF_HCI_H
+#ifndef __HCI_H
+#define __HCI_H
 
 #include <asm/byteorder.h>
 
+#define HCI_MAX_DEV    8
+#define HCI_MAX_FRAME_SIZE     2048
+
+/* HCI dev events */
+#define HCI_DEV_REG    1
+#define HCI_DEV_UNREG   2
+#define HCI_DEV_UP     3
+#define HCI_DEV_DOWN   4
+
+/* HCI device types */
+#define HCI_UART       0
+#define HCI_USB                1
+#define HCI_VHCI       2
+
+/* HCI device modes */
+#define HCI_NORMAL     0x0001
+#define HCI_RAW                0x0002
+#define HCI_MODE_MASK   (HCI_NORMAL | HCI_RAW)
+#define HCI_SOCK       0x1000
+
+/* HCI device states */
+#define HCI_INIT       0x0010
+#define HCI_UP                 0x0020
+#define HCI_RUNNING    0x0040
+
+/* HCI device flags */
+#define HCI_PSCAN      0x0100
+#define HCI_ISCAN      0x0200
+#define HCI_AUTH       0x0400
+
+/* HCI Ioctl defines */
+#define HCIDEVUP        _IOW('H', 201, int)
+#define HCIDEVDOWN      _IOW('H', 202, int)
+#define HCIDEVRESET     _IOW('H', 203, int)
+#define HCIRESETSTAT    _IOW('H', 204, int)
+#define HCIGETINFO      _IOR('H', 205, int)
+#define HCIGETDEVLIST   _IOR('H', 206, int)
+#define HCISETRAW       _IOW('H', 207, int)
+#define HCISETSCAN      _IOW('H', 208, int)
+#define HCISETAUTH      _IOW('H', 209, int)
+#define HCIINQUIRY      _IOR('H', 210, int)
+#define HCISETPTYPE     _IOW('H', 211, int)
+#define HCIGETCONNLIST  _IOR('H', 212, int)
+
+#ifndef __NO_HCI_DEFS
+
 /* HCI Packet types */
 #define HCI_COMMAND_PKT                0x01
 #define HCI_ACLDATA_PKT        0x02
 #define HCI_EVENT_PKT          0x04
 #define HCI_UNKNOWN_PKT                0xff
 
+/* HCI Packet types */
+#define HCI_DM1        0x0008
+#define HCI_DM3        0x0400
+#define HCI_DM5        0x4000
+#define HCI_DH1        0x0010
+#define HCI_DH3        0x0800
+#define HCI_DH5        0x8000
+
+/* ACL flags */
+#define ACL_CONT               0x0001
+#define ACL_START              0x0002
+#define ACL_ACTIVE_BCAST       0x0010
+#define ACL_PICO_BCAST         0x0020
+
+/* Baseband links */
+#define SCO_LINK       0x00
+#define ACL_LINK       0x01
+
+/* LMP features */
+#define LMP_3SLOT      0x01
+#define LMP_5SLOT      0x02
+#define LMP_ENCRYPT    0x04
+#define LMP_SOFFSET    0x08
+#define LMP_TACCURACY  0x10
+#define LMP_RSWITCH    0x20
+#define LMP_HOLD       0x40
+#define LMP_SNIF       0x80
+
+#define LMP_PARK       0x01
+#define LMP_RSSI       0x02
+#define LMP_QUALITY    0x04
+#define LMP_SCO                0x08
+#define LMP_HV2                0x10
+#define LMP_HV3                0x20
+#define LMP_ULAW       0x40
+#define LMP_ALAW       0x80
+
+#define LMP_CVSD       0x01
+#define LMP_PSCHEME    0x02
+#define LMP_PCONTROL   0x04
+
 /* -----  HCI Commands ----- */
 /* OGF & OCF values */
 
 /* Informational Parameters */
 #define OGF_INFO_PARAM 0x04
-#define OCF_NOP                        0x0000
 
-#define OCF_READ_BUFFER_SIZE           0x0005
+#define OCF_READ_LOCAL_VERSION 0x0001
+typedef struct {
+       __u8  status;
+       __u8  hci_ver;
+       __u16 hci_rev;
+       __u8  lmp_ver;
+       __u16 man_name;
+       __u16 lmp_sub;
+} __attribute__ ((packed)) read_local_version_rp;
+
+#define OCF_READ_LOCAL_FEATURES        0x0003
+typedef struct {
+       __u8 status;
+       __u8 features[8];
+} __attribute__ ((packed)) read_local_features_rp;
+
+#define OCF_READ_BUFFER_SIZE   0x0005
 typedef struct {
        __u8    status;
        __u16   acl_mtu;
        __u8    sco_mtu;
        __u16   acl_max_pkt;
        __u16   sco_max_pkt;
-} __attribute__ ((packed))     read_buffer_size_rp;
+} __attribute__ ((packed)) read_buffer_size_rp;
 
-#define OCF_READ_BD_ADDR               0x0009
+#define OCF_READ_BD_ADDR       0x0009
 typedef struct {
        __u8 status;
        bdaddr_t bdaddr;
-} __attribute__ ((packed))             read_bd_addr_rp;
+} __attribute__ ((packed)) read_bd_addr_rp;
 
 /* Host Controller and Baseband */
-#define OGF_HOST_CTL                   0x03
-#define OCF_RESET                              0x0003
+#define OGF_HOST_CTL   0x03
+#define OCF_RESET              0x0003
 #define OCF_WRITE_AUTH_ENABLE  0x0020
        #define AUTH_DISABLED                   0x00
        #define AUTH_ENABLED                    0x01
 
-#define OCF_WRITE_CA_TIMEOUT   0x0016          /* Write_Connection_Accept_Timeout */
-#define OCF_WRITE_PG_TIMEOUT   0x0018          /* Write_Page_Timeout */
+#define OCF_WRITE_CA_TIMEOUT   0x0016  
+#define OCF_WRITE_PG_TIMEOUT   0x0018
 
 #define OCF_WRITE_SCAN_ENABLE  0x001A
        #define SCANS_DISABLED          0x00
-       #define IS_ENA_PS_DIS           0x01    /* Inquiry scan enabled Page Scan disabled */
-       #define IS_DIS_PS_ENA           0x02    /* Inquiry scan disabled Page Scan enabled */
-       #define IS_ENA_PS_ENA           0x03    /* Inquiry scan enabled Page Scan enabled  */
+       #define IS_ENA_PS_DIS           0x01
+       #define IS_DIS_PS_ENA           0x02
+       #define IS_ENA_PS_ENA           0x03
 
 #define OCF_SET_EVENT_FLT      0x0005
 typedef struct {
        __u8    flt_type;
        __u8    cond_type;
-       __u8    condition;
-} __attribute__ ((packed))             set_event_flt_cp;
-#define SET_EVENT_FLT_CP_SIZE  3
+       __u8    condition[0];
+} __attribute__ ((packed)) set_event_flt_cp;
+#define SET_EVENT_FLT_CP_SIZE 2
 
 /* Filter types */
 #define FLT_CLEAR_ALL  0x00
@@ -96,7 +198,33 @@ typedef struct {
 
 /* CONN_SETUP Conditions */
 #define CONN_SETUP_AUTO_OFF    0x01
-#define CONN_SETUP_AUTO_ON             0x02
+#define CONN_SETUP_AUTO_ON     0x02
+
+#define OCF_CHANGE_LOCAL_NAME  0x0013
+typedef struct {
+       __u8    name[248];
+} __attribute__ ((packed)) change_local_name_cp;
+#define CHANGE_LOCAL_NAME_CP_SIZE 248 
+
+#define OCF_READ_LOCAL_NAME    0x0014
+typedef struct {
+       __u8    status;
+       __u8    name[248];
+} __attribute__ ((packed)) read_local_name_rp;
+#define READ_LOCAL_NAME_RP_SIZE 249 
+
+#define OCF_READ_CLASS_OF_DEV  0x0023
+typedef struct {
+       __u8    status;
+       __u8    dev_class[3];
+} __attribute__ ((packed)) read_class_of_dev_rp;
+#define READ_CLASS_OF_DEV_RP_SIZE 4 
+
+#define OCF_WRITE_CLASS_OF_DEV 0x0024
+typedef struct {
+       __u8    dev_class[3];
+} __attribute__ ((packed)) write_class_of_dev_cp;
+#define WRITE_CLASS_OF_DEV_CP_SIZE 3
 
 /* Link Control */
 #define OGF_LINK_CTL   0x01 
@@ -108,30 +236,30 @@ typedef struct {
        __u8    pscan_mode;
        __u16   clock_offset;
        __u8    role_switch;
-} __attribute__ ((packed))             create_conn_cp;
-#define CREATE_CONN_CP_SIZE    13
+} __attribute__ ((packed)) create_conn_cp;
+#define CREATE_CONN_CP_SIZE 13
 
 #define OCF_ACCEPT_CONN_REQ    0x0009
 typedef struct {
        bdaddr_t bdaddr;
        __u8    role;
-} __attribute__ ((packed))             accept_conn_req_cp;
-#define ACCEPT_CONN_REQ_CP_SIZE        7
+} __attribute__ ((packed)) accept_conn_req_cp;
+#define ACCEPT_CONN_REQ_CP_SIZE        7
 
 #define OCF_DISCONNECT 0x0006
 typedef struct {
        __u16   handle;
        __u8    reason;
-} __attribute__ ((packed))             disconnect_cp;
-#define DISCONNECT_CP_SIZE     3
+} __attribute__ ((packed)) disconnect_cp;
+#define DISCONNECT_CP_SIZE 3
 
 #define OCF_INQUIRY            0x0001
 typedef struct {
        __u8    lap[3];
        __u8    lenght;
        __u8    num_rsp;
-} __attribute__ ((packed))             inquiry_cp;
-#define INQUIRY_CP_SIZE                5
+} __attribute__ ((packed)) inquiry_cp;
+#define INQUIRY_CP_SIZE 5
 
 #define OGF_LINK_POLICY                0x02   /* Link Policy */
 
@@ -146,8 +274,8 @@ typedef struct {
        __u8    pscan_mode;
        __u8    class[3];
        __u16   clock_offset;
-} __attribute__ ((packed))             inquiry_info;
-#define INQUIRY_INFO_SIZE      14
+} __attribute__ ((packed)) inquiry_info;
+#define INQUIRY_INFO_SIZE 14
 
 #define EVT_CONN_COMPLETE      0x03
 typedef struct {
@@ -156,58 +284,53 @@ typedef struct {
        bdaddr_t        bdaddr;
        __u8    link_type;
        __u8    encr_mode;
-} __attribute__ ((packed))             evt_conn_complete;
-#define EVT_CONN_COMPLETE_SIZE         13
+} __attribute__ ((packed)) evt_conn_complete;
+#define EVT_CONN_COMPLETE_SIZE 13
 
 #define EVT_CONN_REQUEST       0x04
 typedef struct {
        bdaddr_t        bdaddr;
-#if defined    (__LITTLE_ENDIAN_BITFIELD)
-       __u32   class   :24;
-       __u32   type    :8;
-#else /*       (__BIG_ENDIAN_BITFIELD) */
-       __u32   type    :8;
-       __u32   class   :24;
-#endif
-} __attribute__ ((packed))             evt_conn_request;
-#define EVT_CONN_REQUEST_SIZE  10
+       __u8            dev_class[3];
+       __u8            link_type;
+} __attribute__ ((packed)) evt_conn_request;
+#define EVT_CONN_REQUEST_SIZE 10
 
 #define EVT_DISCONN_COMPLETE   0x05
 typedef struct {
        __u8    status;
        __u16   handle;
        __u8    reason;
-} __attribute__ ((packed))             evt_disconn_complete;
-#define EVT_DISCONN_COMPLETE_SIZE      4
+} __attribute__ ((packed)) evt_disconn_complete;
+#define EVT_DISCONN_COMPLETE_SIZE 4
 
 #define EVT_CMD_COMPLETE       0x0e
 typedef struct {
        __u8    ncmd;
        __u16   opcode;
-} __attribute__ ((packed))             evt_cmd_complete;
-#define EVT_CMD_COMPLETE_SIZE  3
+} __attribute__ ((packed)) evt_cmd_complete;
+#define EVT_CMD_COMPLETE_SIZE 3
 
 #define EVT_CMD_STATUS                 0x0f
 typedef struct {
        __u8    status;
        __u8    ncmd;
        __u16   opcode;
-} __attribute__ ((packed))             evt_cmd_status;
-#define EVT_CMD_STATUS_SIZE            4
+} __attribute__ ((packed)) evt_cmd_status;
+#define EVT_CMD_STATUS_SIZE 4
 
 #define EVT_NUM_COMP_PKTS      0x13
 typedef struct {
        __u8    num_hndl;
        /* variable lenght part */
-} __attribute__ ((packed))             evt_num_comp_pkts;
-#define EVT_NUM_COMP_PKTS_SIZE         1
+} __attribute__ ((packed)) evt_num_comp_pkts;
+#define EVT_NUM_COMP_PKTS_SIZE 1
 
 #define EVT_HCI_DEV_EVENT      0xfd
 typedef struct {
        __u16   event;
        __u16   param;
-} __attribute__ ((packed))             evt_hci_dev_event;
-#define EVT_HCI_DEV_EVENT_SIZE         4
+} __attribute__ ((packed)) evt_hci_dev_event;
+#define EVT_HCI_DEV_EVENT_SIZE 4
 
 /* --------  HCI Packet structures  -------- */
 #define HCI_TYPE_LEN   1
@@ -237,78 +360,35 @@ typedef struct {
 #define HCI_SCO_HDR_SIZE       3
 
 /* Command opcode pack/unpack */
-#define cmd_opcode_pack(ocf, ogf)      (__u16)((ocf & 0x03ff)|(ogf << 10))
+#define cmd_opcode_pack(ogf, ocf)      (__u16)((ocf & 0x03ff)|(ogf << 10))
 #define cmd_opcode_ogf(op)             (op >> 10)
 #define cmd_opcode_ocf(op)             (op & 0x03ff)
 
 /* ACL handle and flags pack/unpack */
 #define acl_handle_pack(h, f)  (__u16)((h & 0x0fff)|(f << 12))
-#define acl_handle(h)                  (h & 0x0fff)
-#define acl_flags(h)                   (h >> 12)
-
-/* ACL flags */
-#define ACL_CONT               0x0001
-#define ACL_START              0x0002
-#define ACL_ACTIVE_BCAST       0x0010
-#define ACL_PICO_BCAST         0x0020
-
-/* Max frame size */
-#define HCI_MAX_FRAME  4096
-
-/* HCI device types */
-#define HCI_UART       0
-#define HCI_USB                1
-#define HCI_EMU                2
-
-/* HCI device modes */
-#define HCI_NORMAL     0x0001
-#define HCI_RAW                0x0002
-#define HCI_MODE_MASK   (HCI_NORMAL | HCI_RAW)
-#define HCI_SOCK       0x1000
-
-/* HCI device states */
-#define HCI_INIT       0x0010
-#define HCI_UP                 0x0020
-#define HCI_RUNNING    0x0040
-
-/* HCI device flags */
-#define HCI_PSCAN      0x0100
-#define HCI_ISCAN      0x0200
-#define HCI_AUTH       0x0400
-
-/* HCI Packet types */
-#define HCI_DM1        0x0008
-#define HCI_DM3        0x0400
-#define HCI_DM5        0x4000
-#define HCI_DH1        0x0010
-#define HCI_DH3        0x0800
-#define HCI_DH5        0x8000
+#define acl_handle(h)          (h & 0x0fff)
+#define acl_flags(h)           (h >> 12)
 
-/* HCI Ioctl defines */
-#define HCIDEVUP       _IOW('H', 201, int)
-#define HCIDEVDOWN     _IOW('H', 202, int)
-#define HCIDEVRESET    _IOW('H', 203, int)
-#define HCIRESETSTAT   _IOW('H', 204, int)
-#define HCIGETINFO     _IOR('H', 205, int)
-#define HCIGETDEVLIST  _IOR('H', 206, int)
-#define HCISETRAW      _IOW('H', 207, int)
-#define HCISETSCAN     _IOW('H', 208, int)
-#define HCISETAUTH     _IOW('H', 209, int)
-#define HCIINQUIRY     _IOWR('H', 210, int)
+#endif /* _NO_HCI_DEFS */
 
 /* HCI Socket options */
 #define HCI_DATA_DIR   0x0001
 #define HCI_FILTER     0x0002
 
-/* HCI CMSG types */
+/* HCI CMSG flags */
 #define HCI_CMSG_DIR   0x0001
 
 struct sockaddr_hci {
-       sa_family_t         hci_family;
-       unsigned short  hci_dev;
+       sa_family_t    hci_family;
+       unsigned short hci_dev;
 };
 #define HCI_DEV_NONE   0xffff
 
+struct hci_filter {
+       __u32 type_mask;
+       __u32 event_mask[2];
+};
+
 struct hci_dev_req {
        __u16 dev_id;
        __u32 dev_opt;
@@ -345,26 +425,32 @@ struct hci_dev_info {
        __u16 dev_id;
        char  name[8];
 
+       bdaddr_t bdaddr;
+
        __u32 flags;
        __u8  type;
 
+       __u8  features[8];
+
+       __u32 pkt_type;
+
        __u16 acl_mtu;
        __u16 acl_max;
        __u16 sco_mtu;
        __u16 sco_max;
 
-       bdaddr_t bdaddr;
-
        struct hci_dev_stats stat;
 };
 
-/* Number of devices */
-#define HCI_MAX_DEV    8
+struct hci_conn_info {
+       __u16    handle;
+       bdaddr_t bdaddr;
+};
 
-/* HCI dev events */
-#define HCI_DEV_REG    1
-#define HCI_DEV_UNREG   2
-#define HCI_DEV_UP     3
-#define HCI_DEV_DOWN   4
+struct hci_conn_list_req {
+       __u16  dev_id;
+       __u16  conn_num;
+       struct hci_conn_info conn_info[0];
+};
 
-#endif /* __IF_HCI_H */
+#endif /* __HCI_H */
index 01fb3a98b32a52d064060f2a12e94b54136125d7..1c60de44dea75c1b4812691e690ef647288dd505 100644 (file)
 */
 
 /* 
- * $Id: hci_core.h,v 1.1 2001/06/01 08:12:11 davem Exp $ 
+ * $Id: hci_core.h,v 1.11 2001/08/05 06:02:15 maxk Exp $ 
  */
 
-#ifndef __IF_HCI_CORE_H
-#define __IF_HCI_CORE_H
+#ifndef __HCI_CORE_H
+#define __HCI_CORE_H
 
-#include "hci.h"
+#include <net/bluetooth/hci.h>
 
 /* HCI upper protocols */
 #define HCI_MAX_PROTO  1
@@ -53,155 +53,132 @@ struct inquiry_cache {
        struct inquiry_entry    *list;
 };
 
-static __inline__ void inquiry_cache_init(struct inquiry_cache *cache)
+static inline void inquiry_cache_init(struct inquiry_cache *cache)
 {
        spin_lock_init(&cache->lock);
        cache->list = NULL;
 }
 
-static __inline__ void inquiry_cache_lock(struct inquiry_cache *cache)
+static inline void inquiry_cache_lock(struct inquiry_cache *cache)
 {
        spin_lock(&cache->lock);
 }
 
-static __inline__ void inquiry_cache_unlock(struct inquiry_cache *cache)
+static inline void inquiry_cache_unlock(struct inquiry_cache *cache)
 {
        spin_unlock(&cache->lock);
 }
 
-static __inline__ void inquiry_cache_lock_bh(struct inquiry_cache *cache)
+static inline void inquiry_cache_lock_bh(struct inquiry_cache *cache)
 {
        spin_lock_bh(&cache->lock);
 }
 
-static __inline__ void inquiry_cache_unlock_bh(struct inquiry_cache *cache)
+static inline void inquiry_cache_unlock_bh(struct inquiry_cache *cache)
 {
        spin_unlock_bh(&cache->lock);
 }
 
-static __inline__ long inquiry_cache_age(struct inquiry_cache *cache)
+static inline long inquiry_cache_age(struct inquiry_cache *cache)
 {
        return jiffies - cache->timestamp;
 }
 
-static __inline__ long inquiry_entry_age(struct inquiry_entry *e)
+static inline long inquiry_entry_age(struct inquiry_entry *e)
 {
        return jiffies - e->timestamp;
 }
 extern void inquiry_cache_flush(struct inquiry_cache *cache);
 
-/* ----- Connection hash ----- */
-#define HCI_MAX_CONN   10
+struct hci_dev;
+
+/* ----- HCI Connections ----- */
+struct hci_conn {
+       struct list_head list;
+       bdaddr_t         dst;
+       __u16            handle;
+       __u8             type;
+       unsigned int     sent;
+
+       struct hci_dev  *hdev;
+       void            *l2cap_data;
+       void            *priv;
+
+       struct sk_buff_head data_q;
+};
 
-/* FIXME:
- * We assume that handle is a number - 0 ... HCI_MAX_CONN.
- */
 struct conn_hash {
-       spinlock_t      lock;
-       unsigned int    num;
-       void            *conn[HCI_MAX_CONN];
+       struct list_head list;
+       spinlock_t       lock;
+       unsigned int     num;
 };
 
-static __inline__ void conn_hash_init(struct conn_hash *h)
+static inline void conn_hash_init(struct conn_hash *h)
 {
-       memset(h, 0, sizeof(struct conn_hash));
+       INIT_LIST_HEAD(&h->list);
        spin_lock_init(&h->lock);
+       h->num = 0;     
 }
 
-static __inline__ void conn_hash_lock(struct conn_hash *h)
+static inline void conn_hash_lock(struct conn_hash *h)
 {
        spin_lock(&h->lock);
 }
 
-static __inline__ void conn_hash_unlock(struct conn_hash *h)
+static inline void conn_hash_unlock(struct conn_hash *h)
 {
        spin_unlock(&h->lock);
 }
 
-static __inline__ void *__conn_hash_add(struct conn_hash *h, __u16 handle, void *conn)
+static inline void __conn_hash_add(struct conn_hash *h, __u16 handle, struct hci_conn *c)
 {
-       if (!h->conn[handle]) {
-               h->conn[handle] = conn;
-               h->num++;
-               return conn;
-       } else
-               return NULL;
+       list_add(&c->list, &h->list);
+       h->num++;
 }
 
-static __inline__ void *conn_hash_add(struct conn_hash *h, __u16 handle, void *conn)
+static inline void conn_hash_add(struct conn_hash *h, __u16 handle, struct hci_conn *c)
 {
-       if (handle >= HCI_MAX_CONN)
-               return NULL;
-
        conn_hash_lock(h);
-       conn = __conn_hash_add(h, handle, conn);
+       __conn_hash_add(h, handle, c);
        conn_hash_unlock(h);
-
-       return conn;
 }
 
-static __inline__ void *__conn_hash_del(struct conn_hash *h, __u16 handle)
+static inline void __conn_hash_del(struct conn_hash *h, struct hci_conn *c)
 {
-       void *conn = h->conn[handle];
-
-       if (conn) {
-               h->conn[handle] = NULL;
-               h->num--;
-               return conn;
-       } else
-               return NULL;
+       list_del(&c->list);
+       h->num--;
 }
 
-static __inline__ void *conn_hash_del(struct conn_hash *h, __u16 handle)
+static inline void conn_hash_del(struct conn_hash *h, struct hci_conn *c)
 {
-       void *conn;
-
-       if (handle >= HCI_MAX_CONN)
-               return NULL;
        conn_hash_lock(h);
-       conn = __conn_hash_del(h, handle); 
+       __conn_hash_del(h, c);
        conn_hash_unlock(h);
-
-       return conn;
 }
 
-static __inline__ void *__conn_hash_lookup(struct conn_hash *h, __u16 handle)
+static inline  struct hci_conn *__conn_hash_lookup(struct conn_hash *h, __u16 handle)
 {
-       return h->conn[handle];
+       register struct list_head *p;
+       register struct hci_conn  *c;
+
+       list_for_each(p, &h->list) {
+               c = list_entry(p, struct hci_conn, list);
+               if (c->handle == handle)
+                       return c;
+       }
+        return NULL;
 }
 
-static __inline__ void *conn_hash_lookup(struct conn_hash *h, __u16 handle)
+static inline struct hci_conn *conn_hash_lookup(struct conn_hash *h, __u16 handle)
 {
-       void *conn;
-
-       if (handle >= HCI_MAX_CONN)
-               return NULL;
+       struct hci_conn *conn;
 
        conn_hash_lock(h);
        conn = __conn_hash_lookup(h, handle);
        conn_hash_unlock(h);
-
        return conn;
 }
 
-struct hci_dev;
-
-/* ----- HCI Connections ----- */
-struct hci_conn {
-       bdaddr_t        dst;
-       __u16           handle;
-
-       unsigned int    acl_sent;
-       unsigned int    sco_sent;
-
-       struct hci_dev  *hdev;
-       void            *l2cap_data;
-       void            *priv;
-
-       struct sk_buff_head     acl_q;
-       struct sk_buff_head     sco_q;
-};
-
 /* ----- HCI Devices ----- */
 struct hci_dev {
        atomic_t        refcnt;
@@ -211,6 +188,9 @@ struct hci_dev {
        __u16           id;
        __u8            type;
        bdaddr_t        bdaddr;
+       __u8            features[8];
+
+       __u16           pkt_type;
 
        atomic_t        cmd_cnt;
        unsigned int    acl_cnt;
@@ -232,7 +212,8 @@ struct hci_dev {
        struct sk_buff_head     rx_q;
        struct sk_buff_head     raw_q;
        struct sk_buff_head     cmd_q;
-       struct sk_buff          *cmd_sent;
+
+       struct sk_buff          *sent_cmd;
 
        struct semaphore        req_lock;
        wait_queue_head_t       req_wait_q;
@@ -251,20 +232,17 @@ struct hci_dev {
        int (*send)(struct sk_buff *skb);
 };
 
-static __inline__ void hci_dev_hold(struct hci_dev *hdev)
+static inline void hci_dev_hold(struct hci_dev *hdev)
 {
        atomic_inc(&hdev->refcnt);
 }
 
-static __inline__ void hci_dev_put(struct hci_dev *hdev)
+static inline void hci_dev_put(struct hci_dev *hdev)
 {
        atomic_dec(&hdev->refcnt);
 }
 
 extern struct hci_dev *hci_dev_get(int index);
-
-#define SENT_CMD_PARAM(X)      (((X->cmd_sent->data) + HCI_COMMAND_HDR_SIZE))
-
 extern int hci_register_dev(struct hci_dev *hdev);
 extern int hci_unregister_dev(struct hci_dev *hdev);
 extern int hci_dev_open(__u16 dev);
@@ -275,6 +253,8 @@ extern int hci_dev_info(unsigned long arg);
 extern int hci_dev_list(unsigned long arg);
 extern int hci_dev_setscan(unsigned long arg);
 extern int hci_dev_setauth(unsigned long arg);
+extern int hci_dev_setptype(unsigned long arg);
+extern int hci_conn_list(unsigned long arg);
 extern int hci_inquiry(unsigned long arg);
 
 extern __u32 hci_dev_setmode(struct hci_dev *hdev, __u32 mode);
@@ -282,18 +262,21 @@ extern __u32 hci_dev_getmode(struct hci_dev *hdev);
 
 extern int hci_recv_frame(struct sk_buff *skb);
 
+/* ----- LMP capabilities ----- */
+#define lmp_rswitch_capable(dev) (dev->features[0] & LMP_RSWITCH)
+
 /* ----- HCI tasks ----- */
-static __inline__ void hci_sched_cmd(struct hci_dev *hdev)
+static inline void hci_sched_cmd(struct hci_dev *hdev)
 {
        tasklet_schedule(&hdev->cmd_task);
 }
 
-static __inline__ void hci_sched_rx(struct hci_dev *hdev)
+static inline void hci_sched_rx(struct hci_dev *hdev)
 {
        tasklet_schedule(&hdev->rx_task);
 }
 
-static __inline__ void hci_sched_tx(struct hci_dev *hdev)
+static inline void hci_sched_tx(struct hci_dev *hdev)
 {
        tasklet_schedule(&hdev->tx_task);
 }
@@ -330,9 +313,9 @@ extern void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
 /* HCI info for socket */
 #define hci_pi(sk)     ((struct hci_pinfo *) &sk->protinfo)
 struct hci_pinfo {
-       struct hci_dev  *hdev;
-       __u32           cmsg_flags;
-       __u32           mask;
+       struct hci_dev    *hdev;
+       struct hci_filter filter;
+       __u32             cmsg_mask;
 };
 
 /* ----- HCI requests ----- */
@@ -340,4 +323,4 @@ struct hci_pinfo {
 #define HCI_REQ_PEND     1
 #define HCI_REQ_CANCELED  2
 
-#endif /* __IF_HCI_CORE_H */
+#endif /* __HCI_CORE_H */
diff --git a/include/net/bluetooth/hci_emu.h b/include/net/bluetooth/hci_emu.h
deleted file mode 100644 (file)
index d349ba8..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/* 
-   BlueZ - Bluetooth protocol stack for Linux
-   Copyright (C) 2000-2001 Qualcomm Incorporated
-
-   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation;
-
-   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
-   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
-   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
-   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
-   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
-   SOFTWARE IS DISCLAIMED.
-*/
-
-/*
- * $Id: hci_emu.h,v 1.1 2001/06/01 08:12:11 davem Exp $
- */
-
-#ifndef __IF_HCI_EMU_H
-#define __IF_HCI_EMU_H
-
-#ifdef __KERNEL__
-
-struct hci_emu_struct {
-       struct hci_dev       hdev;
-       __u32                flags;
-       wait_queue_head_t    read_wait;
-       struct sk_buff_head  readq;
-       struct fasync_struct *fasync;
-};
-
-#endif /* __KERNEL__ */
-
-#define HCI_EMU_MINOR          250
-
-/* Max frame size */
-#define HCI_EMU_MAX_FRAME      4096
-
-/* HCI_EMU device flags */
-#define HCI_EMU_FASYNC         0x0010
-
-#endif /* __IF_HCI_EMU_H */
index f9d6c4f8e712db77a319da4474462286fe861117..8d1ca8118d3195f6195357068e81c95e6b166960 100644 (file)
 */
 
 /*
- * $Id: hci_uart.h,v 1.1 2001/06/01 08:12:11 davem Exp $
+ * $Id: hci_uart.h,v 1.2 2001/06/02 01:40:08 maxk Exp $
  */
 
-#define HCI_MAX_READ 2048
+#ifndef N_HCI
+#define N_HCI  15
+#endif
 
 #ifdef __KERNEL__
 
index e5dcfb1933e9fb76fa465be8a776b6d6d94d10d9..348b4d49ea7d06b6c2882b5f59146d95a970c599 100644 (file)
 */
 
 /*
- * $Id: hci_usb.h,v 1.1 2001/06/01 08:12:11 davem Exp $
+ * $Id: hci_usb.h,v 1.3 2001/06/02 01:40:08 maxk Exp $
  */
 
 #ifdef __KERNEL__
 
-#define HCI_USB_MAX_READ     2048
-
 /* Class, SubClass, and Protocol codes that describe a Bluetooth device */
 #define HCI_DEV_CLASS        0xe0      /* Wireless class */
 #define HCI_DEV_SUBCLASS     0x01      /* RF subclass */
diff --git a/include/net/bluetooth/hci_vhci.h b/include/net/bluetooth/hci_vhci.h
new file mode 100644 (file)
index 0000000..e448c3a
--- /dev/null
@@ -0,0 +1,50 @@
+/* 
+   BlueZ - Bluetooth protocol stack for Linux
+   Copyright (C) 2000-2001 Qualcomm Incorporated
+
+   Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License version 2 as
+   published by the Free Software Foundation;
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES 
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, 
+   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS 
+   SOFTWARE IS DISCLAIMED.
+*/
+
+/*
+ * $Id: hci_vhci.h,v 1.2 2001/08/01 01:02:20 maxk Exp $
+ */
+
+#ifndef __HCI_VHCI_H
+#define __HCI_VHCI_H
+
+#ifdef __KERNEL__
+
+struct hci_vhci_struct {
+       struct hci_dev       hdev;
+       __u32                flags;
+       wait_queue_head_t    read_wait;
+       struct sk_buff_head  readq;
+       struct fasync_struct *fasync;
+};
+
+/* VHCI device flags */
+#define VHCI_FASYNC            0x0010
+
+#endif /* __KERNEL__ */
+
+#define VHCI_DEV       "/dev/vhci"
+#define VHCI_MINOR     250
+
+#endif /* __HCI_VHCI_H */
index a9d7db05d83ca3857cbb3be25e86f05431c0b1bb..b3535653e4e6396ac928679e4f02bfb9c2825da5 100644 (file)
@@ -23,7 +23,7 @@
 */
 
 /*
- *  $Id: l2cap.h,v 1.1 2001/06/01 08:12:11 davem Exp $
+ *  $Id: l2cap.h,v 1.5 2001/06/14 21:28:26 maxk Exp $
  */
 
 #ifndef __L2CAP_H
 #include <asm/types.h>
 #include <asm/byteorder.h>
 
+/* L2CAP defaults */
+#define L2CAP_DEFAULT_MTU      672
+#define L2CAP_DEFAULT_FLUSH_TO 0xFFFF
+
+#define L2CAP_CONN_TIMEOUT     (HZ * 40)
+#define L2CAP_DISCONN_TIMEOUT  (HZ * 2)
+#define L2CAP_CONN_IDLE_TIMEOUT        (HZ * 60)
+
 /* L2CAP socket address */
 struct sockaddr_l2 {
        sa_family_t     l2_family;
@@ -52,11 +60,10 @@ struct l2cap_options {
        __u32 delay_var;
 };
 
-/* L2CAP defaults */
-#define L2CAP_DEFAULT_MTU      672
-#define L2CAP_DEFAULT_FLUSH_TO 0xFFFF
-
-#define L2CAP_CONN_TIMEOUT     (HZ * 40)
+#define L2CAP_CONNINFO  0x02
+struct l2cap_conninfo {
+       __u16 hci_handle;
+};
 
 /* L2CAP command codes */
 #define L2CAP_COMMAND_REJ 0x01
index f4efcd94a41f207c7ef22dd8f1b7428c3eddc009..61da5097f1182f0d98963fcfbd3de3294a2a4816 100644 (file)
@@ -23,7 +23,7 @@
 */
 
 /*
- *  $Id: l2cap_core.h,v 1.1 2001/06/01 08:12:11 davem Exp $
+ *  $Id: l2cap_core.h,v 1.6 2001/08/03 04:19:49 maxk Exp $
  */
 
 #ifndef __L2CAP_CORE_H
@@ -41,12 +41,12 @@ struct l2cap_iff {
        struct list_head conn_list;
 };
 
-static __inline__ void l2cap_iff_lock(struct l2cap_iff *iff)
+static inline void l2cap_iff_lock(struct l2cap_iff *iff)
 {
        spin_lock(&iff->lock);
 }
 
-static __inline__ void l2cap_iff_unlock(struct l2cap_iff *iff)
+static inline void l2cap_iff_unlock(struct l2cap_iff *iff)
 {
        spin_unlock(&iff->lock);
 }
@@ -78,14 +78,16 @@ struct l2cap_conn {
        __u8            tx_ident;
 
        struct l2cap_chan_list chan_list;
+
+       struct timer_list timer;
 };
 
-static __inline__ void __l2cap_conn_link(struct l2cap_iff *iff, struct l2cap_conn *c)
+static inline void __l2cap_conn_link(struct l2cap_iff *iff, struct l2cap_conn *c)
 {
        list_add(&c->list, &iff->conn_list);
 }
 
-static __inline__ void __l2cap_conn_unlink(struct l2cap_iff *iff, struct l2cap_conn *c)
+static inline void __l2cap_conn_unlink(struct l2cap_iff *iff, struct l2cap_conn *c)
 {
        list_del(&c->list);
 }
@@ -126,9 +128,9 @@ struct l2cap_pinfo {
        struct l2cap_accept_q accept_q;
 };
 
-#define CONF_INPUT  0x01
-#define CONF_OUTPUT 0x02
-#define CONF_DONE      (CONF_INPUT | CONF_OUTPUT)
+#define CONF_REQ_SENT    0x01
+#define CONF_INPUT_DONE  0x02
+#define CONF_OUTPUT_DONE 0x04
 
 extern struct bluez_sock_list l2cap_sk_list;
 extern struct list_head  l2cap_iff_list;
index eb118a2dcce846312caeb229b261b4a1459829a0..26ee7fea25d2fb76dda992597a328ace649e22ec 100644 (file)
@@ -11,9 +11,13 @@ Original driver (sg.h):
 Version 2 and 3 extensions to driver:
 *       Copyright (C) 1998 - 2001 Douglas Gilbert
 
-    Version: 3.1.19 (20010623)
+    Version: 3.1.20 (20010814)
     This version is for 2.4 series kernels.
 
+    Changes since 3.1.19 (20010623)
+       - add SG_GET_ACCESS_COUNT ioctl 
+       - make open() increment and close() decrement access_count
+       - only register first 256 devices, reject subsequent devices
     Changes since 3.1.18 (20010505)
        - fix bug that caused long wait when large buffer requested
        - fix leak in error case of sg_new_read() [report: Eric Barton]
@@ -221,6 +225,9 @@ typedef struct sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */
 #define SG_SET_KEEP_ORPHAN 0x2287 /* 1 -> hold for read(), 0 -> drop (def) */
 #define SG_GET_KEEP_ORPHAN 0x2288
 
+/* yields scsi midlevel's access_count for this SCSI device */
+#define SG_GET_ACCESS_COUNT 0x2289  
+
 
 #define SG_SCATTER_SZ (8 * 4096)  /* PAGE_SIZE not available to user */
 /* Largest size (in bytes) a single scatter-gather list element can have.
index a717792c5f969bd965e72a742cc7bdcb59144a5c..f03f679b1784ec5db155e703eabee657b29484ed 100644 (file)
@@ -307,7 +307,6 @@ EXPORT_SYMBOL(init_buffer);
 EXPORT_SYMBOL(refile_buffer);
 EXPORT_SYMBOL(max_sectors);
 EXPORT_SYMBOL(max_readahead);
-EXPORT_SYMBOL(file_moveto);
 
 /* tty routines */
 EXPORT_SYMBOL(tty_hangup);
index 77db5d3453e4d5051fb5ab26b963861d20198497..bd88913d4c2db300455c79424cd6577db92334c7 100644 (file)
@@ -25,8 +25,9 @@
 /*
  * BlueZ Bluetooth address family and sockets.
  *
- * $Id: af_bluetooth.c,v 1.1 2001/06/01 08:12:11 davem Exp $
+ * $Id: af_bluetooth.c,v 1.4 2001/07/05 18:42:44 maxk Exp $
  */
+#define VERSION "1.1"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -36,7 +37,7 @@
 #include <linux/kernel.h>
 #include <linux/major.h>
 #include <linux/sched.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
@@ -129,7 +130,7 @@ struct net_proto_family bluez_sock_family_ops =
 int bluez_init(void)
 {
        INF("BlueZ HCI Core ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-                BLUEZ_VER);
+                VERSION);
        INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
 
        proc_mkdir("bluetooth", NULL);
@@ -161,4 +162,7 @@ void bluez_cleanup(void)
 #ifdef MODULE
 module_init(bluez_init);
 module_exit(bluez_cleanup);
+
+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
+MODULE_DESCRIPTION("BlueZ HCI Core ver " VERSION);
 #endif
index 298995c3e6de571c6b1fefaeaeeb52850967ded3..51d7cd364a33d2a818804b654126fb44001d6cda 100644 (file)
@@ -25,7 +25,7 @@
 /*
  * BlueZ HCI Core.
  *
- * $Id: hci_core.c,v 1.2 2001/06/01 16:57:03 davem Exp $
+ * $Id: hci_core.c,v 1.22 2001/08/03 04:19:50 maxk Exp $
  */
 
 #include <linux/config.h>
@@ -36,7 +36,7 @@
 #include <linux/kernel.h>
 #include <linux/major.h>
 #include <linux/sched.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/poll.h>
 #include <linux/fcntl.h>
 #include <linux/init.h>
@@ -47,6 +47,7 @@
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
+#include <asm/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/bluez.h>
@@ -103,7 +104,7 @@ int hci_unregister_notifier(struct notifier_block *nb)
        return notifier_chain_unregister(&hci_dev_notifier, nb);
 }
 
-static __inline__ void hci_notify(struct hci_dev *hdev, int event)
+static inline void hci_notify(struct hci_dev *hdev, int event)
 {
        notifier_call_chain(&hci_dev_notifier, event, hdev);
 }
@@ -196,14 +197,14 @@ static int inquiry_cache_dump(struct inquiry_cache *cache, int num, __u8 *buf)
 }
 
 /* --------- BaseBand connections --------- */
-static struct hci_conn *hci_conn_add(struct hci_dev *hdev, __u16 handle, bdaddr_t *dst)
+static struct hci_conn *hci_conn_add(struct hci_dev *hdev, __u16 handle, __u8 type, bdaddr_t *dst)
 {
        struct hci_conn *conn;
 
        DBG("%s handle %d dst %s", hdev->name, handle, batostr(dst));
 
-       if (handle > HCI_MAX_CONN) {
-               ERR("%s BUG handle %d is to large", hdev->name, handle);
+       if ( conn_hash_lookup(&hdev->conn_hash, handle)) {
+               ERR("%s handle 0x%x already exists", hdev->name, handle);
                return NULL;
        }
 
@@ -213,33 +214,28 @@ static struct hci_conn *hci_conn_add(struct hci_dev *hdev, __u16 handle, bdaddr_
 
        bacpy(&conn->dst, dst);
        conn->handle = handle;
+       conn->type   = type;
        conn->hdev   = hdev;
 
-       skb_queue_head_init(&conn->acl_q);
-       skb_queue_head_init(&conn->sco_q);
+       skb_queue_head_init(&conn->data_q);
 
-       if (conn_hash_add(&hdev->conn_hash, handle, conn)) {
-               hci_dev_hold(hdev);
-               return conn;
-       } else {
-               kfree(conn);
-               return NULL;
-       }
+       hci_dev_hold(hdev);
+       conn_hash_add(&hdev->conn_hash, handle, conn);
+
+       return conn;
 }
 
 static int hci_conn_del(struct hci_dev *hdev, struct hci_conn *conn)
 {
        DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
 
-       if (conn_hash_del(&hdev->conn_hash, conn->handle)) {
-               hci_dev_put(hdev);
+       conn_hash_del(&hdev->conn_hash, conn);
+       hci_dev_put(hdev);
 
-               /* Unacked frames */
-               hdev->acl_cnt += conn->acl_sent;
-       }
+       /* Unacked frames */
+       hdev->acl_cnt += conn->sent;
 
-       bluez_skb_queue_purge(&conn->acl_q);
-       bluez_skb_queue_purge(&conn->sco_q);
+       skb_queue_purge(&conn->data_q);
 
        kfree(conn);
        return 0;
@@ -248,22 +244,28 @@ static int hci_conn_del(struct hci_dev *hdev, struct hci_conn *conn)
 /* Drop all connection on the device */
 static void hci_conn_hash_flush(struct hci_dev *hdev)
 {
-       struct hci_proto *hp = GET_HPROTO(HCI_PROTO_L2CAP);
        struct conn_hash *h = &hdev->conn_hash;
-       int i;
+       struct hci_proto *hp;
+        struct list_head *p;
 
        DBG("hdev %s", hdev->name);
 
-       for (i = 0; i < HCI_MAX_CONN; i++) {
-               struct hci_conn *conn;
+       p = h->list.next;
+       while (p != &h->list) {
+               struct hci_conn *c;
 
-               if (!(conn = conn_hash_lookup(h, i)))
-                       continue;
+               c = list_entry(p, struct hci_conn, list);
+               p = p->next;
 
-               if (hp && hp->disconn_ind)
-                       hp->disconn_ind(conn, 0x16);
-               
-               hci_conn_del(hdev, conn);
+               if (c->type == ACL_LINK) {
+                       /* ACL link notify L2CAP layer */
+                       if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->disconn_ind)
+                               hp->disconn_ind(c, 0x16);
+               } else {
+                       /* SCO link (no notification) */
+               }
+
+               hci_conn_del(hdev, c);
        }
 }
 
@@ -294,9 +296,14 @@ int hci_connect(struct hci_dev *hdev, bdaddr_t *bdaddr)
        inquiry_cache_unlock_bh(cache);
 
        bacpy(&cc.bdaddr, bdaddr);
-       cc.pkt_type     = __cpu_to_le16(HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5);
+       cc.pkt_type     = __cpu_to_le16(hdev->pkt_type);
        cc.clock_offset = __cpu_to_le16(clock_offset);
-       cc.role_switch  = 0;
+
+       if (lmp_rswitch_capable(hdev))
+               cc.role_switch  = 0x01;
+       else
+               cc.role_switch  = 0x00;
+               
        hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, CREATE_CONN_CP_SIZE, &cc);
 
        return 0;
@@ -316,17 +323,17 @@ int hci_disconnect(struct hci_conn *conn, __u8 reason)
 }
 
 /* --------- HCI request handling ------------ */
-static __inline__ void hci_req_lock(struct hci_dev *hdev)
+static inline void hci_req_lock(struct hci_dev *hdev)
 {
        down(&hdev->req_lock);
 }
 
-static __inline__ void hci_req_unlock(struct hci_dev *hdev)
+static inline void hci_req_unlock(struct hci_dev *hdev)
 {
        up(&hdev->req_lock);
 }
 
-static __inline__ void hci_req_complete(struct hci_dev *hdev, int result)
+static inline void hci_req_complete(struct hci_dev *hdev, int result)
 {
        DBG("%s result 0x%2.2x", hdev->name, result);
 
@@ -337,7 +344,7 @@ static __inline__ void hci_req_complete(struct hci_dev *hdev, int result)
        }
 }
 
-static __inline__ void hci_req_cancel(struct hci_dev *hdev, int err)
+static inline void hci_req_cancel(struct hci_dev *hdev, int err)
 {
        DBG("%s err 0x%2.2x", hdev->name, err);
 
@@ -392,7 +399,7 @@ static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev,
        return err;
 }
 
-static __inline__ int hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
+static inline int hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
                                   unsigned long opt, __u32 timeout)
 {
        int ret;
@@ -423,6 +430,9 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
 
        /* Mandatory initialization */
 
+       /* Read Local Supported Features */
+       hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_LOCAL_FEATURES, 0, NULL);
+
        /* Read Buffer Size (ACL mtu, max pkt, etc.) */
        hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BUFFER_SIZE, 0, NULL);
 
@@ -433,10 +443,9 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
 
        /* Clear Event Filters */
        ec.flt_type  = FLT_CLEAR_ALL;
-       ec.cond_type = 0;
-       hci_send_cmd(hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, SET_EVENT_FLT_CP_SIZE, &ec);
+       hci_send_cmd(hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, 1, &ec);
 
-       /* Page timeout ~ 20 secs */
+       /* Page timeout ~20 secs */
        param = __cpu_to_le16(0x8000);
        hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_PG_TIMEOUT, 2, &param);
 
@@ -479,7 +488,7 @@ static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
        hci_send_cmd(hdev, OGF_LINK_CTL, OCF_INQUIRY, INQUIRY_CP_SIZE, &ic);
 }
 
-/* Open HCI device */
+/* HCI ioctl helpers */
 int hci_dev_open(__u16 dev)
 {
        struct hci_dev *hdev;
@@ -497,24 +506,43 @@ int hci_dev_open(__u16 dev)
                goto done;
        }
 
-       /* Initialize device */
        if (hdev->open(hdev)) {
                ret = -EIO;
                goto done;
        }
 
-       atomic_set(&hdev->cmd_cnt, 1);
-       hdev->cmd_sent= NULL;
-       hdev->flags  |= HCI_INIT;
+       if (hdev->flags & HCI_NORMAL) {
+               atomic_set(&hdev->cmd_cnt, 1);
+               hdev->flags |= HCI_INIT;
 
-       __hci_request(hdev, hci_reset_req, 0, HZ);
+               //__hci_request(hdev, hci_reset_req, 0, HZ);
+               ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
+       
+               hdev->flags &= ~HCI_INIT;
+       }
 
-       if (!(ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT))) {
+       if (!ret) {
                hdev->flags |= HCI_UP;
                hci_notify(hdev, HCI_DEV_UP);
-       }
+       } else {        
+               /* Init failed, cleanup */
+               tasklet_kill(&hdev->rx_task);
+               tasklet_kill(&hdev->tx_task);
+               tasklet_kill(&hdev->cmd_task);
 
-       hdev->flags &= ~HCI_INIT;
+               skb_queue_purge(&hdev->cmd_q);
+               skb_queue_purge(&hdev->rx_q);
+
+               if (hdev->flush)
+                       hdev->flush(hdev);
+
+               if (hdev->sent_cmd) {
+                       kfree_skb(hdev->sent_cmd);
+                       hdev->sent_cmd = NULL;
+               }
+
+               hdev->close(hdev);
+       }
 
 done:
        hci_req_unlock(hdev);
@@ -523,7 +551,6 @@ done:
        return ret;
 }
 
-/* Close HCI device */
 int hci_dev_close(__u16 dev)
 {
        struct hci_dev *hdev;
@@ -548,7 +575,8 @@ int hci_dev_close(__u16 dev)
        hci_conn_hash_flush(hdev);
 
        /* Clear flags */
-       hdev->flags &= (HCI_NORMAL | HCI_SOCK);
+       hdev->flags &= HCI_SOCK;
+       hdev->flags |= HCI_NORMAL;
 
        hci_notify(hdev, HCI_DEV_DOWN);
 
@@ -556,7 +584,7 @@ int hci_dev_close(__u16 dev)
                hdev->flush(hdev);
 
        /* Reset device */
-       bluez_skb_queue_purge(&hdev->cmd_q);
+       skb_queue_purge(&hdev->cmd_q);
        atomic_set(&hdev->cmd_cnt, 1);
        hdev->flags |= HCI_INIT;
        __hci_request(hdev, hci_reset_req, 0, HZ);
@@ -566,14 +594,14 @@ int hci_dev_close(__u16 dev)
        tasklet_kill(&hdev->cmd_task);
 
        /* Drop queues */
-       bluez_skb_queue_purge(&hdev->rx_q);
-       bluez_skb_queue_purge(&hdev->cmd_q);
-       bluez_skb_queue_purge(&hdev->raw_q);
+       skb_queue_purge(&hdev->rx_q);
+       skb_queue_purge(&hdev->cmd_q);
+       skb_queue_purge(&hdev->raw_q);
 
        /* Drop last sent command */
-       if (hdev->cmd_sent) {
-               bluez_skb_free(hdev->cmd_sent);
-               hdev->cmd_sent = NULL;
+       if (hdev->sent_cmd) {
+               kfree_skb(hdev->sent_cmd);
+               hdev->sent_cmd = NULL;
        }
 
        /* After this point our queues are empty
@@ -588,6 +616,304 @@ done:
        return 0;
 }
 
+int hci_dev_reset(__u16 dev)
+{
+       struct hci_dev *hdev;
+       int ret = 0;
+
+       if (!(hdev = hci_dev_get(dev)))
+               return -ENODEV;
+
+       hci_req_lock(hdev);
+       tasklet_disable(&hdev->tx_task);
+
+       if (!(hdev->flags & HCI_UP))
+               goto done;
+
+       /* Drop queues */
+       skb_queue_purge(&hdev->rx_q);
+       skb_queue_purge(&hdev->cmd_q);
+
+       inquiry_cache_flush(&hdev->inq_cache);
+
+       hci_conn_hash_flush(hdev);
+
+       if (hdev->flush)
+               hdev->flush(hdev);
+
+       atomic_set(&hdev->cmd_cnt, 1); 
+       hdev->acl_cnt = 0; hdev->sco_cnt = 0;
+
+       ret = __hci_request(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
+
+done:
+       tasklet_enable(&hdev->tx_task);
+       hci_req_unlock(hdev);
+       hci_dev_put(hdev);
+
+       return ret;
+}
+
+int hci_dev_reset_stat(__u16 dev)
+{
+       struct hci_dev *hdev;
+       int ret = 0;
+
+       if (!(hdev = hci_dev_get(dev)))
+               return -ENODEV;
+
+       memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
+
+       hci_dev_put(hdev);
+
+       return ret;
+}
+
+int hci_dev_setauth(unsigned long arg)
+{
+       struct hci_dev *hdev;
+       struct hci_dev_req dr;
+       int ret = 0;
+
+       if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
+               return -EFAULT;
+
+       if (!(hdev = hci_dev_get(dr.dev_id)))
+               return -ENODEV;
+
+       ret = hci_request(hdev, hci_auth_req, dr.dev_opt, HCI_INIT_TIMEOUT);
+
+       hci_dev_put(hdev);
+
+       return ret;
+}
+
+int hci_dev_setscan(unsigned long arg)
+{
+       struct hci_dev *hdev;
+       struct hci_dev_req dr;
+       int ret = 0;
+
+       if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
+               return -EFAULT;
+
+       if (!(hdev = hci_dev_get(dr.dev_id)))
+               return -ENODEV;
+
+       ret = hci_request(hdev, hci_scan_req, dr.dev_opt, HCI_INIT_TIMEOUT);
+
+       hci_dev_put(hdev);
+
+       return ret;
+}
+
+int hci_dev_setptype(unsigned long arg)
+{
+       struct hci_dev *hdev;
+       struct hci_dev_req dr;
+       int ret = 0;
+
+       if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
+               return -EFAULT;
+
+       if (!(hdev = hci_dev_get(dr.dev_id)))
+               return -ENODEV;
+
+       hdev->pkt_type = (__u16) dr.dev_opt;
+
+       hci_dev_put(hdev);
+
+       return ret;
+}
+
+int hci_dev_list(unsigned long arg)
+{
+       struct hci_dev_list_req *dl;
+       struct hci_dev_req *dr;
+       struct hci_dev *hdev;
+       int i, n, size;
+       __u16 dev_num;
+
+       if (get_user(dev_num, (__u16 *) arg))
+               return -EFAULT;
+
+       size = dev_num * sizeof(struct hci_dev_req) + sizeof(__u16);
+
+       if (verify_area(VERIFY_WRITE, (void *) arg, size))
+               return -EFAULT;
+
+       if (!(dl = kmalloc(size, GFP_KERNEL)))
+               return -ENOMEM;
+       dr = dl->dev_req;
+
+       spin_lock_bh(&hdev_list_lock);
+       for (i = 0, n = 0; i < HCI_MAX_DEV && n < dev_num; i++) {
+               if ((hdev = hdev_list[i])) {
+                       (dr + n)->dev_id  = hdev->id;
+                       (dr + n)->dev_opt = hdev->flags;
+                       n++;
+               }
+       }
+       spin_unlock_bh(&hdev_list_lock);
+
+       dl->dev_num = n;
+       size = n * sizeof(struct hci_dev_req) + sizeof(__u16);
+
+       copy_to_user((void *) arg, dl, size);
+
+       return 0;
+}
+
+int hci_dev_info(unsigned long arg)
+{
+       struct hci_dev *hdev;
+       struct hci_dev_info di;
+       int err = 0;
+
+       if (copy_from_user(&di, (void *) arg, sizeof(di)))
+               return -EFAULT;
+
+       if (!(hdev = hci_dev_get(di.dev_id)))
+               return -ENODEV;
+
+       strcpy(di.name, hdev->name);
+       di.bdaddr   = hdev->bdaddr;
+       di.type     = hdev->type;
+       di.flags    = hdev->flags;
+       di.pkt_type = hdev->pkt_type;
+       di.acl_mtu  = hdev->acl_mtu;
+       di.acl_max  = hdev->acl_max;
+       di.sco_mtu  = hdev->sco_mtu;
+       di.sco_max  = hdev->sco_max;
+
+       memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
+       memcpy(&di.features, &hdev->features, sizeof(di.features));
+
+       if (copy_to_user((void *) arg, &di, sizeof(di)))
+               err = -EFAULT;
+
+       hci_dev_put(hdev);
+
+       return err;
+}
+
+__u32 hci_dev_setmode(struct hci_dev *hdev, __u32 mode)
+{
+       __u32 omode = hdev->flags & HCI_MODE_MASK;
+
+       hdev->flags &= ~HCI_MODE_MASK;
+       hdev->flags |= (mode & HCI_MODE_MASK);
+
+       return omode;
+}
+
+__u32 hci_dev_getmode(struct hci_dev *hdev)
+{
+       return hdev->flags & HCI_MODE_MASK;
+}
+
+int hci_conn_list(unsigned long arg)
+{
+       struct hci_conn_list_req req, *cl;
+       struct hci_conn_info *ci;
+       struct hci_dev *hdev;
+       struct list_head *p;
+       int n = 0, size;
+
+       if (copy_from_user(&req, (void *) arg, sizeof(req)))
+               return -EFAULT;
+
+       if (!(hdev = hci_dev_get(req.dev_id)))
+               return -ENODEV;
+
+       size = req.conn_num * sizeof(struct hci_conn_info) + sizeof(req);
+
+       if (verify_area(VERIFY_WRITE, (void *)arg, size))
+               return -EFAULT;
+
+       if (!(cl = kmalloc(size, GFP_KERNEL)))
+               return -ENOMEM;
+       ci = cl->conn_info;
+
+       local_bh_disable();
+       conn_hash_lock(&hdev->conn_hash);
+       list_for_each(p, &hdev->conn_hash.list) {
+               register struct hci_conn *c;
+               c = list_entry(p, struct hci_conn, list);
+
+               (ci + n)->handle = c->handle;
+               bacpy(&(ci + n)->bdaddr, &c->dst);
+               n++;
+       }
+       conn_hash_unlock(&hdev->conn_hash);
+       local_bh_enable();
+
+       cl->dev_id = hdev->id;
+       cl->conn_num = n;
+       size = n * sizeof(struct hci_conn_info) + sizeof(req);
+
+       copy_to_user((void *) arg, cl, size);
+
+       hci_dev_put(hdev);
+
+       return 0;
+}
+
+int hci_inquiry(unsigned long arg)
+{
+       struct inquiry_cache *cache;
+       struct hci_inquiry_req ir;
+       struct hci_dev *hdev;
+       int err = 0, do_inquiry = 0;
+       long timeo;
+       __u8 *buf, *ptr;
+
+       ptr = (void *) arg;
+       if (copy_from_user(&ir, ptr, sizeof(ir)))
+               return -EFAULT;
+
+       if (!(hdev = hci_dev_get(ir.dev_id)))
+               return -ENODEV;
+
+       cache = &hdev->inq_cache;
+
+       inquiry_cache_lock(cache);
+       if (inquiry_cache_age(cache) > INQUIRY_CACHE_AGE_MAX || ir.flags & IREQ_CACHE_FLUSH) {
+               inquiry_cache_flush(cache);
+               do_inquiry = 1;
+       }
+       inquiry_cache_unlock(cache);
+
+       timeo = ir.length * 2 * HZ;
+       if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0)
+               goto done;
+
+       /* cache_dump can't sleep. Therefore we allocate temp buffer and then
+        * copy it to the user space.
+        */
+       if (!(buf = kmalloc(sizeof(inquiry_info) * ir.num_rsp, GFP_KERNEL))) {
+               err = -ENOMEM;
+               goto done;
+       }
+       ir.num_rsp = inquiry_cache_dump(cache, ir.num_rsp, buf);
+
+       DBG("num_rsp %d", ir.num_rsp);
+
+       if (!verify_area(VERIFY_WRITE, ptr, sizeof(ir) + (sizeof(inquiry_info) * ir.num_rsp))) {
+               copy_to_user(ptr, &ir, sizeof(ir));
+               ptr += sizeof(ir);
+               copy_to_user(ptr, buf, sizeof(inquiry_info) * ir.num_rsp);
+       } else 
+               err = -EFAULT;
+
+       kfree(buf);
+
+done:
+       hci_dev_put(hdev);
+
+       return err;
+}
+
 /* Interface to HCI drivers */
 
 /* Register HCI device */
@@ -608,6 +934,8 @@ int hci_register_dev(struct hci_dev *hdev)
                        hdev->id    = i;
                        hdev->flags = HCI_NORMAL;
 
+                       hdev->pkt_type = (HCI_DM1 | HCI_DH1);
+
                        tasklet_init(&hdev->cmd_task, hci_cmd_task, (unsigned long) hdev);
                        tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev);
                        tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev);
@@ -725,7 +1053,7 @@ static int hci_send_frame(struct sk_buff *skb)
        struct hci_dev *hdev = (struct hci_dev *) skb->dev;
 
        if (!hdev) {
-               bluez_skb_free(skb);
+               kfree_skb(skb);
                return -ENODEV;
        }
 
@@ -740,23 +1068,26 @@ static int hci_send_frame(struct sk_buff *skb)
        return hdev->send(skb);
 }
 
-/* ACL scheduler */
-static __inline__ struct hci_conn *hci_low_acl_sent(struct hci_dev *hdev, int *quote)
+/* Connection scheduler */
+static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
 {
        struct conn_hash *h = &hdev->conn_hash;
        struct hci_conn *conn = NULL;
-       int i, num = 0, min = 0xffff;
+       int num = 0, min = 0xffff;
+        struct list_head *p;
 
        conn_hash_lock(h);
-       for (i = 0; i < HCI_MAX_CONN; i++) {
-               struct hci_conn *c;
+       list_for_each(p, &h->list) {
+               register struct hci_conn *c;
 
-               if (!(c = __conn_hash_lookup(h,i)) || !skb_queue_len(&c->acl_q))
+               c = list_entry(p, struct hci_conn, list);
+
+               if (c->type != type || skb_queue_empty(&c->data_q))
                        continue;
                num++;
 
-               if (c->acl_sent < min) {
-                       min  = c->acl_sent;
+               if (c->sent < min) {
+                       min  = c->sent;
                        conn = c;
                }
        }
@@ -773,67 +1104,56 @@ static __inline__ struct hci_conn *hci_low_acl_sent(struct hci_dev *hdev, int *q
        return conn;
 }
 
-static __inline__ void hci_sched_acl(struct hci_dev *hdev)
+static inline void hci_sched_acl(struct hci_dev *hdev)
 {
        struct hci_conn *conn;
-       struct sk_buff *skb, *frag;
+       struct sk_buff *skb;
        int quote;
 
        DBG("%s", hdev->name);
 
-       while (hdev->acl_cnt) {
-               if (!(conn = hci_low_acl_sent(hdev, &quote)))
-                       break;
-
-               while (quote && (skb = skb_peek(&conn->acl_q))) {
-                       if (bluez_skb_frags(skb)+1 > hdev->acl_cnt) {
-                               /* FIXME: Schedule next connection */
-                               goto done;
-                       }
-
-                       if (!(frag = bluez_skb_clone(skb, GFP_ATOMIC)))
-                               break;
-
-                       skb_unlink(skb);
-                       do {
-                               DBG("frag %p len %d", frag, frag->len);
+       while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, &quote))) {
+               while (quote && (skb = skb_dequeue(&conn->data_q))) {
+                       DBG("skb %p len %d", skb, skb->len);
 
-                               hci_send_frame(frag);
+                       hci_send_frame(skb);
 
-                               conn->acl_sent++;
-                               hdev->acl_cnt--;
-                               quote--;
-                       } while ((frag = bluez_skb_get_frag(skb)));
-                       kfree_skb(skb);
+                       conn->sent++;
+                       hdev->acl_cnt--;
+                       quote--;
                }
        }
-done:
-       return;
 }
 
 /* Schedule SCO */
-static __inline__ void hci_sched_sco(struct hci_dev *hdev)
+static inline void hci_sched_sco(struct hci_dev *hdev)
 {
-       struct conn_hash *h = &hdev->conn_hash;
-       struct sk_buff *skb;
-       int i;
+       /* FIXME: For now we queue SCO packets to the raw queue 
 
-       DBG("%s", hdev->name);
-
-       conn_hash_lock(h);
-       for (i = 0; i< HCI_MAX_CONN; i++) {
-               struct hci_conn *conn;
-
-               if (!(conn = __conn_hash_lookup(h, i)))
-                       continue;
-
-               while (hdev->sco_cnt && (skb = skb_dequeue(&conn->sco_q))) {
+               while (hdev->sco_cnt && (skb = skb_dequeue(&conn->data_q))) {
                        hci_send_frame(skb);
                        conn->sco_sent++;
                        hdev->sco_cnt--;
                }
-       }
-       conn_hash_unlock(h);
+       */
+}
+
+/* Get data from the previously sent command */
+static void * hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
+{
+       hci_command_hdr *hc;
+
+       if (!hdev->sent_cmd)
+               return NULL;
+
+       hc = (void *) hdev->sent_cmd->data;
+
+       if (hc->opcode != __cpu_to_le16(cmd_opcode_pack(ogf, ocf)))
+               return NULL;
+
+       DBG("%s ogf 0x%x ocf 0x%x", hdev->name, ogf, ocf);
+
+       return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
 }
 
 /* Send raw HCI frame */
@@ -842,31 +1162,31 @@ int hci_send_raw(struct sk_buff *skb)
        struct hci_dev *hdev = (struct hci_dev *) skb->dev;
 
        if (!hdev) {
-               bluez_skb_free(skb);
+               kfree_skb(skb);
                return -ENODEV;
        }
 
        DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
 
-       /* Queue frame according it's type */
-       switch (skb->pkt_type) {
-       case HCI_COMMAND_PKT:
-               skb_queue_tail(&hdev->cmd_q, skb);
-               hci_sched_cmd(hdev);
-               break;
-
-       case HCI_ACLDATA_PKT:
-       case HCI_SCODATA_PKT:
-               /* FIXME:
-                * Check header here and queue to aproptiate connection.
-                */
-       default:
-               skb_queue_tail(&hdev->raw_q, skb);
-               hci_sched_tx(hdev);
+       if (hdev->flags & HCI_NORMAL) {
+               /* Queue frame according it's type */
+               switch (skb->pkt_type) {
+               case HCI_COMMAND_PKT:
+                       skb_queue_tail(&hdev->cmd_q, skb);
+                       hci_sched_cmd(hdev);
+                       return 0;
 
-               return 0;
-       };
+               case HCI_ACLDATA_PKT:
+               case HCI_SCODATA_PKT:
+                       /* FIXME:
+                        * Check header here and queue to apropriate connection.
+                        */
+                       break;
+               }
+       }
 
+       skb_queue_tail(&hdev->raw_q, skb);
+       hci_sched_tx(hdev);
        return 0;
 }
 
@@ -885,7 +1205,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *p
        }
        
        hc = (hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
-       hc->opcode = __cpu_to_le16(cmd_opcode_pack(ocf, ogf));
+       hc->opcode = __cpu_to_le16(cmd_opcode_pack(ogf, ocf));
        hc->plen   = plen;
 
        if (plen)
@@ -902,7 +1222,6 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *p
 }
 
 /* Send ACL data */
-
 static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
 {
        int len = skb->len;     
@@ -918,30 +1237,46 @@ static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
 int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
 {
        struct hci_dev *hdev = conn->hdev;
-       struct sk_buff *frag;
-       int sent = 0;
+       struct sk_buff *list;
 
-       DBG("%s conn %p len %d flags 0x%x", hdev->name, conn, skb->len, flags);
-       DBG("frags %d", bluez_skb_frags(skb));
+       DBG("%s conn %p flags 0x%x", hdev->name, conn, flags);
 
-       /* Add ACL header to all fragments */
-       flags |= ACL_START;
-       frag = skb;
-       do {
-               DBG("frag %p len %d", frag, frag->len);
-               sent += frag->len;
+       skb->dev = (void *) hdev;
+       skb->pkt_type = HCI_ACLDATA_PKT;
+       hci_add_acl_hdr(skb, conn->handle, flags | ACL_START);
 
-               hci_add_acl_hdr(frag, conn->handle, flags);
-               frag->pkt_type = HCI_ACLDATA_PKT;
-               frag->dev = (void *) hdev;
+       if (!(list = skb_shinfo(skb)->frag_list)) {
+               /* Non fragmented */
+               DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
+               
+               skb_queue_tail(&conn->data_q, skb);
+       } else {
+               /* Fragmented */
+               DBG("%s frag %p len %d", hdev->name, skb, skb->len);
 
-               flags = ACL_CONT;
-       } while ((frag = bluez_skb_next_frag(frag)));
+               skb_shinfo(skb)->frag_list = NULL;
 
-       skb_queue_tail(&conn->acl_q, skb);
-       hci_sched_tx(hdev);
+               /* Queue all fragments atomically */
+               spin_lock_bh(&conn->data_q.lock);
+
+               __skb_queue_tail(&conn->data_q, skb);
+               do {
+                       skb = list; list = list->next;
+                       
+                       skb->dev = (void *) hdev;
+                       skb->pkt_type = HCI_ACLDATA_PKT;
+                       hci_add_acl_hdr(skb, conn->handle, flags | ACL_CONT);
+               
+                       DBG("%s frag %p len %d", hdev->name, skb, skb->len);
 
-       return sent;
+                       __skb_queue_tail(&conn->data_q, skb);
+               } while (list);
+
+               spin_unlock_bh(&conn->data_q.lock);
+       }
+               
+       hci_sched_tx(hdev);
+       return 0;
 }
 
 /* Send SCO data */
@@ -953,7 +1288,7 @@ int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
        DBG("%s len %d", hdev->name, skb->len);
 
        if (skb->len > hdev->sco_mtu) {
-               bluez_skb_free(skb);
+               kfree_skb(skb);
                return -EINVAL;
        }
 
@@ -965,7 +1300,7 @@ int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
 
        skb->dev = (void *) hdev;
        skb->pkt_type = HCI_SCODATA_PKT;
-       skb_queue_tail(&conn->sco_q, skb);
+       skb_queue_tail(&conn->data_q, skb);
        hci_sched_tx(hdev);
 
        return 0;
@@ -1001,6 +1336,8 @@ static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *
 static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
 {
        __u8 status, param;
+       void *sent;
+
 
        DBG("%s ocf 0x%x", hdev->name, ocf);
 
@@ -1022,8 +1359,11 @@ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb
                break;
 
        case OCF_WRITE_AUTH_ENABLE:
+               if (!(sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE)))
+                       break;
+
                status = *((__u8 *) skb->data);
-               param  = *(SENT_CMD_PARAM(hdev));
+               param  = *((__u8 *) sent);
 
                if (!status) {
                        if (param == AUTH_ENABLED)
@@ -1055,8 +1395,12 @@ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb
                break;
 
        case OCF_WRITE_SCAN_ENABLE:
+               if (!(sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE)))
+                       break;
                status = *((__u8 *) skb->data);
-               param  = *(SENT_CMD_PARAM(hdev));
+               param  = *((__u8 *) sent);
+
+               DBG("param 0x%x", param);
 
                if (!status) {
                        switch (param) {
@@ -1091,24 +1435,47 @@ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb
 /* Command Complete OGF INFO_PARAM  */
 static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
 {
-       read_buffer_size_rp *rsp;
-       read_bd_addr_rp *rap;
+       read_local_features_rp *lf;
+       read_buffer_size_rp *bs;
+       read_bd_addr_rp *ba;
 
        DBG("%s ocf 0x%x", hdev->name, ocf);
 
        switch (ocf) {
+       case OCF_READ_LOCAL_FEATURES:
+               lf = (read_local_features_rp *) skb->data;
+
+               if (lf->status) {
+                       DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status);
+                       break;
+               }
+
+               memcpy(hdev->features, lf->features, sizeof(hdev->features));
+
+               /* Adjust default settings according to features 
+                * supported by device. */
+               if (hdev->features[0] & LMP_3SLOT)
+                       hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
+
+               if (hdev->features[0] & LMP_5SLOT)
+                       hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
+
+               DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, lf->features[0], lf->features[1], lf->features[2]);
+
+               break;
+
        case OCF_READ_BUFFER_SIZE:
-               rsp = (read_buffer_size_rp *) skb->data;
+               bs = (read_buffer_size_rp *) skb->data;
 
-               if (rsp->status) {
-                       DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, rsp->status);
+               if (bs->status) {
+                       DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status);
                        break;
                }
 
-               hdev->acl_mtu = __le16_to_cpu(rsp->acl_mtu);
-               hdev->sco_mtu = rsp->sco_mtu;
-               hdev->acl_max = hdev->acl_cnt = __le16_to_cpu(rsp->acl_max_pkt);
-               hdev->sco_max = hdev->sco_cnt = __le16_to_cpu(rsp->sco_max_pkt);
+               hdev->acl_mtu = __le16_to_cpu(bs->acl_mtu);
+               hdev->sco_mtu = bs->sco_mtu;
+               hdev->acl_max = hdev->acl_cnt = __le16_to_cpu(bs->acl_max_pkt);
+               hdev->sco_max = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt);
 
                DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
                    hdev->acl_mtu, hdev->sco_mtu, hdev->acl_max, hdev->sco_max);
@@ -1116,15 +1483,15 @@ static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *s
                break;
 
        case OCF_READ_BD_ADDR:
-               rap = (read_bd_addr_rp *) skb->data;
+               ba = (read_bd_addr_rp *) skb->data;
 
-               if (!rap->status) {
-                       bacpy(&hdev->bdaddr, &rap->bdaddr);
+               if (!ba->status) {
+                       bacpy(&hdev->bdaddr, &ba->bdaddr);
                } else {
-                       DBG("%s: READ_BD_ADDR failed %d", hdev->name, rap->status);
+                       DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status);
                }
 
-               hci_req_complete(hdev, rap->status);
+               hci_req_complete(hdev, ba->status);
                break;
 
        default:
@@ -1143,7 +1510,11 @@ static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
        switch (ocf) {
        case OCF_CREATE_CONN:
                if (status) {
-                       create_conn_cp *cc = (void *) SENT_CMD_PARAM(hdev);
+                       create_conn_cp *cc = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_CREATE_CONN);
+
+                       if (!cc)
+                               break;
+
                        DBG("%s Create connection error: status 0x%x %s", hdev->name,
                            status, batostr(&cc->bdaddr));
 
@@ -1235,13 +1606,20 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
        accept_conn_req_cp ac;
        int accept = 0;
 
-       DBG("%s Connection request: %s type 0x%x", hdev->name, batostr(&cr->bdaddr), cr->type);
+       DBG("%s Connection request: %s type 0x%x", hdev->name, batostr(&cr->bdaddr), cr->link_type);
 
        /* Notify upper protocols */
-       if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_ind) {
-               tasklet_disable(&hdev->tx_task);
-               accept = hp->connect_ind(hdev, &cr->bdaddr);
-               tasklet_enable(&hdev->tx_task);
+       if (cr->link_type == ACL_LINK) {
+               /* ACL link notify L2CAP */
+               if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_ind) {
+                       tasklet_disable(&hdev->tx_task);
+                       accept = hp->connect_ind(hdev, &cr->bdaddr);
+                       tasklet_enable(&hdev->tx_task);
+               }
+       } else {
+               /* SCO link (no notification) */
+               /* FIXME: Should be accept it here or let the requester (app) accept it ? */
+               accept = 1;
        }
 
        if (accept) {
@@ -1270,11 +1648,16 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
        tasklet_disable(&hdev->tx_task);
 
        if (!cc->status)
-               conn = hci_conn_add(hdev, __le16_to_cpu(cc->handle), &cc->bdaddr);
+               conn = hci_conn_add(hdev, __le16_to_cpu(cc->handle), cc->link_type, &cc->bdaddr);
 
        /* Notify upper protocols */
-       if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_cfm)
-               hp->connect_cfm(hdev, &cc->bdaddr, cc->status, conn);
+       if (cc->link_type == ACL_LINK) {
+               /* ACL link notify L2CAP layer */
+               if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_cfm)
+                       hp->connect_cfm(hdev, &cc->bdaddr, cc->status, conn);
+       } else {
+               /* SCO link (no notification) */
+       }
 
        tasklet_enable(&hdev->tx_task);
 }
@@ -1293,8 +1676,13 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
                tasklet_disable(&hdev->tx_task);
 
                /* Notify upper protocols */
-               if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->disconn_ind)
-                       hp->disconn_ind(conn, dc->reason);
+               if (conn->type == ACL_LINK) {
+                       /* ACL link notify L2CAP layer */
+                       if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->disconn_ind)
+                               hp->disconn_ind(conn, dc->reason);
+               } else {
+                       /* SCO link (no notification) */
+               }
 
                hci_conn_del(hdev, conn);
 
@@ -1324,13 +1712,13 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
                struct hci_conn *conn;
                __u16 handle, count;
 
-               handle = __le16_to_cpu(*ptr++);
-               count  = __le16_to_cpu(*ptr++);
+               handle = __le16_to_cpu(get_unaligned(ptr++));
+               count  = __le16_to_cpu(get_unaligned(ptr++));
 
                hdev->acl_cnt += count;
 
                if ((conn = conn_hash_lookup(&hdev->conn_hash, handle)))
-                       conn->acl_sent -= count;
+                       conn->sent -= count;
        }
 
        tasklet_enable(&hdev->tx_task);
@@ -1338,7 +1726,7 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
        hci_sched_tx(hdev);
 }
 
-static __inline__ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
 {
        hci_event_hdr *he = (hci_event_hdr *) skb->data;
        evt_cmd_status *cs;
@@ -1382,11 +1770,6 @@ static __inline__ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *sk
                ogf = cmd_opcode_ogf(opcode);
                ocf = cmd_opcode_ocf(opcode);
 
-               if (cs->ncmd) {
-                       atomic_set(&hdev->cmd_cnt, 1);
-                       hci_sched_cmd(hdev);
-               }
-
                switch (ogf) {
                case OGF_INFO_PARAM:
                        hci_cs_info_param(hdev, ocf, cs->status);
@@ -1409,6 +1792,11 @@ static __inline__ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *sk
                        break;
                };
 
+               if (cs->ncmd) {
+                       atomic_set(&hdev->cmd_cnt, 1);
+                       if (!skb_queue_empty(&hdev->cmd_q))
+                               hci_sched_cmd(hdev);
+               }
                break;
 
        case EVT_CMD_COMPLETE:
@@ -1419,11 +1807,6 @@ static __inline__ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *sk
                ogf = cmd_opcode_ogf(opcode);
                ocf = cmd_opcode_ocf(opcode);
 
-               if (ec->ncmd) {
-                       atomic_set(&hdev->cmd_cnt, 1);
-                       hci_sched_cmd(hdev);
-               }
-
                switch (ogf) {
                case OGF_INFO_PARAM:
                        hci_cc_info_param(hdev, ocf, skb);
@@ -1446,15 +1829,20 @@ static __inline__ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *sk
                        break;
                };
 
+               if (ec->ncmd) {
+                       atomic_set(&hdev->cmd_cnt, 1);
+                       if (!skb_queue_empty(&hdev->cmd_q))
+                               hci_sched_cmd(hdev);
+               }
                break;
        };
 
-       bluez_skb_free(skb);
+       kfree_skb(skb);
        hdev->stat.evt_rx++;
 }
 
 /* ACL data packet */
-static __inline__ void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
 {
        hci_acl_hdr *ah = (void *) skb->data;
        struct hci_conn *conn;
@@ -1469,38 +1857,28 @@ static __inline__ void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *
        DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
 
        if ((conn = conn_hash_lookup(&hdev->conn_hash, handle))) {
-               struct hci_proto *hp;
+               register struct hci_proto *hp;
 
                /* Send to upper protocol */
-               if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->recv_acldata)
+               if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->recv_acldata) {
                        hp->recv_acldata(conn, skb, flags);
-               else
-                       bluez_skb_free(skb);
+                       goto sent;
+               }
+       } else {
+               ERR("%s ACL packet for unknown connection handle %d", hdev->name, handle);
        }
 
+       kfree_skb(skb);
+sent:
        hdev->stat.acl_rx++;
 }
 
 /* SCO data packet */
-static __inline__ void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
 {
-       hci_sco_hdr *sh = (void *) skb->data;
-       struct hci_conn *conn;
-
-       skb_pull(skb, HCI_SCO_HDR_SIZE);
-
        DBG("%s len %d", hdev->name, skb->len);
 
-       if ((conn = conn_hash_lookup(&hdev->conn_hash, __le16_to_cpu(sh->handle)))) {
-               struct hci_proto *hp;
-
-               /* Send to upper protocol */
-               if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->recv_acldata)
-                       hp->recv_scodata(conn, skb);
-               else
-                       bluez_skb_free(skb);
-       }
-
+       kfree_skb(skb);
        hdev->stat.sco_rx++;
 }
 
@@ -1525,13 +1903,13 @@ void hci_rx_task(unsigned long arg)
                        switch (skb->pkt_type) {
                        case HCI_ACLDATA_PKT:
                        case HCI_SCODATA_PKT:
-                               bluez_skb_free(skb);
+                               kfree_skb(skb);
                                continue;
                        };
                }
 
                if (hdev->flags & HCI_NORMAL) {
-                       /* Handle frame */
+                       /* Process frame */
                        switch (skb->pkt_type) {
                        case HCI_EVENT_PKT:
                                hci_event_packet(hdev, skb);
@@ -1548,11 +1926,11 @@ void hci_rx_task(unsigned long arg)
                                break;
 
                        default:
-                               bluez_skb_free(skb);
+                               kfree_skb(skb);
                                break;
                        };
                } else {
-                       bluez_skb_free(skb);
+                       kfree_skb(skb);
                }
        }
 
@@ -1574,7 +1952,7 @@ static void hci_tx_task(unsigned long arg)
 
        hci_sched_sco(hdev);
 
-       /* Send next queued raw(unknown type) packet */
+       /* Send next queued raw (unknown type) packet */
        while ((skb = skb_dequeue(&hdev->raw_q)))
                hci_send_frame(skb);
 
@@ -1590,10 +1968,10 @@ static void hci_cmd_task(unsigned long arg)
 
        /* Send queued commands */
        if (atomic_read(&hdev->cmd_cnt) && (skb = skb_dequeue(&hdev->cmd_q))) {
-               if (hdev->cmd_sent)
-                       bluez_skb_free(hdev->cmd_sent);
+               if (hdev->sent_cmd)
+                       kfree_skb(hdev->sent_cmd);
 
-               if ((hdev->cmd_sent = bluez_skb_clone(skb, GFP_ATOMIC))) {
+               if ((hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC))) {
                        atomic_dec(&hdev->cmd_cnt);
                        hci_send_frame(skb);
                } else {
@@ -1609,7 +1987,7 @@ int hci_recv_frame(struct sk_buff *skb)
        struct hci_dev *hdev = (struct hci_dev *) skb->dev;
 
        if (!hdev || !(hdev->flags & (HCI_UP | HCI_INIT))) {
-               bluez_skb_free(skb);
+               kfree_skb(skb);
                return -1;
        }
 
@@ -1625,237 +2003,6 @@ int hci_recv_frame(struct sk_buff *skb)
        return 0;
 }
 
-/* ----- HCI Ioctl helpers ----- */
-int hci_dev_reset(__u16 dev)
-{
-       struct hci_dev *hdev;
-       int ret = 0;
-
-       if (!(hdev = hci_dev_get(dev)))
-               return -ENODEV;
-
-       hci_req_lock(hdev);
-       tasklet_disable(&hdev->tx_task);
-
-       if (!(hdev->flags & HCI_UP))
-               goto done;
-
-       /* Drop queues */
-       bluez_skb_queue_purge(&hdev->rx_q);
-       bluez_skb_queue_purge(&hdev->cmd_q);
-
-       inquiry_cache_flush(&hdev->inq_cache);
-
-       hci_conn_hash_flush(hdev);
-
-       if (hdev->flush)
-               hdev->flush(hdev);
-
-       atomic_set(&hdev->cmd_cnt, 1); 
-       hdev->acl_cnt = 0; hdev->sco_cnt = 0;
-
-       ret = __hci_request(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
-
-done:
-       tasklet_enable(&hdev->tx_task);
-       hci_req_unlock(hdev);
-       hci_dev_put(hdev);
-
-       return ret;
-}
-
-int hci_dev_reset_stat(__u16 dev)
-{
-       struct hci_dev *hdev;
-       int ret = 0;
-
-       if (!(hdev = hci_dev_get(dev)))
-               return -ENODEV;
-
-       memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
-
-       hci_dev_put(hdev);
-
-       return ret;
-}
-
-int hci_dev_setauth(unsigned long arg)
-{
-       struct hci_dev *hdev;
-       struct hci_dev_req dr;
-       int ret = 0;
-
-       if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
-               return -EFAULT;
-
-       if (!(hdev = hci_dev_get(dr.dev_id)))
-               return -ENODEV;
-
-       ret = hci_request(hdev, hci_auth_req, dr.dev_opt, HCI_INIT_TIMEOUT);
-
-       hci_dev_put(hdev);
-
-       return ret;
-}
-
-int hci_dev_setscan(unsigned long arg)
-{
-       struct hci_dev *hdev;
-       struct hci_dev_req dr;
-       int ret = 0;
-
-       if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
-               return -EFAULT;
-
-       if (!(hdev = hci_dev_get(dr.dev_id)))
-               return -ENODEV;
-
-       ret = hci_request(hdev, hci_scan_req, dr.dev_opt, HCI_INIT_TIMEOUT);
-
-       hci_dev_put(hdev);
-
-       return ret;
-}
-
-int hci_dev_list(unsigned long arg)
-{
-       struct hci_dev_list_req *dl;
-       struct hci_dev_req *dr;
-       struct hci_dev *hdev;
-       int i, n, size;
-       __u16 dev_num;
-
-       if (get_user(dev_num, (__u16 *) arg))
-               return -EFAULT;
-
-       size = dev_num * sizeof(struct hci_dev_req) + sizeof(__u16);
-
-       if (verify_area(VERIFY_WRITE, (void *) arg, size))
-               return -EFAULT;
-
-       if (!(dl = kmalloc(size, GFP_KERNEL)))
-               return -ENOMEM;
-       dr = dl->dev_req;
-
-       spin_lock_bh(&hdev_list_lock);
-       for (i = 0, n = 0; i < HCI_MAX_DEV && n < dev_num; i++) {
-               if ((hdev = hdev_list[i])) {
-                       (dr + n)->dev_id  = hdev->id;
-                       (dr + n)->dev_opt = hdev->flags;
-                       n++;
-               }
-       }
-       spin_unlock_bh(&hdev_list_lock);
-
-       dl->dev_num = n;
-       size = n * sizeof(struct hci_dev_req) + sizeof(__u16);
-
-       copy_to_user((void *) arg, dl, size);
-
-       return 0;
-}
-
-int hci_dev_info(unsigned long arg)
-{
-       struct hci_dev *hdev;
-       struct hci_dev_info di;
-       int err = 0;
-
-       if (copy_from_user(&di, (void *) arg, sizeof(di)))
-               return -EFAULT;
-
-       if (!(hdev = hci_dev_get(di.dev_id)))
-               return -ENODEV;
-
-       strcpy(di.name, hdev->name);
-       di.type    = hdev->type;
-       di.flags   = hdev->flags;
-       di.acl_mtu = hdev->acl_mtu;
-       di.acl_max = hdev->acl_max;
-       di.sco_mtu = hdev->sco_mtu;
-       di.sco_max = hdev->sco_max;
-       di.bdaddr  = hdev->bdaddr;
-
-       memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
-
-       if (copy_to_user((void *) arg, &di, sizeof(di)))
-               err = -EFAULT;
-
-       hci_dev_put(hdev);
-
-       return err;
-}
-
-__u32 hci_dev_setmode(struct hci_dev *hdev, __u32 mode)
-{
-       __u32 omode = hdev->flags & HCI_MODE_MASK;
-
-       hdev->flags &= ~HCI_MODE_MASK;
-       hdev->flags |= (mode & HCI_MODE_MASK);
-
-       return omode;
-}
-
-__u32 hci_dev_getmode(struct hci_dev *hdev)
-{
-       return hdev->flags & HCI_MODE_MASK;
-}
-
-int hci_inquiry(unsigned long arg)
-{
-       struct inquiry_cache *cache;
-       struct hci_inquiry_req ir;
-       struct hci_dev *hdev;
-       int err = 0, do_inquiry = 0;
-       long timeo;
-       __u8 *buf, *ptr;
-
-       ptr = (void *) arg;
-       if (copy_from_user(&ir, ptr, sizeof(ir)))
-               return -EFAULT;
-
-       if (!(hdev = hci_dev_get(ir.dev_id)))
-               return -ENODEV;
-
-       cache = &hdev->inq_cache;
-
-       inquiry_cache_lock(cache);
-       if (inquiry_cache_age(cache) > INQUIRY_CACHE_AGE_MAX || ir.flags & IREQ_CACHE_FLUSH) {
-               inquiry_cache_flush(cache);
-               do_inquiry = 1;
-       }
-       inquiry_cache_unlock(cache);
-
-       timeo = ir.length * 2 * HZ;
-       if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0)
-               goto done;
-
-       /* cache_dump can't sleep. Therefore we allocate temp buffer and then
-        * copy it to the user space.
-        */
-       if (!(buf = kmalloc(sizeof(inquiry_info) * ir.num_rsp, GFP_KERNEL))) {
-               err = -ENOMEM;
-               goto done;
-       }
-       ir.num_rsp = inquiry_cache_dump(cache, ir.num_rsp, buf);
-
-       DBG("num_rsp %d", ir.num_rsp);
-
-       if (!verify_area(VERIFY_WRITE, ptr, sizeof(ir) + (sizeof(inquiry_info) * ir.num_rsp))) {
-               copy_to_user(ptr, &ir, sizeof(ir));
-               ptr += sizeof(ir);
-               copy_to_user(ptr, buf, sizeof(inquiry_info) * ir.num_rsp);
-       } else 
-               err = -EFAULT;
-
-       kfree(buf);
-
-done:
-       hci_dev_put(hdev);
-
-       return err;
-}
-
 int hci_core_init(void)
 {
        /* Init locks */
index ff1f4d10c430d5c10e636e2f3f863f88f8b7f6b3..89a892f79fd3f6268293158402ef5d5013d6759b 100644 (file)
@@ -25,7 +25,7 @@
 /*
  * BlueZ HCI socket layer.
  *
- * $Id: hci_sock.c,v 1.1 2001/06/01 08:12:11 davem Exp $
+ * $Id: hci_sock.c,v 1.9 2001/08/05 06:02:16 maxk Exp $
  */
 
 #include <linux/config.h>
@@ -36,7 +36,7 @@
 #include <linux/kernel.h>
 #include <linux/major.h>
 #include <linux/sched.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/poll.h>
 #include <linux/fcntl.h>
 #include <linux/init.h>
@@ -81,13 +81,15 @@ static struct sock *hci_sock_lookup(struct hci_dev *hdev)
 /* Send frame to RAW socket */
 void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
 {
-       struct sk_buff *nskb;
        struct sock * sk;
 
        DBG("hdev %p len %d", hdev, skb->len);
 
        read_lock(&hci_sk_list.lock);
        for (sk = hci_sk_list.head; sk; sk = sk->next) {
+               struct hci_filter *flt; 
+               struct sk_buff *nskb;
+
                if (sk->state != BT_BOUND || hci_pi(sk)->hdev != hdev)
                        continue;
 
@@ -95,7 +97,20 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
                if (skb->sk == sk)
                        continue;
 
-               if (!(nskb = bluez_skb_clone(skb, GFP_ATOMIC)))
+               /* Apply filter */
+               flt = &hci_pi(sk)->filter;
+
+               if (!test_bit(skb->pkt_type, &flt->type_mask))
+                       continue;
+
+               if (skb->pkt_type == HCI_EVENT_PKT) {
+                       register int evt = (*(__u8 *)skb->data & 63);
+
+                       if (!test_bit(evt, &flt->event_mask))
+                               continue;
+               }
+
+               if (!(nskb = skb_clone(skb, GFP_ATOMIC)))
                        continue;
 
                /* Put type byte before the data */
@@ -128,8 +143,8 @@ static int hci_sock_release(struct socket *sock)
 
        sock_orphan(sk);
 
-       bluez_skb_queue_purge(&sk->receive_queue);
-       bluez_skb_queue_purge(&sk->write_queue);
+       skb_queue_purge(&sk->receive_queue);
+       skb_queue_purge(&sk->write_queue);
 
        sock_put(sk);
 
@@ -144,7 +159,7 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long a
        struct hci_dev *hdev = hci_pi(sk)->hdev;
        __u32 mode;
 
-       DBG("cmd %x", cmd);
+       DBG("cmd %x arg %lx", cmd, arg);
 
        switch (cmd) {
        case HCIGETINFO:
@@ -156,37 +171,31 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long a
        case HCIDEVUP:
                if (!capable(CAP_NET_ADMIN))
                        return -EACCES;
-
                return hci_dev_open(arg);
 
        case HCIDEVDOWN:
                if (!capable(CAP_NET_ADMIN))
                        return -EACCES;
-
                return hci_dev_close(arg);
 
        case HCIDEVRESET:
                if (!capable(CAP_NET_ADMIN))
                        return -EACCES;
-
                return hci_dev_reset(arg);
 
        case HCIRESETSTAT:
                if (!capable(CAP_NET_ADMIN))
                        return -EACCES;
-
                return hci_dev_reset_stat(arg);
 
        case HCISETSCAN:
                if (!capable(CAP_NET_ADMIN))
                        return -EACCES;
-
                return hci_dev_setscan(arg);
 
        case HCISETAUTH:
                if (!capable(CAP_NET_ADMIN))
                        return -EACCES;
-
                return hci_dev_setauth(arg);
 
        case HCISETRAW:
@@ -203,9 +212,17 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long a
 
                return hci_dev_setmode(hdev, mode);
 
+       case HCISETPTYPE:
+               if (!capable(CAP_NET_ADMIN))
+                       return -EACCES;
+               return hci_dev_setptype(arg);
+
        case HCIINQUIRY:
                return hci_inquiry(arg);
 
+       case HCIGETCONNLIST:
+               return hci_conn_list(arg);
+
        default:
                return -EINVAL;
        };
@@ -291,11 +308,11 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
        return len;
 }
 
-static __inline__ void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
+static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
 {
-       __u32 flags = hci_pi(sk)->cmsg_flags;
+       __u32 mask = hci_pi(sk)->cmsg_mask;
 
-       if (flags & HCI_CMSG_DIR)
+       if (mask & HCI_CMSG_DIR)
                put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(int), &bluez_cb(skb)->incomming);
 }
  
@@ -326,7 +343,7 @@ static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len,
        skb->h.raw = skb->data;
        err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
 
-       if (hci_pi(sk)->cmsg_flags)
+       if (hci_pi(sk)->cmsg_mask)
                hci_sock_cmsg(sk, msg, skb);
 
        skb_free_datagram(sk, skb);
@@ -334,24 +351,34 @@ static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len,
        return err ? : copied;
 }
 
-int hci_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
+int hci_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int len)
 {
        struct sock *sk = sock->sk;
-       int err = 0, opt;
-
-       if (get_user(opt, (int *)optval))
-               return -EFAULT;
+       struct hci_filter flt;
+       int err = 0, opt = 0;
 
-       DBG("sk %p, opt %d", sk, opt);
+       DBG("sk %p, opt %d", sk, optname);
 
        lock_sock(sk);
 
        switch (optname) {
        case HCI_DATA_DIR:
+               if (get_user(opt, (int *)optval))
+                       return -EFAULT;
+
                if (opt)
-                       hci_pi(sk)->cmsg_flags |= HCI_CMSG_DIR;
+                       hci_pi(sk)->cmsg_mask |= HCI_CMSG_DIR;
                else
-                       hci_pi(sk)->cmsg_flags &= ~HCI_CMSG_DIR;
+                       hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_DIR;
+               break;
+
+       case HCI_FILTER:
+               len = MIN(len, sizeof(struct hci_filter));
+               if (copy_from_user(&flt, optval, len)) {
+                       err = -EFAULT;
+                       break;
+               }
+               memcpy(&hci_pi(sk)->filter, &flt, len);
                break;
 
        default:
@@ -373,7 +400,7 @@ int hci_sock_getsockopt(struct socket *sock, int level, int optname, char *optva
 
        switch (optname) {
        case HCI_DATA_DIR:
-               if (hci_pi(sk)->cmsg_flags & HCI_CMSG_DIR)
+               if (hci_pi(sk)->cmsg_mask & HCI_CMSG_DIR)
                        opt = 1;
                else 
                        opt = 0;
@@ -382,6 +409,12 @@ int hci_sock_getsockopt(struct socket *sock, int level, int optname, char *optva
                        return -EFAULT;
                break;
 
+       case HCI_FILTER:
+               len = MIN(len, sizeof(struct hci_filter));
+               if (copy_to_user(optval, &hci_pi(sk)->filter, len))
+                       return -EFAULT;
+               break;
+
        default:
                return -ENOPROTOOPT;
                break;
@@ -431,6 +464,11 @@ static int hci_sock_create(struct socket *sock, int protocol)
        sk->protocol = protocol;
        sk->state    = BT_OPEN;
 
+       /* Initialize filter */
+       hci_pi(sk)->filter.type_mask  = (1<<HCI_EVENT_PKT);
+       hci_pi(sk)->filter.event_mask[0] = ~0L;
+       hci_pi(sk)->filter.event_mask[1] = ~0L;
+
        bluez_sock_link(&hci_sk_list, sk);
 
        MOD_INC_USE_COUNT;
@@ -455,7 +493,7 @@ static int hci_sock_dev_event(struct notifier_block *this, unsigned long event,
                memcpy(skb_put(skb, EVT_HCI_DEV_EVENT_SIZE), &he, EVT_HCI_DEV_EVENT_SIZE);
 
                hci_send_to_sock(NULL, skb);
-               bluez_skb_free(skb);
+               kfree_skb(skb);
        }
 
        if (event == HCI_DEV_UNREG) {
index bced9819054ee2bed5c6b841f36f97480a57facd..73e0e4df1479a83ecae3ea5fd35b73070e1df9bb 100644 (file)
@@ -25,8 +25,9 @@
 /*
  * BlueZ L2CAP core and sockets.
  *
- * $Id: l2cap_core.c,v 1.1 2001/06/01 08:12:11 davem Exp $
+ * $Id: l2cap_core.c,v 1.19 2001/08/03 04:19:50 maxk Exp $
  */
+#define VERSION "1.1"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -36,7 +37,7 @@
 #include <linux/kernel.h>
 #include <linux/major.h>
 #include <linux/sched.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/poll.h>
 #include <linux/fcntl.h>
 #include <linux/init.h>
@@ -73,7 +74,7 @@ rwlock_t l2cap_rt_lock = RW_LOCK_UNLOCKED;
 
 static int  l2cap_conn_del(struct l2cap_conn *conn, int err);
 
-static __inline__ void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent);
+static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent);
 static void l2cap_chan_del(struct sock *sk, int err);
 static int  l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len);
 
@@ -176,7 +177,7 @@ static struct l2cap_iff *l2cap_get_route(bdaddr_t *src, bdaddr_t *dst)
 }
 
 /* ----- L2CAP timers ------ */
-static void l2cap_timeout(unsigned long arg)
+static void l2cap_sock_timeout(unsigned long arg)
 {
        struct sock *sk = (struct sock *) arg;
 
@@ -199,7 +200,7 @@ static void l2cap_timeout(unsigned long arg)
        sock_put(sk);
 }
 
-static void l2cap_set_timer(struct sock *sk, long timeout)
+static void l2cap_sock_set_timer(struct sock *sk, long timeout)
 {
        DBG("sock %p state %d timeout %ld", sk, sk->state, timeout);
 
@@ -207,7 +208,7 @@ static void l2cap_set_timer(struct sock *sk, long timeout)
                sock_hold(sk);
 }
 
-static void l2cap_clear_timer(struct sock *sk)
+static void l2cap_sock_clear_timer(struct sock *sk)
 {
        DBG("sock %p state %d", sk, sk->state);
 
@@ -215,13 +216,47 @@ static void l2cap_clear_timer(struct sock *sk)
                __sock_put(sk);
 }
 
-static void l2cap_init_timer(struct sock *sk)
+static void l2cap_sock_init_timer(struct sock *sk)
 {
        init_timer(&sk->timer);
-       sk->timer.function = l2cap_timeout;
+       sk->timer.function = l2cap_sock_timeout;
        sk->timer.data = (unsigned long)sk;
 }
 
+static void l2cap_conn_timeout(unsigned long arg)
+{
+       struct l2cap_conn *conn = (void *)arg;
+       
+       DBG("conn %p state %d", conn, conn->state);
+
+       if (conn->state == BT_CONNECTED) {
+               hci_disconnect(conn->hconn, 0x13);
+       }
+               
+       return;
+}
+
+static void l2cap_conn_set_timer(struct l2cap_conn *conn, long timeout)
+{
+       DBG("conn %p state %d timeout %ld", conn, conn->state, timeout);
+
+       mod_timer(&conn->timer, jiffies + timeout);
+}
+
+static void l2cap_conn_clear_timer(struct l2cap_conn *conn)
+{
+       DBG("conn %p state %d", conn, conn->state);
+
+       del_timer(&conn->timer);
+}
+
+static void l2cap_conn_init_timer(struct l2cap_conn *conn)
+{
+       init_timer(&conn->timer);
+       conn->timer.function = l2cap_conn_timeout;
+       conn->timer.data = (unsigned long)conn;
+}
+
 /* -------- L2CAP connections --------- */
 /* Add new connection to the interface.
  * Interface must be locked
@@ -244,6 +279,8 @@ static struct l2cap_conn *l2cap_conn_add(struct l2cap_iff *iff, bdaddr_t *dst)
        spin_lock_init(&conn->lock);
        conn->chan_list.lock = RW_LOCK_UNLOCKED;
 
+       l2cap_conn_init_timer(conn);
+       
        __l2cap_conn_link(iff, conn);
 
        DBG("%s -> %s, %p", batostr(src), batostr(dst), conn);
@@ -262,17 +299,18 @@ static int l2cap_conn_del(struct l2cap_conn *conn, int err)
 
        DBG("conn %p, state %d, err %d", conn, conn->state, err);
 
+       l2cap_conn_clear_timer(conn);
        __l2cap_conn_unlink(conn->iff, conn);
 
        conn->state = BT_CLOSED;
 
        if (conn->rx_skb)
-               bluez_skb_free(conn->rx_skb);
+               kfree_skb(conn->rx_skb);
 
        /* Kill channels */
        while ((sk = conn->chan_list.head)) {
                bh_lock_sock(sk);
-               l2cap_clear_timer(sk);
+               l2cap_sock_clear_timer(sk);
                l2cap_chan_del(sk, err);
                bh_unlock_sock(sk);
 
@@ -285,11 +323,11 @@ static int l2cap_conn_del(struct l2cap_conn *conn, int err)
        return 0;
 }
 
-static __inline__ struct l2cap_conn *l2cap_get_conn_by_addr(struct l2cap_iff *iff, bdaddr_t *dst)
+static inline struct l2cap_conn *l2cap_get_conn_by_addr(struct l2cap_iff *iff, bdaddr_t *dst)
 {
        struct list_head *p;
 
-       list_for_each(p, &iff->conn_list){
+       list_for_each(p, &iff->conn_list) {
                struct l2cap_conn *c;
 
                c = list_entry(p, struct l2cap_conn, list);
@@ -337,7 +375,7 @@ int l2cap_connect(struct sock *sk)
        l2cap_chan_add(conn, sk, NULL);
 
        sk->state = BT_CONNECT;
-       l2cap_set_timer(sk, sk->sndtimeo);
+       l2cap_sock_set_timer(sk, sk->sndtimeo);
 
        switch (conn->state) {
        case BT_CONNECTED:
@@ -347,8 +385,8 @@ int l2cap_connect(struct sock *sk)
                        req.psm  = l2cap_pi(sk)->psm;
                        l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
                } else {
+                       l2cap_sock_clear_timer(sk);
                        sk->state = BT_CONNECTED;
-                       l2cap_clear_timer(sk);
                }
                break;
 
@@ -364,7 +402,6 @@ int l2cap_connect(struct sock *sk)
 
 done:
        read_unlock_bh(&l2cap_rt_lock);
-
        return err;
 }
 
@@ -425,7 +462,7 @@ struct sock *l2cap_accept_dequeue(struct sock *parent, int state)
        struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
        struct sock *sk;
 
-       for (sk = q->head; sk; sk = l2cap_pi(sk)->next_q){
+       for (sk = q->head; sk; sk = l2cap_pi(sk)->next_q) {
                if (!state || sk->state == state) {
                        l2cap_accept_unlink(sk);
                        break;
@@ -490,8 +527,8 @@ static void l2cap_sock_destruct(struct sock *sk)
 {
        DBG("sk %p", sk);
 
-       bluez_skb_queue_purge(&sk->receive_queue);
-       bluez_skb_queue_purge(&sk->write_queue);
+       skb_queue_purge(&sk->receive_queue);
+       skb_queue_purge(&sk->write_queue);
 
        MOD_DEC_USE_COUNT;
 }
@@ -533,6 +570,8 @@ static void l2cap_sock_close(struct sock *sk)
 {
        struct l2cap_conn *conn;
 
+       l2cap_sock_clear_timer(sk);
+
        lock_sock(sk);
 
        conn = l2cap_pi(sk)->conn;
@@ -555,7 +594,7 @@ static void l2cap_sock_close(struct sock *sk)
                        req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
                        l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
 
-                       l2cap_set_timer(sk, sk->sndtimeo);
+                       l2cap_sock_set_timer(sk, sk->sndtimeo);
                } else {
                        l2cap_chan_del(sk, ECONNRESET);
                }
@@ -614,7 +653,7 @@ static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, int prio)
        sk->protocol = proto;
        sk->state    = BT_OPEN;
 
-       l2cap_init_timer(sk);
+       l2cap_sock_init_timer(sk);
 
        bluez_sock_link(&l2cap_sk_list, sk);
 
@@ -689,6 +728,8 @@ static int l2cap_sock_w4_connect(struct sock *sk, int flags)
        long timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
        int err = 0;
 
+       DBG("sk %p", sk);
+
        add_wait_queue(sk->sleep, &wait);
        current->state = TASK_INTERRUPTIBLE;
 
@@ -951,7 +992,6 @@ int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char *opt
        };
 
        release_sock(sk);
-
        return err;
 }
 
@@ -959,11 +999,14 @@ int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char *opt
 {
        struct sock *sk = sock->sk;
        struct l2cap_options opts;
-       int len; 
+       struct l2cap_conninfo cinfo;
+       int len, err = 0; 
 
        if (get_user(len, optlen))
                return -EFAULT;
 
+       lock_sock(sk);
+
        switch (optname) {
        case L2CAP_OPTIONS:
                opts.imtu     = l2cap_pi(sk)->imtu;
@@ -972,16 +1015,63 @@ int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char *opt
 
                len = MIN(len, sizeof(opts));
                if (copy_to_user(optval, (char *)&opts, len))
-                       return -EFAULT;
+                       err = -EFAULT;
+
+               break;
+
+       case L2CAP_CONNINFO:
+               if (sk->state != BT_CONNECTED) {
+                       err = -ENOTCONN;
+                       break;
+               }
+
+               cinfo.hci_handle = l2cap_pi(sk)->conn->hconn->handle;
+
+               len = MIN(len, sizeof(cinfo));
+               if (copy_to_user(optval, (char *)&cinfo, len))
+                       err = -EFAULT;
 
                break;
 
        default:
-               return -ENOPROTOOPT;
+               err = -ENOPROTOOPT;
                break;
        };
 
-       return 0;
+       release_sock(sk);
+       return err;
+}
+
+static unsigned int l2cap_sock_poll(struct file * file, struct socket *sock, poll_table *wait)
+{
+       struct sock *sk = sock->sk;
+       struct l2cap_accept_q *aq;
+       unsigned int mask;
+
+       DBG("sock %p, sk %p", sock, sk);
+
+       poll_wait(file, sk->sleep, wait);
+       mask = 0;
+
+       if (sk->err || !skb_queue_empty(&sk->error_queue))
+               mask |= POLLERR;
+
+       if (sk->shutdown == SHUTDOWN_MASK)
+               mask |= POLLHUP;
+
+       aq = &l2cap_pi(sk)->accept_q;
+       if (!skb_queue_empty(&sk->receive_queue) || aq->head || (sk->shutdown & RCV_SHUTDOWN))
+               mask |= POLLIN | POLLRDNORM;
+
+       if (sk->state == BT_CLOSED)
+               mask |= POLLHUP;
+
+       if (sock_writeable(sk))
+               mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
+       else
+               set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
+
+       return mask;
 }
 
 static int l2cap_sock_release(struct socket *sock)
@@ -1013,7 +1103,7 @@ static struct sock * __l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 c
        return s;
 }
 
-static __inline__ struct sock *l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
+static inline struct sock *l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
 {
        struct sock *s;
 
@@ -1035,7 +1125,7 @@ static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 ci
 
        return s;
 }
-static __inline__ struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
+static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
 {
        struct sock *s;
 
@@ -1058,7 +1148,7 @@ static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, __u8 id
        return s;
 }
 
-static __inline__ struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, __u8 ident)
+static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, __u8 ident)
 {
        struct sock *s;
 
@@ -1081,7 +1171,7 @@ static __u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
        return 0;
 }
 
-static __inline__ void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
+static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
 {
        sock_hold(sk);
 
@@ -1093,7 +1183,7 @@ static __inline__ void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock
        l->head = sk;
 }
 
-static __inline__ void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
+static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
 {
        struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
 
@@ -1116,6 +1206,8 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct so
 
        DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
 
+       l2cap_conn_clear_timer(conn);
+
        atomic_inc(&conn->refcnt);
        l2cap_pi(sk)->conn = conn;
 
@@ -1135,7 +1227,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct so
                l2cap_accept_queue(parent, sk);
 }
 
-static __inline__ void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
+static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
 {
        struct l2cap_chan_list *l = &conn->chan_list;
 
@@ -1144,7 +1236,8 @@ static __inline__ void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk,
        write_unlock(&l->lock);
 }
 
-/* Delete channel. Must be called on the locked socket. */
+/* Delete channel. 
+ * Must be called on the locked socket. */
 static void l2cap_chan_del(struct sock *sk, int err)
 {
        struct l2cap_conn *conn;
@@ -1162,16 +1255,21 @@ static void l2cap_chan_del(struct sock *sk, int err)
                bh_unlock_sock(parent);
        }
 
-       if (conn) {
+       if (conn) { 
+               long timeout;
+
                /* Unlink from channel list */
                l2cap_chan_unlink(&conn->chan_list, sk);
                l2cap_pi(sk)->conn = NULL;
 
-               if (conn->out &&
-                   conn->state == BT_CONNECTED &&
-                   atomic_dec_and_test(&conn->refcnt)) {
-                       /* Disconnect baseband */
-                       hci_disconnect(conn->hconn, 0x13);
+               if (conn->out)
+                       timeout = L2CAP_DISCONN_TIMEOUT;
+               else
+                       timeout = L2CAP_CONN_IDLE_TIMEOUT;
+               
+               if (atomic_dec_and_test(&conn->refcnt) && conn->state == BT_CONNECTED) {
+                       /* Schedule Baseband disconnect */
+                       l2cap_conn_set_timer(conn, timeout);
                }
        }
 
@@ -1197,14 +1295,14 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
                if (sk->type != SOCK_SEQPACKET) {
                        sk->state = BT_CONNECTED;
                        sk->state_change(sk);
-                       l2cap_clear_timer(sk);
+                       l2cap_sock_clear_timer(sk);
                } else if (sk->state == BT_CONNECT) {
                        l2cap_conn_req req;
                        req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
                        req.psm  = l2cap_pi(sk)->psm;
                        l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
 
-                       l2cap_set_timer(sk, sk->sndtimeo);
+                       l2cap_sock_set_timer(sk, sk->sndtimeo);
                }
 
                bh_unlock_sock(sk);
@@ -1220,7 +1318,7 @@ static void l2cap_chan_ready(struct sock *sk)
        DBG("sk %p, parent %p", sk, parent);
 
        l2cap_pi(sk)->conf_state = 0;
-       l2cap_clear_timer(sk);
+       l2cap_sock_clear_timer(sk);
 
        if (!parent) {
                /* Outgoing channel.
@@ -1232,7 +1330,7 @@ static void l2cap_chan_ready(struct sock *sk)
                /* Incomming channel.
                 * Wake up socket sleeping on accept.
                 */
-               parent->state_change(parent);
+               parent->data_ready(parent, 1);
        }
 }
 
@@ -1254,7 +1352,7 @@ void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
                if (skb->sk == sk)
                        continue;
 
-               if (!(nskb = bluez_skb_clone(skb, GFP_ATOMIC)))
+               if (!(nskb = skb_clone(skb, GFP_ATOMIC)))
                        continue;
 
                skb_queue_tail(&sk->receive_queue, nskb);
@@ -1266,17 +1364,18 @@ void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
 static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len)
 {
        struct l2cap_conn *conn = l2cap_pi(sk)->conn;
-       struct l2cap_iff  *iff  = conn->iff;
-       struct sk_buff *skb, *frag;
+       struct sk_buff *skb, **frag;
        int err, size, count, sent=0;
-       l2cap_hdr * lh;
+       l2cap_hdr *lh;
 
        /* Check outgoing MTU */
        if (len > l2cap_pi(sk)->omtu)
                return -EINVAL;
 
+       DBG("sk %p len %d", sk, len);
+
        /* First fragment (with L2CAP header) */
-       count = MIN(iff->mtu - L2CAP_HDR_SIZE, len);
+       count = MIN(conn->iff->mtu - L2CAP_HDR_SIZE, len);
        size  = L2CAP_HDR_SIZE + count;
        if (!(skb = bluez_skb_send_alloc(sk, size, msg->msg_flags & MSG_DONTWAIT, &err)))
                return err;
@@ -1295,21 +1394,23 @@ static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len)
        len  -= count;
 
        /* Continuation fragments (no L2CAP header) */
+       frag = &skb_shinfo(skb)->frag_list;
        while (len) {
-               count = MIN(iff->mtu, len);
+               count = MIN(conn->iff->mtu, len);
 
-               if (!(frag = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err)))
+               *frag = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
+               if (!*frag)
                        goto fail;
-
-               bluez_skb_add_frag(skb, frag);
-       
-               if (memcpy_fromiovec(skb_put(frag, count), msg->msg_iov, count)) {
+               
+               if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) {
                        err = -EFAULT;
                        goto fail;
                }
 
                sent += count;
                len  -= count;
+
+               frag = &(*frag)->next;
        }
 
        if ((err = hci_send_acl(conn->hconn, skb, 0)) < 0)
@@ -1318,12 +1419,12 @@ static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len)
        return sent;
 
 fail:
-       bluez_skb_free(skb);
-
+       kfree_skb(skb);
        return err;
 }
+
 /* --------- L2CAP signalling commands --------- */
-static __inline__ __u8 l2cap_get_ident(struct l2cap_conn *conn)
+static inline __u8 l2cap_get_ident(struct l2cap_conn *conn)
 {
        __u8 id;
 
@@ -1344,7 +1445,7 @@ static __inline__ __u8 l2cap_get_ident(struct l2cap_conn *conn)
        return id;
 }
 
-static __inline__ struct sk_buff *l2cap_build_cmd(__u8 code, __u8 ident, __u16 len, void *data)
+static inline struct sk_buff *l2cap_build_cmd(__u8 code, __u8 ident, __u16 len, void *data)
 {
        struct sk_buff *skb;
        l2cap_cmd_hdr *cmd;
@@ -1382,7 +1483,6 @@ static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *d
        ident = l2cap_get_ident(conn);
        if (!(skb = l2cap_build_cmd(code, ident, len, data)))
                return -ENOMEM;
-       skb->dev = (void *) conn->iff->hdev;
        return hci_send_acl(conn->hconn, skb, 0);
 }
 
@@ -1394,13 +1494,10 @@ static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16
 
        if (!(skb = l2cap_build_cmd(code, ident, len, data)))
                return -ENOMEM;
-
-       skb->dev = (void *) conn->iff->hdev;
-
        return hci_send_acl(conn->hconn, skb, 0);
 }
 
-static __inline__ int l2cap_get_conf_opt(__u8 **ptr, __u8 *type, __u32 *val)
+static inline int l2cap_get_conf_opt(__u8 **ptr, __u8 *type, __u32 *val)
 {
        l2cap_conf_opt *opt = (l2cap_conf_opt *) (*ptr);
        int len;
@@ -1433,9 +1530,9 @@ static __inline__ int l2cap_get_conf_opt(__u8 **ptr, __u8 *type, __u32 *val)
        return len;
 }
 
-static __inline__ void l2cap_parse_conf_req(struct sock *sk, char *data, int len)
+static inline void l2cap_parse_conf_req(struct sock *sk, char *data, int len)
 {
-       __u8 type; __u32 val;
+       __u8 type, hint; __u32 val;
        __u8 *ptr = data;
 
        DBG("sk %p len %d", sk, len);
@@ -1443,6 +1540,9 @@ static __inline__ void l2cap_parse_conf_req(struct sock *sk, char *data, int len
        while (len >= L2CAP_CONF_OPT_SIZE) {
                len -= l2cap_get_conf_opt(&ptr, &type, &val);
 
+               hint  = type & 0x80;
+               type &= 0x7f;
+
                switch (type) {
                case L2CAP_CONF_MTU:
                        l2cap_pi(sk)->conf_mtu = val;
@@ -1454,11 +1554,18 @@ static __inline__ void l2cap_parse_conf_req(struct sock *sk, char *data, int len
 
                case L2CAP_CONF_QOS:
                        break;
+               
+               default:
+                       if (hint)
+                               break;
+
+                       /* FIXME: Reject unknon option */
+                       break;
                };
        }
 }
 
-static __inline__ void l2cap_add_conf_opt(__u8 **ptr, __u8 type, __u8 len, __u32 val)
+static inline void l2cap_add_conf_opt(__u8 **ptr, __u8 type, __u8 len, __u32 val)
 {
        register l2cap_conf_opt *opt = (l2cap_conf_opt *) (*ptr);
 
@@ -1540,7 +1647,7 @@ static int l2cap_build_conf_rsp(struct sock *sk, __u8 *data, int *result)
        return ptr - data;
 }
 
-static __inline__ int l2cap_connect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
+static inline int l2cap_connect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
 {
        struct l2cap_chan_list *list = &conn->chan_list;
        l2cap_conn_req *req = (l2cap_conn_req *) data;
@@ -1605,7 +1712,7 @@ reject:
        return 0;
 }
 
-static __inline__ int l2cap_connect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
+static inline int l2cap_connect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
 {
        l2cap_conn_rsp *rsp = (l2cap_conn_rsp *) data;
        __u16 scid, dcid, result, status;
@@ -1626,8 +1733,9 @@ static __inline__ int l2cap_connect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *
        if (!result) {
                char req[64];
 
-               l2cap_pi(sk)->dcid = dcid;
                sk->state = BT_CONFIG;
+               l2cap_pi(sk)->dcid = dcid;
+               l2cap_pi(sk)->conf_state |= CONF_REQ_SENT;
 
                l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
        } else {
@@ -1638,7 +1746,7 @@ static __inline__ int l2cap_connect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *
        return 0;
 }
 
-static __inline__ int l2cap_config_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
+static inline int l2cap_config_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
 {
        l2cap_conf_req * req = (l2cap_conf_req *) data;
        __u16 dcid, flags;
@@ -1671,12 +1779,12 @@ static __inline__ int l2cap_config_req(struct l2cap_conn *conn, l2cap_cmd_hdr *c
                goto unlock;
 
        /* Output config done */
-       l2cap_pi(sk)->conf_state |= CONF_OUTPUT;
+       l2cap_pi(sk)->conf_state |= CONF_OUTPUT_DONE;
 
-       if (l2cap_pi(sk)->conf_state == CONF_DONE) {
+       if (l2cap_pi(sk)->conf_state & CONF_INPUT_DONE) {
                sk->state = BT_CONNECTED;
                l2cap_chan_ready(sk);
-       } else {
+       } else if (!(l2cap_pi(sk)->conf_state & CONF_REQ_SENT)) {
                char req[64];
                l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
        }
@@ -1687,7 +1795,7 @@ unlock:
        return 0;
 }
 
-static __inline__ int l2cap_config_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
+static inline int l2cap_config_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
 {
        l2cap_conf_rsp *rsp = (l2cap_conf_rsp *)data;
        __u16 scid, flags, result;
@@ -1705,11 +1813,6 @@ static __inline__ int l2cap_config_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *c
 
        bh_lock_sock(sk);
 
-       if (sk->state != BT_CONFIG) {
-               err = -EINVAL;
-               goto done;
-       }
-
        if (result) {
                l2cap_disconn_req req;
 
@@ -1722,7 +1825,7 @@ static __inline__ int l2cap_config_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *c
                req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
                l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
 
-               l2cap_set_timer(sk, sk->sndtimeo);
+               l2cap_sock_set_timer(sk, sk->sndtimeo);
                goto done;
        }
 
@@ -1730,9 +1833,9 @@ static __inline__ int l2cap_config_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *c
                goto done;
 
        /* Input config done */
-       l2cap_pi(sk)->conf_state |= CONF_INPUT;
+       l2cap_pi(sk)->conf_state |= CONF_INPUT_DONE;
 
-       if (l2cap_pi(sk)->conf_state == CONF_DONE) {
+       if (l2cap_pi(sk)->conf_state & CONF_OUTPUT_DONE) {
                sk->state = BT_CONNECTED;
                l2cap_chan_ready(sk);
        }
@@ -1743,7 +1846,7 @@ done:
        return err;
 }
 
-static __inline__ int l2cap_disconnect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
+static inline int l2cap_disconnect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
 {
        l2cap_disconn_req *req = (l2cap_disconn_req *) data;
        l2cap_disconn_rsp rsp;
@@ -1773,7 +1876,7 @@ static __inline__ int l2cap_disconnect_req(struct l2cap_conn *conn, l2cap_cmd_hd
        return 0;
 }
 
-static __inline__ int l2cap_disconnect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
+static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
 {
        l2cap_disconn_rsp *rsp = (l2cap_disconn_rsp *) data;
        __u16 dcid, scid;
@@ -1788,7 +1891,7 @@ static __inline__ int l2cap_disconnect_rsp(struct l2cap_conn *conn, l2cap_cmd_hd
                return -ENOENT;
 
        bh_lock_sock(sk);
-       l2cap_clear_timer(sk);
+       l2cap_sock_clear_timer(sk);
        l2cap_chan_del(sk, ECONNABORTED);
        bh_unlock_sock(sk);
 
@@ -1797,7 +1900,7 @@ static __inline__ int l2cap_disconnect_rsp(struct l2cap_conn *conn, l2cap_cmd_hd
        return 0;
 }
 
-static __inline__ void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
+static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
 {
        __u8 *data = skb->data;
        int len = skb->len;
@@ -1809,7 +1912,7 @@ static __inline__ void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff
                data += L2CAP_CMD_HDR_SIZE;
                len  -= L2CAP_CMD_HDR_SIZE;
 
-               cmd.len = le16_to_cpu(cmd.len);
+               cmd.len = __le16_to_cpu(cmd.len);
 
                DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd.len, cmd.ident);
 
@@ -1869,7 +1972,7 @@ static __inline__ void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff
                        DBG("error %d", err);
 
                        /* FIXME: Map err to a valid reason. */
-                       rej.reason = cpu_to_le16(0);
+                       rej.reason = __cpu_to_le16(0);
                        l2cap_send_rsp(conn, cmd.ident, L2CAP_COMMAND_REJ, L2CAP_CMD_REJ_SIZE, &rej);
                }
 
@@ -1877,10 +1980,10 @@ static __inline__ void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff
                len  -= cmd.len;
        }
 
-       bluez_skb_free(skb);
+       kfree_skb(skb);
 }
 
-static __inline__ int l2cap_data_channel(struct l2cap_conn *conn, __u16 cid, struct sk_buff *skb)
+static inline int l2cap_data_channel(struct l2cap_conn *conn, __u16 cid, struct sk_buff *skb)
 {
        struct sock *sk;
 
@@ -1903,7 +2006,7 @@ static __inline__ int l2cap_data_channel(struct l2cap_conn *conn, __u16 cid, str
        return 0;
 
 drop:
-       bluez_skb_free(skb);
+       kfree_skb(skb);
 
        return 0;
 }
@@ -1914,8 +2017,8 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
        __u16 cid, len;
 
        skb_pull(skb, L2CAP_HDR_SIZE);
-       cid = le16_to_cpu(lh->cid);
-       len = le16_to_cpu(lh->len);
+       cid = __le16_to_cpu(lh->cid);
+       len = __le16_to_cpu(lh->len);
 
        DBG("len %d, cid 0x%4.4x", len, cid);
 
@@ -2008,10 +2111,10 @@ int l2cap_connect_cfm(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 status, struc
                        goto done;
                }
 
-               conn->state = BT_CONNECTED;
                conn->hconn = hconn;
-
                hconn->l2cap_data = (void *)conn;
+
+               conn->state = BT_CONNECTED;
        }
 
 done:
@@ -2044,7 +2147,7 @@ int l2cap_recv_acldata(struct hci_conn *hconn, struct sk_buff *skb, __u16 flags)
        struct l2cap_conn *conn = hconn->l2cap_data;
 
        if (!conn) {
-               ERR("unknown connection");
+               ERR("unknown connection %p", hconn);
                goto drop;
        }
 
@@ -2054,8 +2157,14 @@ int l2cap_recv_acldata(struct hci_conn *hconn, struct sk_buff *skb, __u16 flags)
                int flen, tlen, size;
                l2cap_hdr *lh;
 
+               if (conn->rx_len) {
+                       ERR("Unexpected start frame (len %d)", skb->len);
+                       kfree_skb(conn->rx_skb); conn->rx_skb = NULL;
+                       conn->rx_len = 0;
+               }
+
                if (skb->len < L2CAP_HDR_SIZE) {
-                       DBG("Corrupted L2CAP frame %d", skb->len);
+                       ERR("Frame is too small (len %d)", skb->len);
                        goto drop;
                }
 
@@ -2082,12 +2191,14 @@ int l2cap_recv_acldata(struct hci_conn *hconn, struct sk_buff *skb, __u16 flags)
        } else {
                DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
 
-               /* Check length */
+               if (!conn->rx_len) {
+                       ERR("Unexpected continuation frame (len %d)", skb->len);
+                       goto drop;
+               }
+
                if (skb->len > conn->rx_len) {
-                       if (conn->rx_skb) {
-                               bluez_skb_free(conn->rx_skb);
-                               conn->rx_skb = NULL;
-                       }
+                       ERR("Fragment is too large (len %d)", skb->len);
+                       kfree_skb(conn->rx_skb); conn->rx_skb = NULL;
                        goto drop;
                }
 
@@ -2098,13 +2209,11 @@ int l2cap_recv_acldata(struct hci_conn *hconn, struct sk_buff *skb, __u16 flags)
                        /* Complete frame received */
                        l2cap_recv_frame(conn, conn->rx_skb);
                        conn->rx_skb = NULL;
-                       conn->rx_len = 0;
                }
        }
 
 drop:
-       bluez_skb_free(skb);
-
+       kfree_skb(skb);
        return 0;
 }
 
@@ -2118,7 +2227,7 @@ struct proto_ops l2cap_sock_ops = {
        getname:        l2cap_sock_getname,
        sendmsg:        l2cap_sock_sendmsg,
        recvmsg:        l2cap_sock_recvmsg,
-       poll:           datagram_poll,
+       poll:           l2cap_sock_poll,
        socketpair:     sock_no_socketpair,
        ioctl:          sock_no_ioctl,
        shutdown:       sock_no_shutdown,
@@ -2148,7 +2257,7 @@ struct notifier_block l2cap_nblock = {
 int __init l2cap_init(void)
 {
        INF("BlueZ L2CAP ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-               BLUEZ_VER);
+               VERSION);
        INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
 
        if (bluez_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops)) {
@@ -2200,3 +2309,6 @@ void l2cap_cleanup(void)
 
 module_init(l2cap_init);
 module_exit(l2cap_cleanup);
+
+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
+MODULE_DESCRIPTION("BlueZ L2CAP ver " VERSION);
index 071da8019e83a75262cbadf364378ed97b277f14..7722a3971e42e9b1575cb8204b62089f2b562875 100644 (file)
@@ -25,7 +25,7 @@
 /*
  * BlueZ L2CAP proc fs support.
  *
- * $Id: l2cap_proc.c,v 1.1 2001/06/01 08:12:11 davem Exp $
+ * $Id: l2cap_proc.c,v 1.2 2001/06/02 01:40:09 maxk Exp $
  */
 
 #include <linux/config.h>
@@ -36,7 +36,7 @@
 #include <linux/kernel.h>
 #include <linux/major.h>
 #include <linux/sched.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/poll.h>
 #include <linux/fcntl.h>
 #include <linux/init.h>
index 6ec1deed22f74e546b9b433ec83b99c5aea182d0..66f78702c6a2dadcc32a7e0c54615eb0348445d2 100644 (file)
@@ -25,7 +25,7 @@
 /*
  * BlueZ kernel library.
  *
- * $Id: lib.c,v 1.1 2001/06/01 08:12:11 davem Exp $
+ * $Id: lib.c,v 1.3 2001/06/22 23:14:23 maxk Exp $
  */
 
 #include <linux/kernel.h>
@@ -76,7 +76,8 @@ char *batostr(bdaddr_t *ba)
 
        i ^= 1;
        sprintf(str[i], "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
-               ba->b0, ba->b1, ba->b2, ba->b3, ba->b4, ba->b5);
+               ba->b[0], ba->b[1], ba->b[2],
+               ba->b[3], ba->b[4], ba->b[5]);
 
        return str[i];
 }
index 9743688849bbff2f4208f5e08633bdcb6f4387b4..5eae8790449b9895eeda3981c8dd6ae51896b562 100644 (file)
@@ -25,7 +25,7 @@
 /*
  * BlueZ symbols.
  *
- * $Id: syms.c,v 1.1 2001/06/01 08:12:11 davem Exp $
+ * $Id: syms.c,v 1.1 2001/07/12 19:31:24 maxk Exp $
  */
 
 #include <linux/config.h>
index 89d1a0d5d797f198e4a6722cd673fec962049bfa..6d87f218213667d81e34cdea5f612002392515e6 100644 (file)
@@ -2275,6 +2275,32 @@ int dev_ioctl(unsigned int cmd, void *arg)
                        }
                        return ret;
 
+               /*
+                *      These ioctl calls:
+                *      - require superuser power.
+                *      - require strict serialization.
+                *      - return a value
+                */
+                
+               case SIOCETHTOOL:
+               case SIOCGMIIPHY:
+               case SIOCGMIIREG:
+                       if (!capable(CAP_NET_ADMIN))
+                               return -EPERM;
+                       dev_load(ifr.ifr_name);
+                       dev_probe_lock();
+                       rtnl_lock();
+                       ret = dev_ifsioc(&ifr, cmd);
+                       rtnl_unlock();
+                       dev_probe_unlock();
+                       if (!ret) {
+                               if (colon)
+                                       *colon = ':';
+                               if (copy_to_user(arg, &ifr, sizeof(struct ifreq)))
+                                       return -EFAULT;
+                       }
+                       return ret;
+
                /*
                 *      These ioctl calls:
                 *      - require superuser power.
@@ -2293,9 +2319,6 @@ int dev_ioctl(unsigned int cmd, void *arg)
                case SIOCSIFHWBROADCAST:
                case SIOCSIFTXQLEN:
                case SIOCSIFNAME:
-               case SIOCETHTOOL:
-               case SIOCGMIIPHY:
-               case SIOCGMIIREG:
                case SIOCSMIIREG:
                        if (!capable(CAP_NET_ADMIN))
                                return -EPERM;
index 81d5e033dc434ba5c2dcf384123fcc8d21ac2c3f..59e81c1f0cf8499a4eca14636d380090303dd45d 100644 (file)
@@ -1,6 +1,6 @@
 /* linux/net/inet/arp.c
  *
- * Version:    $Id: arp.c,v 1.98 2001/05/16 16:45:35 davem Exp $
+ * Version:    $Id: arp.c,v 1.99 2001/08/30 22:55:42 davem Exp $
  *
  * Copyright (C) 1994 by Florian  La Roche
  *
@@ -560,7 +560,6 @@ void arp_send(int type, int ptype, u32 dest_ip,
                memset(arp_ptr, 0, dev->addr_len);
        arp_ptr+=dev->addr_len;
        memcpy(arp_ptr, &dest_ip, 4);
-       skb->dev = dev;
 
        dev_queue_xmit(skb);
        return;
index 1e85f0a38a60f52ecc392e343b61aa725e25a6f3..f86498876be3adb8ae7f6324e16961aa55e7dd69 100644 (file)
@@ -3,7 +3,7 @@
  *     
  *             Alan Cox, <alan@redhat.com>
  *
- *     Version: $Id: icmp.c,v 1.80 2001/08/22 20:38:41 davem Exp $
+ *     Version: $Id: icmp.c,v 1.81 2001/09/01 00:31:50 davem Exp $
  *
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License
@@ -885,7 +885,7 @@ int icmp_rcv(struct sk_buff *skb)
        case CHECKSUM_HW:
                if ((u16)csum_fold(skb->csum) == 0)
                        break;
-               NETDEBUG(printk(KERN_DEBUG "icmp v4 hw csum failure\n"));
+               NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "icmp v4 hw csum failure\n"));
        case CHECKSUM_NONE:
                if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0)))
                        goto error;
index 3d241d224bce8181178bb14baab83810044afdc3..fe8603ebb6612e36b9aeb1846950fe46c5f2b925 100644 (file)
@@ -5,7 +5,7 @@
  *
  *             The IP fragmentation functionality.
  *             
- * Version:    $Id: ip_fragment.c,v 1.57 2001/03/07 22:00:57 davem Exp $
+ * Version:    $Id: ip_fragment.c,v 1.58 2001/09/01 00:31:50 davem Exp $
  *
  * Authors:    Fred N. van Kempen <waltje@uWalt.NL.Mugnet.ORG>
  *             Alan Cox <Alan.Cox@linux.org>
@@ -335,7 +335,7 @@ static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph)
        return ip_frag_intern(hash, qp);
 
 out_nomem:
-       NETDEBUG(printk(KERN_ERR "ip_frag_create: no memory left !\n"));
+       NETDEBUG(if (net_ratelimit()) printk(KERN_ERR "ip_frag_create: no memory left !\n"));
        return NULL;
 }
 
@@ -578,7 +578,8 @@ static struct sk_buff *ip_frag_reasm(struct ipq *qp, struct net_device *dev)
        return head;
 
 out_nomem:
-       NETDEBUG(printk(KERN_ERR 
+       NETDEBUG(if (net_ratelimit())
+                printk(KERN_ERR 
                        "IP: queue_glue: no memory for gluing queue %p\n",
                        qp));
        goto out_fail;
index b511e29fd5b1427ab8363f16b43e4592b89d1cdf..8faded2b254f50fee9510884d06706c42247b918 100644 (file)
@@ -5,7 +5,7 @@
  *
  *             The options processing module for ip.c
  *
- * Version:    $Id: ip_options.c,v 1.20 2000/08/09 09:17:00 davem Exp $
+ * Version:    $Id: ip_options.c,v 1.21 2001/09/01 00:31:50 davem Exp $
  *
  * Authors:    A.N.Kuznetsov
  *             
@@ -549,7 +549,7 @@ void ip_forward_options(struct sk_buff *skb)
                        ip_rt_get_source(&optptr[srrptr-1], rt);
                        skb->nh.iph->daddr = rt->rt_dst;
                        optptr[2] = srrptr+4;
-               } else
+               } else if (net_ratelimit())
                        printk(KERN_CRIT "ip_forward(): Argh! Destination lost!\n");
                if (opt->ts_needaddr) {
                        optptr = raw + opt->ts;
index cec87fe34d454757281cfc7e46f35a4b740afb54..69412c30cd2c6ff6b3f71650bd9bedda33dd4836 100644 (file)
@@ -5,7 +5,7 @@
  *
  *             The Internet Protocol (IP) output module.
  *
- * Version:    $Id: ip_output.c,v 1.97 2001/08/09 17:53:40 davem Exp $
+ * Version:    $Id: ip_output.c,v 1.98 2001/09/01 00:31:50 davem Exp $
  *
  * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -174,7 +174,8 @@ static inline int ip_finish_output2(struct sk_buff *skb)
        } else if (dst->neighbour)
                return dst->neighbour->output(skb);
 
-       printk(KERN_DEBUG "khm\n");
+       if (net_ratelimit())
+               printk(KERN_DEBUG "ip_finish_output2: No header cache and no neighbour!\n");
        kfree_skb(skb);
        return -EINVAL;
 }
index a6ea0387de07330f4132ee2b89309b1a7dce7996..b411ecdc4bc65055d43da1b811b9ebbf83ed4d3e 100644 (file)
@@ -878,7 +878,7 @@ static struct inet_protocol ipip_protocol = {
        name:           "IPIP"
 };
 
-static const char banner[] __initdata =
+static char banner[] __initdata =
        KERN_INFO "IPv4 over IPv4 tunneling driver\n";
 
 int __init ipip_init(void)
index 2d09e4009ff89bd7b85c302de3c5e9b657b8e937..a60c4057646d880b12c1ff6414c27084d6b99b2a 100644 (file)
@@ -5,7 +5,7 @@
  *
  *             Implementation of the Transmission Control Protocol(TCP).
  *
- * Version:    $Id: tcp_ipv4.c,v 1.229 2001/04/20 20:46:19 davem Exp $
+ * Version:    $Id: tcp_ipv4.c,v 1.230 2001/09/01 00:31:50 davem Exp $
  *
  *             IPv4 specific functions
  *
@@ -1505,7 +1505,7 @@ static int tcp_v4_checksum_init(struct sk_buff *skb)
                                  skb->nh.iph->daddr,skb->csum))
                        return 0;
 
-               NETDEBUG(printk(KERN_DEBUG "hw tcp v4 csum failed\n"));
+               NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "hw tcp v4 csum failed\n"));
                skb->ip_summed = CHECKSUM_NONE;
        }
        if (skb->len <= 76) {
index 547a2a13c2a0c023599b662f5d63876c04d46963..095955c0c6341721ef1f949ad7873b6064a70818 100644 (file)
@@ -5,7 +5,7 @@
  *
  *             The User Datagram Protocol (UDP).
  *
- * Version:    $Id: udp.c,v 1.98 2001/03/06 21:15:10 davem Exp $
+ * Version:    $Id: udp.c,v 1.99 2001/09/01 00:31:50 davem Exp $
  *
  * Authors:    Ross Biro, <bir7@leland.Stanford.Edu>
  *             Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -856,7 +856,7 @@ static int udp_checksum_init(struct sk_buff *skb, struct udphdr *uh,
                skb->ip_summed = CHECKSUM_UNNECESSARY;
                if (!udp_check(uh, ulen, saddr, daddr, skb->csum))
                        return 0;
-               NETDEBUG(printk(KERN_DEBUG "udp v4 hw csum failure.\n"));
+               NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "udp v4 hw csum failure.\n"));
                skb->ip_summed = CHECKSUM_NONE;
        }
        if (skb->ip_summed != CHECKSUM_UNNECESSARY)
@@ -925,7 +925,7 @@ int udp_rcv(struct sk_buff *skb)
        return(0);
 
 short_packet:
-       NETDEBUG(printk(KERN_DEBUG "UDP: short packet: %d/%d\n", ulen, len));
+       NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "UDP: short packet: %d/%d\n", ulen, len));
        UDP_INC_STATS_BH(UdpInErrors);
        kfree_skb(skb);
        return(0);
@@ -935,7 +935,8 @@ csum_error:
         * RFC1122: OK.  Discards the bad packet silently (as far as 
         * the network is concerned, anyway) as per 4.1.3.4 (MUST). 
         */
-       NETDEBUG(printk(KERN_DEBUG "UDP: bad checksum. From %d.%d.%d.%d:%d to %d.%d.%d.%d:%d ulen %d\n",
+       NETDEBUG(if (net_ratelimit())
+                printk(KERN_DEBUG "UDP: bad checksum. From %d.%d.%d.%d:%d to %d.%d.%d.%d:%d ulen %d\n",
                        NIPQUAD(saddr),
                        ntohs(uh->source),
                        NIPQUAD(daddr),
index 482b025d1fb03adfa87049678a64409f3365c93d..e5e42fe58f7f736da0594d680a6a1d2615e31a2a 100644 (file)
@@ -6,7 +6,7 @@
  *     Pedro Roque             <roque@di.fc.ul.pt>     
  *     Alexey Kuznetsov        <kuznet@ms2.inr.ac.ru>
  *
- *     $Id: addrconf.c,v 1.67 2001/08/03 09:32:17 davem Exp $
+ *     $Id: addrconf.c,v 1.68 2001/09/01 00:31:50 davem Exp $
  *
  *     This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -628,7 +628,8 @@ struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr, struct net_device *
 
 void addrconf_dad_failure(struct inet6_ifaddr *ifp)
 {
-       printk(KERN_INFO "%s: duplicate address detected!\n", ifp->idev->dev->name);
+       if (net_ratelimit())
+               printk(KERN_INFO "%s: duplicate address detected!\n", ifp->idev->dev->name);
        if (ifp->flags&IFA_F_PERMANENT) {
                spin_lock_bh(&ifp->lock);
                addrconf_del_timer(ifp);
@@ -818,14 +819,16 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
        prefered_lft = ntohl(pinfo->prefered);
 
        if (prefered_lft > valid_lft) {
-               printk(KERN_WARNING "addrconf: prefix option has invalid lifetime\n");
+               if (net_ratelimit())
+                       printk(KERN_WARNING "addrconf: prefix option has invalid lifetime\n");
                return;
        }
 
        in6_dev = in6_dev_get(dev);
 
        if (in6_dev == NULL) {
-               printk(KERN_DEBUG "addrconf: device %s not configured\n", dev->name);
+               if (net_ratelimit())
+                       printk(KERN_DEBUG "addrconf: device %s not configured\n", dev->name);
                return;
        }
 
@@ -881,7 +884,9 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
                        }
                        goto ok;
                }
-               printk(KERN_DEBUG "IPv6 addrconf: prefix with wrong length %d\n", pinfo->prefix_len);
+               if (net_ratelimit())
+                       printk(KERN_DEBUG "IPv6 addrconf: prefix with wrong length %d\n",
+                              pinfo->prefix_len);
                in6_dev_put(in6_dev);
                return;
 
index 51e69d2547ee22b2fe46205dd115a8118e17d18b..6e43fb578c87138605de8b5f710033e14b97a3f5 100644 (file)
@@ -5,7 +5,7 @@
  *     Authors:
  *     Pedro Roque             <roque@di.fc.ul.pt>     
  *
- *     $Id: datagram.c,v 1.22 2000/12/13 18:31:50 davem Exp $
+ *     $Id: datagram.c,v 1.23 2001/09/01 00:31:50 davem Exp $
  *
  *     This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -427,7 +427,8 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
                        break;
 
                default:
-                       printk(KERN_DEBUG "invalid cmsg type: %d\n", cmsg->cmsg_type);
+                       if (net_ratelimit())
+                               printk(KERN_DEBUG "invalid cmsg type: %d\n", cmsg->cmsg_type);
                        err = -EINVAL;
                        break;
                };
index fbc0e6bd77eda79d9e2723756b946d230ff6309d..8986d989134de4a74d8357849d2ea87f1b6586b4 100644 (file)
@@ -5,7 +5,7 @@
  *     Authors:
  *     Pedro Roque             <roque@di.fc.ul.pt>
  *
- *     $Id: icmp.c,v 1.35 2001/08/13 18:56:13 davem Exp $
+ *     $Id: icmp.c,v 1.36 2001/09/01 00:31:50 davem Exp $
  *
  *     Based on net/ipv4/icmp.c
  *
@@ -322,7 +322,8 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
         *      for now we don't know that.
         */
        if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) {
-               printk(KERN_DEBUG "icmpv6_send: addr_any/mcast source\n");
+               if (net_ratelimit())
+                       printk(KERN_DEBUG "icmpv6_send: addr_any/mcast source\n");
                return;
        }
 
@@ -368,7 +369,8 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
        len = min(unsigned int, len, IPV6_MIN_MTU - sizeof(struct ipv6hdr));
 
        if (len < 0) {
-               printk(KERN_DEBUG "icmp: len problem\n");
+               if (net_ratelimit())
+                       printk(KERN_DEBUG "icmp: len problem\n");
                goto out;
        }
 
@@ -507,30 +509,32 @@ int icmpv6_rcv(struct sk_buff *skb)
                skb->ip_summed = CHECKSUM_UNNECESSARY;
                if (csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6,
                                    skb->csum)) {
-                       printk(KERN_DEBUG "ICMPv6 hw checksum failed\n");
+                       if (net_ratelimit())
+                               printk(KERN_DEBUG "ICMPv6 hw checksum failed\n");
                        skb->ip_summed = CHECKSUM_NONE;
                }
        }
        if (skb->ip_summed == CHECKSUM_NONE) {
                if (csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6,
                                    skb_checksum(skb, 0, skb->len, 0))) {
-                       printk(KERN_DEBUG "ICMPv6 checksum failed [%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x > %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]\n",
-                               ntohs(saddr->in6_u.u6_addr16[0]),
-                               ntohs(saddr->in6_u.u6_addr16[1]),
-                               ntohs(saddr->in6_u.u6_addr16[2]),
-                               ntohs(saddr->in6_u.u6_addr16[3]),
-                               ntohs(saddr->in6_u.u6_addr16[4]),
-                               ntohs(saddr->in6_u.u6_addr16[5]),
-                               ntohs(saddr->in6_u.u6_addr16[6]),
-                               ntohs(saddr->in6_u.u6_addr16[7]),
-                               ntohs(daddr->in6_u.u6_addr16[0]),
-                               ntohs(daddr->in6_u.u6_addr16[1]),
-                               ntohs(daddr->in6_u.u6_addr16[2]),
-                               ntohs(daddr->in6_u.u6_addr16[3]),
-                               ntohs(daddr->in6_u.u6_addr16[4]),
-                               ntohs(daddr->in6_u.u6_addr16[5]),
-                               ntohs(daddr->in6_u.u6_addr16[6]),
-                               ntohs(daddr->in6_u.u6_addr16[7]));
+                       if (net_ratelimit())
+                               printk(KERN_DEBUG "ICMPv6 checksum failed [%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x > %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]\n",
+                                      ntohs(saddr->in6_u.u6_addr16[0]),
+                                      ntohs(saddr->in6_u.u6_addr16[1]),
+                                      ntohs(saddr->in6_u.u6_addr16[2]),
+                                      ntohs(saddr->in6_u.u6_addr16[3]),
+                                      ntohs(saddr->in6_u.u6_addr16[4]),
+                                      ntohs(saddr->in6_u.u6_addr16[5]),
+                                      ntohs(saddr->in6_u.u6_addr16[6]),
+                                      ntohs(saddr->in6_u.u6_addr16[7]),
+                                      ntohs(daddr->in6_u.u6_addr16[0]),
+                                      ntohs(daddr->in6_u.u6_addr16[1]),
+                                      ntohs(daddr->in6_u.u6_addr16[2]),
+                                      ntohs(daddr->in6_u.u6_addr16[3]),
+                                      ntohs(daddr->in6_u.u6_addr16[4]),
+                                      ntohs(daddr->in6_u.u6_addr16[5]),
+                                      ntohs(daddr->in6_u.u6_addr16[6]),
+                                      ntohs(daddr->in6_u.u6_addr16[7]));
                        goto discard_it;
                }
        }
index 01ee245ba99e5fa527b87b5260b2ae4ac65eab3c..ff395981cfb7683acea8f8f585ccf31fc9381617 100644 (file)
@@ -5,7 +5,7 @@
  *     Authors:
  *     Pedro Roque             <roque@di.fc.ul.pt>     
  *
- *     $Id: ip6_output.c,v 1.31 2001/04/17 20:39:51 davem Exp $
+ *     $Id: ip6_output.c,v 1.32 2001/09/01 00:31:50 davem Exp $
  *
  *     Based on linux/net/ipv4/ip_output.c
  *
@@ -149,7 +149,8 @@ static int route6_me_harder(struct sk_buff *skb)
        dst = ip6_route_output(skb->sk, &fl);
 
        if (dst->error) {
-               printk(KERN_DEBUG "route6_me_harder: No more route.\n");
+               if (net_ratelimit())
+                       printk(KERN_DEBUG "route6_me_harder: No more route.\n");
                return -EINVAL;
        }
 
@@ -239,7 +240,8 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
                return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute);
        }
 
-       printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n");
+       if (net_ratelimit())
+               printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n");
        icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst->pmtu, skb->dev);
        kfree_skb(skb);
        return -EMSGSIZE;
index d8fc9bfabf2dd7d4b08ed4bc090e285c0c21a5a8..981e1c9d5e8a564345e1a051b39ee1ba219bf9b8 100644 (file)
@@ -6,7 +6,7 @@
  *     Pedro Roque             <roque@di.fc.ul.pt>     
  *     Alexey Kuznetsov        <kuznet@ms2.inr.ac.ru>
  *
- *     $Id: sit.c,v 1.51 2001/05/17 04:12:18 davem Exp $
+ *     $Id: sit.c,v 1.52 2001/09/01 00:31:50 davem Exp $
  *
  *     This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -482,7 +482,8 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
                        neigh = skb->dst->neighbour;
 
                if (neigh == NULL) {
-                       printk(KERN_DEBUG "sit: nexthop == NULL\n");
+                       if (net_ratelimit())
+                               printk(KERN_DEBUG "sit: nexthop == NULL\n");
                        goto tx_error;
                }
 
index 9293d9972b929864b8b45e97e7c2225da5cb76f5..33e9cb1ec50753bd574063de6269ee3a4662589b 100644 (file)
@@ -5,7 +5,7 @@
  *     Authors:
  *     Pedro Roque             <roque@di.fc.ul.pt>     
  *
- *     $Id: tcp_ipv6.c,v 1.137 2001/06/13 16:25:03 davem Exp $
+ *     $Id: tcp_ipv6.c,v 1.138 2001/09/01 00:31:50 davem Exp $
  *
  *     Based on: 
  *     linux/net/ipv4/tcp.c
@@ -1380,7 +1380,7 @@ static int tcp_v6_checksum_init(struct sk_buff *skb)
                if (!tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
                                  &skb->nh.ipv6h->daddr,skb->csum))
                        return 0;
-               NETDEBUG(printk(KERN_DEBUG "hw tcp v6 csum failed\n"));
+               NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "hw tcp v6 csum failed\n"));
        }
        if (skb->len <= 76) {
                if (tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
index 35216c464837ceb7c19696981173f2d7f39dca97..7d013f85d9c874be31c0629e6676b9c53c16757c 100644 (file)
@@ -7,7 +7,7 @@
  *
  *     Based on linux/ipv4/udp.c
  *
- *     $Id: udp.c,v 1.63 2001/06/13 16:25:03 davem Exp $
+ *     $Id: udp.c,v 1.64 2001/09/01 00:31:50 davem Exp $
  *
  *     Fixes:
  *     Hideaki YOSHIFUJI       :       sin6_scope_id support
@@ -635,7 +635,7 @@ int udpv6_rcv(struct sk_buff *skb)
        if (skb->ip_summed==CHECKSUM_HW) {
                skb->ip_summed = CHECKSUM_UNNECESSARY;
                if (csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, skb->csum)) {
-                       NETDEBUG(printk(KERN_DEBUG "udp v6 hw csum failure.\n"));
+                       NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "udp v6 hw csum failure.\n"));
                        skb->ip_summed = CHECKSUM_NONE;
                }
        }
index e71849f1b3b659d88d11ec5303e0e4819e3d030b..281c8a681b69278213e1d6c7e3ec3a9ac10bc2f4 100644 (file)
@@ -457,15 +457,17 @@ int irda_device_txqueue_empty(struct net_device *dev)
 dongle_t *irda_device_dongle_init(struct net_device *dev, int type)
 {
        struct dongle_reg *reg;
-       char modname[32];
        dongle_t *dongle;
 
        ASSERT(dev != NULL, return NULL;);
 
 #ifdef CONFIG_KMOD
+       {
+       char modname[32];
        /* Try to load the module needed */
        sprintf(modname, "irda-dongle-%d", type);
        request_module(modname);
+       }
 #endif /* CONFIG_KMOD */
 
        if (!(reg = hashbin_find(dongles, type, NULL))) {
index c61bcd1af8e12d9368068c2070809ca796a0ebf4..aeafa310f1e401f36335c0ed53d8d3bc8baa15b0 100644 (file)
@@ -397,7 +397,7 @@ EXPORT_SYMBOL(lapb_disconnect_request);
 EXPORT_SYMBOL(lapb_data_request);
 EXPORT_SYMBOL(lapb_data_received);
 
-static const char banner[] __initdata = KERN_INFO "NET4: LAPB for Linux. Version 0.01 for NET4.0\n";
+static char banner[] __initdata = KERN_INFO "NET4: LAPB for Linux. Version 0.01 for NET4.0\n";
 
 static int __init lapb_init(void)
 {
index 2b94267d85ddfe64e16f88e93878fdfac59efb02..42d07092f9342a44b625d3a5c85d8a41de320df8 100644 (file)
@@ -1262,7 +1262,7 @@ static struct notifier_block nr_dev_notifier = {
 
 static struct net_device *dev_nr;
 
-static const char banner[] __initdata = KERN_INFO "G4KLX NET/ROM for Linux. Version 0.7 for AX25.037 Linux 2.4\n";
+static char banner[] __initdata = KERN_INFO "G4KLX NET/ROM for Linux. Version 0.7 for AX25.037 Linux 2.4\n";
 
 static int __init nr_proto_init(void)
 {
index 8523d1bea1fc5fcc09275a05a85c4c677fb4ebab..312427597dede792c6bb46f103062eb209cea5b3 100644 (file)
@@ -79,7 +79,6 @@ rpc_create_client(struct rpc_xprt *xprt, char *servname,
 #ifdef RPC_DEBUG
        rpc_register_sysctl();
 #endif
-       xdr_init();
 
        if (!xprt)
                goto out;
index 369358b73e20a1b8a033330da8da0cde328bf519..0c66733d8f79803d338b3d27822b656ac56fdd49 100644 (file)
@@ -94,17 +94,9 @@ EXPORT_SYMBOL(xdr_encode_string);
 EXPORT_SYMBOL(xdr_decode_string);
 EXPORT_SYMBOL(xdr_decode_netobj);
 EXPORT_SYMBOL(xdr_encode_netobj);
-EXPORT_SYMBOL(xdr_zero);
-EXPORT_SYMBOL(xdr_one);
-EXPORT_SYMBOL(xdr_two);
 EXPORT_SYMBOL(xdr_shift_iovec);
 EXPORT_SYMBOL(xdr_zero_iovec);
 
-/* RPC errors */
-EXPORT_SYMBOL(rpc_success);
-EXPORT_SYMBOL(rpc_garbage_args);
-EXPORT_SYMBOL(rpc_system_err);
-
 /* Debugging symbols */
 #ifdef RPC_DEBUG
 EXPORT_SYMBOL(rpc_debug);
index cddbfb5245ece5e37c04351d100f9272039330cd..e041bad0e6ecb87d3eadd48c9181ad56feb6cf6c 100644 (file)
@@ -31,7 +31,6 @@ svc_create(struct svc_program *prog, unsigned int bufsize, unsigned int xdrsize)
 {
        struct svc_serv *serv;
 
-       xdr_init();
 #ifdef RPC_DEBUG
        rpc_register_sysctl();
 #endif
index 99b286af9d6a680404c27dca719d1db6dcac7d53..ac875042ee94152de723873bfccd7c1eb5837fa6 100644 (file)
 #include <linux/sunrpc/xdr.h>
 #include <linux/sunrpc/msg_prot.h>
 
-u32    rpc_success, rpc_prog_unavail, rpc_prog_mismatch, rpc_proc_unavail,
-       rpc_garbage_args, rpc_system_err;
-u32    rpc_auth_ok, rpc_autherr_badcred, rpc_autherr_rejectedcred,
-       rpc_autherr_badverf, rpc_autherr_rejectedverf, rpc_autherr_tooweak;
-u32    xdr_zero, xdr_one, xdr_two;
-
-void
-xdr_init(void)
-{
-       static int      inited = 0;
-
-       if (inited)
-               return;
-
-       xdr_zero = htonl(0);
-       xdr_one = htonl(1);
-       xdr_two = htonl(2);
-
-       rpc_success = htonl(RPC_SUCCESS);
-       rpc_prog_unavail = htonl(RPC_PROG_UNAVAIL);
-       rpc_prog_mismatch = htonl(RPC_PROG_MISMATCH);
-       rpc_proc_unavail = htonl(RPC_PROC_UNAVAIL);
-       rpc_garbage_args = htonl(RPC_GARBAGE_ARGS);
-       rpc_system_err = htonl(RPC_SYSTEM_ERR);
-
-       rpc_auth_ok = htonl(RPC_AUTH_OK);
-       rpc_autherr_badcred = htonl(RPC_AUTH_BADCRED);
-       rpc_autherr_rejectedcred = htonl(RPC_AUTH_REJECTEDCRED);
-       rpc_autherr_badverf = htonl(RPC_AUTH_BADVERF);
-       rpc_autherr_rejectedverf = htonl(RPC_AUTH_REJECTEDVERF);
-       rpc_autherr_tooweak = htonl(RPC_AUTH_TOOWEAK);
-
-       inited = 1;
-}
-
 /*
  * XDR functions for basic NFS types
  */